mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 13:29:13 -04:00
Merge branch 'main' into feat/htpasswd
This commit is contained in:
commit
97544530c9
10 changed files with 212 additions and 28 deletions
30
components.d.ts
vendored
30
components.d.ts
vendored
|
@ -12,6 +12,7 @@ declare module '@vue/runtime-core' {
|
||||||
'404.page': typeof import('./src/pages/404.page.vue')['default']
|
'404.page': typeof import('./src/pages/404.page.vue')['default']
|
||||||
About: typeof import('./src/pages/About.vue')['default']
|
About: typeof import('./src/pages/About.vue')['default']
|
||||||
App: typeof import('./src/App.vue')['default']
|
App: typeof import('./src/App.vue')['default']
|
||||||
|
AsciiTextDrawer: typeof import('./src/tools/ascii-text-drawer/ascii-text-drawer.vue')['default']
|
||||||
'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
|
'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
|
||||||
Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
|
Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
|
||||||
Base64StringConverter: typeof import('./src/tools/base64-string-converter/base64-string-converter.vue')['default']
|
Base64StringConverter: typeof import('./src/tools/base64-string-converter/base64-string-converter.vue')['default']
|
||||||
|
@ -88,28 +89,17 @@ declare module '@vue/runtime-core' {
|
||||||
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
|
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
|
||||||
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
|
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
|
||||||
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
|
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
|
||||||
'IconMdi:contentCopy': typeof import('~icons/mdi/content-copy')['default']
|
|
||||||
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
|
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
|
||||||
IconMdiArrowDown: typeof import('~icons/mdi/arrow-down')['default']
|
|
||||||
IconMdiArrowRightBottom: typeof import('~icons/mdi/arrow-right-bottom')['default']
|
|
||||||
IconMdiCamera: typeof import('~icons/mdi/camera')['default']
|
|
||||||
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
|
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
|
||||||
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
|
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
|
||||||
IconMdiClose: typeof import('~icons/mdi/close')['default']
|
IconMdiClose: typeof import('~icons/mdi/close')['default']
|
||||||
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
|
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
|
||||||
IconMdiDeleteOutline: typeof import('~icons/mdi/delete-outline')['default']
|
|
||||||
IconMdiDownload: typeof import('~icons/mdi/download')['default']
|
|
||||||
IconMdiEye: typeof import('~icons/mdi/eye')['default']
|
IconMdiEye: typeof import('~icons/mdi/eye')['default']
|
||||||
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
|
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
|
||||||
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
|
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
|
||||||
IconMdiPause: typeof import('~icons/mdi/pause')['default']
|
|
||||||
IconMdiPlay: typeof import('~icons/mdi/play')['default']
|
|
||||||
IconMdiRecord: typeof import('~icons/mdi/record')['default']
|
|
||||||
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
|
|
||||||
IconMdiSearch: typeof import('~icons/mdi/search')['default']
|
IconMdiSearch: typeof import('~icons/mdi/search')['default']
|
||||||
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
|
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
|
||||||
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
|
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
|
||||||
IconMdiVideo: typeof import('~icons/mdi/video')['default']
|
|
||||||
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
|
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
|
||||||
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
|
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
|
||||||
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
|
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
|
||||||
|
@ -136,39 +126,25 @@ declare module '@vue/runtime-core' {
|
||||||
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
|
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
|
||||||
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
||||||
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
||||||
NAlert: typeof import('naive-ui')['NAlert']
|
|
||||||
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
||||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
|
||||||
NCode: typeof import('naive-ui')['NCode']
|
NCode: typeof import('naive-ui')['NCode']
|
||||||
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
||||||
NColorPicker: typeof import('naive-ui')['NColorPicker']
|
|
||||||
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||||
NDatePicker: typeof import('naive-ui')['NDatePicker']
|
|
||||||
NDivider: typeof import('naive-ui')['NDivider']
|
NDivider: typeof import('naive-ui')['NDivider']
|
||||||
NDynamicInput: typeof import('naive-ui')['NDynamicInput']
|
|
||||||
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
||||||
NForm: typeof import('naive-ui')['NForm']
|
|
||||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||||
NGi: typeof import('naive-ui')['NGi']
|
NGi: typeof import('naive-ui')['NGi']
|
||||||
NGrid: typeof import('naive-ui')['NGrid']
|
NGrid: typeof import('naive-ui')['NGrid']
|
||||||
NH1: typeof import('naive-ui')['NH1']
|
NH1: typeof import('naive-ui')['NH1']
|
||||||
NH2: typeof import('naive-ui')['NH2']
|
|
||||||
NH3: typeof import('naive-ui')['NH3']
|
NH3: typeof import('naive-ui')['NH3']
|
||||||
NIcon: typeof import('naive-ui')['NIcon']
|
NIcon: typeof import('naive-ui')['NIcon']
|
||||||
NImage: typeof import('naive-ui')['NImage']
|
|
||||||
NInputGroup: typeof import('naive-ui')['NInputGroup']
|
|
||||||
NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel']
|
|
||||||
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
||||||
|
NLabel: typeof import('naive-ui')['NLabel']
|
||||||
NLayout: typeof import('naive-ui')['NLayout']
|
NLayout: typeof import('naive-ui')['NLayout']
|
||||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||||
NMenu: typeof import('naive-ui')['NMenu']
|
NMenu: typeof import('naive-ui')['NMenu']
|
||||||
NProgress: typeof import('naive-ui')['NProgress']
|
|
||||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||||
NSlider: typeof import('naive-ui')['NSlider']
|
NSpin: typeof import('naive-ui')['NSpin']
|
||||||
NStatistic: typeof import('naive-ui')['NStatistic']
|
|
||||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
|
||||||
NTable: typeof import('naive-ui')['NTable']
|
|
||||||
NTag: typeof import('naive-ui')['NTag']
|
|
||||||
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
||||||
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
||||||
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
"@tiptap/pm": "2.1.6",
|
"@tiptap/pm": "2.1.6",
|
||||||
"@tiptap/starter-kit": "2.1.6",
|
"@tiptap/starter-kit": "2.1.6",
|
||||||
"@tiptap/vue-3": "2.0.3",
|
"@tiptap/vue-3": "2.0.3",
|
||||||
|
"@types/figlet": "^1.5.8",
|
||||||
"@vicons/material": "^0.12.0",
|
"@vicons/material": "^0.12.0",
|
||||||
"@vicons/tabler": "^0.12.0",
|
"@vicons/tabler": "^0.12.0",
|
||||||
"@vueuse/core": "^10.3.0",
|
"@vueuse/core": "^10.3.0",
|
||||||
|
@ -58,6 +59,7 @@
|
||||||
"date-fns": "^2.29.3",
|
"date-fns": "^2.29.3",
|
||||||
"dompurify": "^3.0.6",
|
"dompurify": "^3.0.6",
|
||||||
"emojilib": "^3.0.10",
|
"emojilib": "^3.0.10",
|
||||||
|
"figlet": "^1.7.0",
|
||||||
"figue": "^1.2.0",
|
"figue": "^1.2.0",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
"highlight.js": "^11.7.0",
|
"highlight.js": "^11.7.0",
|
||||||
|
|
16
pnpm-lock.yaml
generated
16
pnpm-lock.yaml
generated
|
@ -23,6 +23,9 @@ dependencies:
|
||||||
'@tiptap/vue-3':
|
'@tiptap/vue-3':
|
||||||
specifier: 2.0.3
|
specifier: 2.0.3
|
||||||
version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.6)(vue@3.3.4)
|
version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.6)(vue@3.3.4)
|
||||||
|
'@types/figlet':
|
||||||
|
specifier: ^1.5.8
|
||||||
|
version: 1.5.8
|
||||||
'@vicons/material':
|
'@vicons/material':
|
||||||
specifier: ^0.12.0
|
specifier: ^0.12.0
|
||||||
version: 0.12.0
|
version: 0.12.0
|
||||||
|
@ -74,6 +77,9 @@ dependencies:
|
||||||
emojilib:
|
emojilib:
|
||||||
specifier: ^3.0.10
|
specifier: ^3.0.10
|
||||||
version: 3.0.10
|
version: 3.0.10
|
||||||
|
figlet:
|
||||||
|
specifier: ^1.7.0
|
||||||
|
version: 1.7.0
|
||||||
figue:
|
figue:
|
||||||
specifier: ^1.2.0
|
specifier: ^1.2.0
|
||||||
version: 1.2.0
|
version: 1.2.0
|
||||||
|
@ -2935,6 +2941,10 @@ packages:
|
||||||
/@types/estree@1.0.0:
|
/@types/estree@1.0.0:
|
||||||
resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
|
resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
|
||||||
|
|
||||||
|
/@types/figlet@1.5.8:
|
||||||
|
resolution: {integrity: sha512-G22AUvy4Tl95XLE7jmUM8s8mKcoz+Hr+Xm9W90gJsppJq9f9tHvOGkrpn4gRX0q/cLtBdNkWtWCKDg2UDZoZvQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@types/fs-extra@11.0.1:
|
/@types/fs-extra@11.0.1:
|
||||||
resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==}
|
resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -5870,6 +5880,12 @@ packages:
|
||||||
web-streams-polyfill: 3.2.1
|
web-streams-polyfill: 3.2.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/figlet@1.7.0:
|
||||||
|
resolution: {integrity: sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg==}
|
||||||
|
engines: {node: '>= 0.4.0'}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/figue@1.2.0:
|
/figue@1.2.0:
|
||||||
resolution: {integrity: sha512-CXKr12kiNWjKtUK3X+YHeXKepn80s9Rg6pgZXoLQYEybgwaGJ9uGW4DrBrVK30ZWZf1mcvTbXF56AcovG7gLVw==}
|
resolution: {integrity: sha512-CXKr12kiNWjKtUK3X+YHeXKepn80s9Rg6pgZXoLQYEybgwaGJ9uGW4DrBrVK30ZWZf1mcvTbXF56AcovG7gLVw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
93
src/tools/ascii-text-drawer/ascii-text-drawer.vue
Normal file
93
src/tools/ascii-text-drawer/ascii-text-drawer.vue
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import figlet from 'figlet';
|
||||||
|
import TextareaCopyable from '@/components/TextareaCopyable.vue';
|
||||||
|
|
||||||
|
const input = ref('Ascii ART');
|
||||||
|
const font = useStorage('ascii-text-drawer:font', 'Standard');
|
||||||
|
const width = useStorage('ascii-text-drawer:width', 80);
|
||||||
|
const output = ref('');
|
||||||
|
const errored = ref(false);
|
||||||
|
const processing = ref(false);
|
||||||
|
|
||||||
|
figlet.defaults({ fontPath: '//unpkg.com/figlet@1.6.0/fonts/' });
|
||||||
|
|
||||||
|
watchEffect(async () => {
|
||||||
|
processing.value = true;
|
||||||
|
try {
|
||||||
|
const options: figlet.Options = {
|
||||||
|
font: font.value as figlet.Fonts,
|
||||||
|
width: width.value,
|
||||||
|
whitespaceBreak: true,
|
||||||
|
};
|
||||||
|
output.value = await (new Promise<string>((resolve, reject) =>
|
||||||
|
figlet.text(input.value, options,
|
||||||
|
(err, text) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(text ?? '');
|
||||||
|
})));
|
||||||
|
errored.value = false;
|
||||||
|
}
|
||||||
|
catch (e: any) {
|
||||||
|
errored.value = true;
|
||||||
|
}
|
||||||
|
processing.value = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
const fonts = ['1Row', '3-D', '3D Diagonal', '3D-ASCII', '3x5', '4Max', '5 Line Oblique', 'AMC 3 Line', 'AMC 3 Liv1', 'AMC AAA01', 'AMC Neko', 'AMC Razor', 'AMC Razor2', 'AMC Slash', 'AMC Slider', 'AMC Thin', 'AMC Tubes', 'AMC Untitled', 'ANSI Shadow', 'ASCII New Roman', 'Acrobatic', 'Alligator', 'Alligator2', 'Alpha', 'Alphabet', 'Arrows', 'Avatar', 'B1FF', 'B1FF', 'Banner', 'Banner3-D', 'Banner3', 'Banner4', 'Barbwire', 'Basic', 'Bear', 'Bell', 'Benjamin', 'Big Chief', 'Big Money-ne', 'Big Money-nw', 'Big Money-se', 'Big Money-sw', 'Big', 'Bigfig', 'Binary', 'Block', 'Blocks', 'Bloody', 'Bolger', 'Braced', 'Bright', 'Broadway KB', 'Broadway', 'Bubble', 'Bulbhead', 'Caligraphy', 'Caligraphy2', 'Calvin S', 'Cards', 'Catwalk', 'Chiseled', 'Chunky', 'Coinstak', 'Cola', 'Colossal', 'Computer', 'Contessa', 'Contrast', 'Cosmike', 'Crawford', 'Crawford2', 'Crazy', 'Cricket', 'Cursive', 'Cyberlarge', 'Cybermedium', 'Cybersmall', 'Cygnet', 'DANC4', 'DOS Rebel', 'DWhistled', 'Dancing Font', 'Decimal', 'Def Leppard', 'Delta Corps Priest 1', 'Diamond', 'Diet Cola', 'Digital', 'Doh', 'Doom', 'Dot Matrix', 'Double Shorts', 'Double', 'Dr Pepper', 'Efti Chess', 'Efti Font', 'Efti Italic', 'Efti Piti', 'Efti Robot', 'Efti Wall', 'Efti Water', 'Electronic', 'Elite', 'Epic', 'Fender', 'Filter', 'Fire Font-k', 'Fire Font-s', 'Flipped', 'Flower Power', 'Four Tops', 'Fraktur', 'Fun Face', 'Fun Faces', 'Fuzzy', 'Georgi16', 'Georgia11', 'Ghost', 'Ghoulish', 'Glenyn', 'Goofy', 'Gothic', 'Graceful', 'Gradient', 'Graffiti', 'Greek', 'Heart Left', 'Heart Right', 'Henry 3D', 'Hex', 'Hieroglyphs', 'Hollywood', 'Horizontal Left', 'Horizontal Right', 'ICL-1900', 'Impossible', 'Invita', 'Isometric1', 'Isometric2', 'Isometric3', 'Isometric4', 'Italic', 'Ivrit', 'JS Block Letters', 'JS Bracket Letters', 'JS Capital Curves', 'JS Cursive', 'JS Stick Letters', 'Jacky', 'Jazmine', 'Jerusalem', 'Katakana', 'Kban', 'Keyboard', 'Knob', 'Konto Slant', 'Konto', 'LCD', 'Larry 3D 2', 'Larry 3D', 'Lean', 'Letters', 'Lil Devil', 'Line Blocks', 'Linux', 'Lockergnome', 'Madrid', 'Marquee', 'Maxfour', 'Merlin1', 'Merlin2', 'Mike', 'Mini', 'Mirror', 'Mnemonic', 'Modular', 'Morse', 'Morse2', 'Moscow', 'Mshebrew210', 'Muzzle', 'NScript', 'NT Greek', 'NV Script', 'Nancyj-Fancy', 'Nancyj-Improved', 'Nancyj-Underlined', 'Nancyj', 'Nipples', 'O8', 'OS2', 'Octal', 'Ogre', 'Old Banner', 'Patorjk\'s Cheese', 'Patorjk-HeX', 'Pawp', 'Peaks Slant', 'Peaks', 'Pebbles', 'Pepper', 'Poison', 'Puffy', 'Puzzle', 'Pyramid', 'Rammstein', 'Rectangles', 'Red Phoenix', 'Relief', 'Relief2', 'Reverse', 'Roman', 'Rot13', 'Rot13', 'Rotated', 'Rounded', 'Rowan Cap', 'Rozzo', 'Runic', 'Runyc', 'S Blood', 'SL Script', 'Santa Clara', 'Script', 'Serifcap', 'Shadow', 'Shimrod', 'Short', 'Slant Relief', 'Slant', 'Slide', 'Small Caps', 'Small Isometric1', 'Small Keyboard', 'Small Poison', 'Small Script', 'Small Shadow', 'Small Slant', 'Small Tengwar', 'Small', 'Soft', 'Speed', 'Spliff', 'Stacey', 'Stampate', 'Stampatello', 'Standard', 'Star Strips', 'Star Wars', 'Stellar', 'Stforek', 'Stick Letters', 'Stop', 'Straight', 'Stronger Than All', 'Sub-Zero', 'Swamp Land', 'Swan', 'Sweet', 'THIS', 'Tanja', 'Tengwar', 'Term', 'Test1', 'The Edge', 'Thick', 'Thin', 'Thorned', 'Three Point', 'Ticks Slant', 'Ticks', 'Tiles', 'Tinker-Toy', 'Tombstone', 'Train', 'Trek', 'Tsalagi', 'Tubular', 'Twisted', 'Two Point', 'USA Flag', 'Univers', 'Varsity', 'Wavy', 'Weird', 'Wet Letter', 'Whimsy', 'Wow'];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<c-card style="max-width: 600px;">
|
||||||
|
<c-input-text
|
||||||
|
v-model:value="input"
|
||||||
|
label="Your text:"
|
||||||
|
placeholder="Your text to draw"
|
||||||
|
raw-text
|
||||||
|
multiline
|
||||||
|
rows="4"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<n-divider />
|
||||||
|
|
||||||
|
<n-grid cols="4" x-gap="12" w-full>
|
||||||
|
<n-gi span="2">
|
||||||
|
<c-select
|
||||||
|
v-model:value="font"
|
||||||
|
label-position="top"
|
||||||
|
label="Font:"
|
||||||
|
:options="fonts"
|
||||||
|
searchable="true"
|
||||||
|
placeholder="Select font to use"
|
||||||
|
/>
|
||||||
|
</n-gi>
|
||||||
|
<n-gi span="2">
|
||||||
|
<n-form-item label="Width:" label-placement="top" label-width="100" :show-feedback="false">
|
||||||
|
<n-input-number v-model:value="width" min="0" max="10000" w-full placeholder="Width of the text" />
|
||||||
|
</n-form-item>
|
||||||
|
</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
|
||||||
|
<n-divider />
|
||||||
|
|
||||||
|
<div v-if="processing" flex items-center justify-center>
|
||||||
|
<n-spin size="medium" />
|
||||||
|
<span class="ml-2">Loading font...</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<c-alert v-if="errored" mt-1 text-center type="error">
|
||||||
|
Current settings resulted in error.
|
||||||
|
</c-alert>
|
||||||
|
|
||||||
|
<n-form-item v-if="!processing && !errored" label="Ascii Art text:">
|
||||||
|
<TextareaCopyable
|
||||||
|
:value="output"
|
||||||
|
mb-1 mt-1
|
||||||
|
copy-placement="outside"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
</c-card>
|
||||||
|
</template>
|
12
src/tools/ascii-text-drawer/index.ts
Normal file
12
src/tools/ascii-text-drawer/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { Artboard } from '@vicons/tabler';
|
||||||
|
import { defineTool } from '../tool';
|
||||||
|
|
||||||
|
export const tool = defineTool({
|
||||||
|
name: 'ASCII Art Text Generator',
|
||||||
|
path: '/ascii-text-drawer',
|
||||||
|
description: 'Create ASCII art text with many fonts and styles.',
|
||||||
|
keywords: ['ascii', 'asciiart', 'text', 'drawer'],
|
||||||
|
component: () => import('./ascii-text-drawer.vue'),
|
||||||
|
icon: Artboard,
|
||||||
|
createdAt: new Date('2024-03-03'),
|
||||||
|
});
|
|
@ -1,8 +1,12 @@
|
||||||
import { tool as base64FileConverter } from './base64-file-converter';
|
import { tool as base64FileConverter } from './base64-file-converter';
|
||||||
import { tool as base64StringConverter } from './base64-string-converter';
|
import { tool as base64StringConverter } from './base64-string-converter';
|
||||||
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
||||||
|
|
||||||
|
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
||||||
|
|
||||||
import { tool as textToUnicode } from './text-to-unicode';
|
import { tool as textToUnicode } from './text-to-unicode';
|
||||||
import { tool as htpasswdGenerator } from './htpasswd-generator';
|
import { tool as htpasswdGenerator } from './htpasswd-generator';
|
||||||
|
import { tool as safelinkDecoder } from './safelink-decoder';
|
||||||
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
|
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
|
||||||
import { tool as numeronymGenerator } from './numeronym-generator';
|
import { tool as numeronymGenerator } from './numeronym-generator';
|
||||||
import { tool as macAddressGenerator } from './mac-address-generator';
|
import { tool as macAddressGenerator } from './mac-address-generator';
|
||||||
|
@ -125,6 +129,7 @@ export const toolsByCategory: ToolCategory[] = [
|
||||||
userAgentParser,
|
userAgentParser,
|
||||||
httpStatusCodes,
|
httpStatusCodes,
|
||||||
jsonDiff,
|
jsonDiff,
|
||||||
|
safelinkDecoder,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -161,7 +166,15 @@ export const toolsByCategory: ToolCategory[] = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Text',
|
name: 'Text',
|
||||||
components: [loremIpsumGenerator, textStatistics, emojiPicker, stringObfuscator, textDiff, numeronymGenerator],
|
components: [
|
||||||
|
loremIpsumGenerator,
|
||||||
|
textStatistics,
|
||||||
|
emojiPicker,
|
||||||
|
stringObfuscator,
|
||||||
|
textDiff,
|
||||||
|
numeronymGenerator,
|
||||||
|
asciiTextDrawer,
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Data',
|
name: 'Data',
|
||||||
|
|
12
src/tools/safelink-decoder/index.ts
Normal file
12
src/tools/safelink-decoder/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { Mailbox } from '@vicons/tabler';
|
||||||
|
import { defineTool } from '../tool';
|
||||||
|
|
||||||
|
export const tool = defineTool({
|
||||||
|
name: 'Outlook Safelink decoder',
|
||||||
|
path: '/safelink-decoder',
|
||||||
|
description: 'Decode Outlook SafeLink links',
|
||||||
|
keywords: ['outlook', 'safelink', 'decoder'],
|
||||||
|
component: () => import('./safelink-decoder.vue'),
|
||||||
|
icon: Mailbox,
|
||||||
|
createdAt: new Date('2024-03-11'),
|
||||||
|
});
|
21
src/tools/safelink-decoder/safelink-decoder.service.test.ts
Normal file
21
src/tools/safelink-decoder/safelink-decoder.service.test.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { decodeSafeLinksURL } from './safelink-decoder.service';
|
||||||
|
|
||||||
|
describe('safelink-decoder', () => {
|
||||||
|
describe('decodeSafeLinksURL', () => {
|
||||||
|
describe('decode outlook safelink urls', () => {
|
||||||
|
it('should decode basic safelink urls', () => {
|
||||||
|
expect(decodeSafeLinksURL('https://aus01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.google.com%2Fsearch%3Fq%3Dsafelink%26rlz%3D1&data=05%7C02%7C%7C1ed07253975b46da1d1508dc3443752a%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638442711583216725%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=%2BQY0HBnnxfI7pzZoxzlhZdDvYu80LwQB0zUUjrffVnk%3D&reserved=0'))
|
||||||
|
.toBe('https://www.google.com/search?q=safelink&rlz=1');
|
||||||
|
});
|
||||||
|
it('should decode encoded safelink urls', () => {
|
||||||
|
expect(decodeSafeLinksURL('https://aus01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.google.com%2Fsearch%3Fq%3Dsafelink%26rlz%3D1&data=05%7C02%7C%7C1ed07253975b46da1d1508dc3443752a%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638442711583216725%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=%2BQY0HBnnxfI7pzZoxzlhZdDvYu80LwQB0zUUjrffVnk%3D&reserved=0'))
|
||||||
|
.toBe('https://www.google.com/search?q=safelink&rlz=1');
|
||||||
|
});
|
||||||
|
it('throw on not outlook safelink urls', () => {
|
||||||
|
expect(() => decodeSafeLinksURL('https://google.com'))
|
||||||
|
.toThrow('Invalid SafeLinks URL provided');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
7
src/tools/safelink-decoder/safelink-decoder.service.ts
Normal file
7
src/tools/safelink-decoder/safelink-decoder.service.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export function decodeSafeLinksURL(safeLinksUrl: string) {
|
||||||
|
if (!safeLinksUrl.match(/\.safelinks\.protection\.outlook\.com/)) {
|
||||||
|
throw new Error('Invalid SafeLinks URL provided');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new URL(safeLinksUrl).searchParams.get('url');
|
||||||
|
}
|
32
src/tools/safelink-decoder/safelink-decoder.vue
Normal file
32
src/tools/safelink-decoder/safelink-decoder.vue
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { decodeSafeLinksURL } from './safelink-decoder.service';
|
||||||
|
import TextareaCopyable from '@/components/TextareaCopyable.vue';
|
||||||
|
|
||||||
|
const inputSafeLinkUrl = ref('');
|
||||||
|
const outputDecodedUrl = computed(() => {
|
||||||
|
try {
|
||||||
|
return decodeSafeLinksURL(inputSafeLinkUrl.value);
|
||||||
|
}
|
||||||
|
catch (e: any) {
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<c-input-text
|
||||||
|
v-model:value="inputSafeLinkUrl"
|
||||||
|
raw-text
|
||||||
|
placeholder="Your input Outlook SafeLink Url..."
|
||||||
|
autofocus
|
||||||
|
label="Your input Outlook SafeLink Url:"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<n-divider />
|
||||||
|
|
||||||
|
<n-form-item label="Output decoded URL:">
|
||||||
|
<TextareaCopyable :value="outputDecodedUrl" :word-wrap="true" />
|
||||||
|
</n-form-item>
|
||||||
|
</div>
|
||||||
|
</template>
|
Loading…
Add table
Add a link
Reference in a new issue