+
+
+ Current settings resulted in error.
+
+
+
+
+
+
+
diff --git a/src/tools/ascii-text-drawer/index.ts b/src/tools/ascii-text-drawer/index.ts
new file mode 100644
index 00000000..cc1ba86c
--- /dev/null
+++ b/src/tools/ascii-text-drawer/index.ts
@@ -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'),
+});
diff --git a/src/tools/base64-file-converter/base64-file-converter.vue b/src/tools/base64-file-converter/base64-file-converter.vue
index e607c018..a489f9a1 100644
--- a/src/tools/base64-file-converter/base64-file-converter.vue
+++ b/src/tools/base64-file-converter/base64-file-converter.vue
@@ -1,15 +1,20 @@
+
+
+
+
+ Raw emails to normalize:
+
+
+
+
+ Normalized emails:
+
+
+
+
+ Clear emails
+
+
+ Copy normalized emails
+
+
+
+
diff --git a/src/tools/email-normalizer/index.ts b/src/tools/email-normalizer/index.ts
new file mode 100644
index 00000000..299a30f7
--- /dev/null
+++ b/src/tools/email-normalizer/index.ts
@@ -0,0 +1,12 @@
+import { Mail } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'Email normalizer',
+ path: '/email-normalizer',
+ description: 'Normalize email addresses to a standard format for easier comparison. Useful for deduplication and data cleaning.',
+ keywords: ['email', 'normalizer'],
+ component: () => import('./email-normalizer.vue'),
+ icon: Mail,
+ createdAt: new Date('2024-08-15'),
+});
diff --git a/src/tools/emoji-picker/emoji-picker.vue b/src/tools/emoji-picker/emoji-picker.vue
index 750695f5..a12b10c2 100644
--- a/src/tools/emoji-picker/emoji-picker.vue
+++ b/src/tools/emoji-picker/emoji-picker.vue
@@ -4,6 +4,7 @@ import emojiKeywords from 'emojilib';
import _ from 'lodash';
import type { EmojiInfo } from './emoji.types';
import { useFuzzySearch } from '@/composable/fuzzySearch';
+import useDebouncedRef from '@/composable/debouncedref';
const escapeUnicode = ({ emoji }: { emoji: string }) => emoji.split('').map(unit => `\\u${unit.charCodeAt(0).toString(16).padStart(4, '0')}`).join('');
const getEmojiCodePoints = ({ emoji }: { emoji: string }) => emoji.codePointAt(0) ? `0x${emoji.codePointAt(0)?.toString(16)}` : undefined;
@@ -23,7 +24,7 @@ const emojisGroups: { emojiInfos: EmojiInfo[]; group: string }[] = _
.map((emojiInfos, group) => ({ group, emojiInfos }))
.value();
-const searchQuery = ref('');
+const searchQuery = useDebouncedRef('', 500);
const { searchResult } = useFuzzySearch({
search: searchQuery,
diff --git a/src/tools/emoji-picker/index.ts b/src/tools/emoji-picker/index.ts
index ef01b2de..3a28cf0f 100644
--- a/src/tools/emoji-picker/index.ts
+++ b/src/tools/emoji-picker/index.ts
@@ -1,10 +1,11 @@
import { MoodSmile } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Emoji picker',
+ name: translate('tools.emoji-picker.title'),
path: '/emoji-picker',
- description: 'Copy and paste emojis easily and get the unicode and code points value of each emoji.',
+ description: translate('tools.emoji-picker.description'),
keywords: ['emoji', 'picker', 'unicode', 'copy', 'paste'],
component: () => import('./emoji-picker.vue'),
icon: MoodSmile,
diff --git a/src/tools/encryption/index.ts b/src/tools/encryption/index.ts
index 9a95f4bc..c8dd85db 100644
--- a/src/tools/encryption/index.ts
+++ b/src/tools/encryption/index.ts
@@ -1,10 +1,11 @@
import { Lock } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Encrypt / decrypt text',
+ name: translate('tools.encryption.title'),
path: '/encryption',
- description: 'Encrypt and decrypt text clear text using crypto algorithm like AES, TripleDES, Rabbit or RC4.',
+ description: translate('tools.encryption.description'),
keywords: ['cypher', 'encipher', 'text', 'AES', 'TripleDES', 'Rabbit', 'RC4'],
component: () => import('./encryption.vue'),
icon: Lock,
diff --git a/src/tools/eta-calculator/eta-calculator.vue b/src/tools/eta-calculator/eta-calculator.vue
index a81a77de..e1c36a62 100644
--- a/src/tools/eta-calculator/eta-calculator.vue
+++ b/src/tools/eta-calculator/eta-calculator.vue
@@ -26,8 +26,8 @@ const endAt = computed(() =>
- With a concrete example, if you wash 3 plates in 5 minutes and you have 500 plates to wash, it will take you 5
- hours and 10 minutes to wash them all.
+ With a concrete example, if you wash 5 plates in 3 minutes and you have 500 plates to wash, it will take you 5
+ hours to wash them all.
diff --git a/src/tools/eta-calculator/index.ts b/src/tools/eta-calculator/index.ts
index abda2870..5016ab66 100644
--- a/src/tools/eta-calculator/index.ts
+++ b/src/tools/eta-calculator/index.ts
@@ -1,11 +1,11 @@
import { Hourglass } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'ETA calculator',
+ name: translate('tools.eta-calculator.title'),
path: '/eta-calculator',
- description:
- 'An ETA (Estimated Time of Arrival) calculator to know the approximate end time of a task, for example the moment of ending of a download.',
+ description: translate('tools.eta-calculator.description'),
keywords: ['eta', 'calculator', 'estimated', 'time', 'arrival', 'average'],
component: () => import('./eta-calculator.vue'),
icon: Hourglass,
diff --git a/src/tools/git-memo/index.ts b/src/tools/git-memo/index.ts
index c91ee813..f65ffe07 100644
--- a/src/tools/git-memo/index.ts
+++ b/src/tools/git-memo/index.ts
@@ -1,11 +1,11 @@
import { BrandGit } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Git cheatsheet',
+ name: translate('tools.git-memo.title'),
path: '/git-memo',
- description:
- 'Git is a decentralized version management software. With this cheatsheet you will have a quick access to the most common git commands.',
+ description: translate('tools.git-memo.description'),
keywords: ['git', 'push', 'force', 'pull', 'commit', 'amend', 'rebase', 'merge', 'reset', 'soft', 'hard', 'lease'],
component: () => import('./git-memo.vue'),
icon: BrandGit,
diff --git a/src/tools/hash-text/index.ts b/src/tools/hash-text/index.ts
index 3012747c..2070e41d 100644
--- a/src/tools/hash-text/index.ts
+++ b/src/tools/hash-text/index.ts
@@ -1,11 +1,11 @@
import { EyeOff } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Hash text',
+ name: translate('tools.hash-text.title'),
path: '/hash-text',
- description:
- 'Hash a text string using the function you need : MD5, SHA1, SHA256, SHA224, SHA512, SHA384, SHA3 or RIPEMD160',
+ description: translate('tools.hash-text.description'),
keywords: [
'hash',
'digest',
diff --git a/src/tools/hmac-generator/index.ts b/src/tools/hmac-generator/index.ts
index c0ca7da4..3500684e 100644
--- a/src/tools/hmac-generator/index.ts
+++ b/src/tools/hmac-generator/index.ts
@@ -1,11 +1,11 @@
import { ShortTextRound } from '@vicons/material';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Hmac generator',
+ name: translate('tools.hmac-generator.title'),
path: '/hmac-generator',
- description:
- 'Computes a hash-based message authentication code (HMAC) using a secret key and your favorite hashing function.',
+ description: translate('tools.hmac-generator.description'),
keywords: ['hmac', 'generator', 'MD5', 'SHA1', 'SHA256', 'SHA224', 'SHA512', 'SHA384', 'SHA3', 'RIPEMD160'],
component: () => import('./hmac-generator.vue'),
icon: ShortTextRound,
diff --git a/src/tools/html-entities/index.ts b/src/tools/html-entities/index.ts
index 4907dc68..e292f087 100644
--- a/src/tools/html-entities/index.ts
+++ b/src/tools/html-entities/index.ts
@@ -1,10 +1,11 @@
import { Code } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Escape html entities',
+ name: translate('tools.html-entities.title'),
path: '/html-entities',
- description: 'Escape or unescape html entities (replace <,>, &, " and \' to their html version)',
+ description: translate('tools.html-entities.description'),
keywords: ['html', 'entities', 'escape', 'unescape', 'special', 'characters', 'tags'],
component: () => import('./html-entities.vue'),
icon: Code,
diff --git a/src/tools/html-wysiwyg-editor/editor/menu-bar.vue b/src/tools/html-wysiwyg-editor/editor/menu-bar.vue
index d3ad3168..9069673c 100644
--- a/src/tools/html-wysiwyg-editor/editor/menu-bar.vue
+++ b/src/tools/html-wysiwyg-editor/editor/menu-bar.vue
@@ -84,8 +84,8 @@ const items: MenuItem[] = [
type: 'button',
icon: H3,
title: 'Heading 3',
- action: () => editor.value.chain().focus().toggleHeading({ level: 4 }).run(),
- isActive: () => editor.value.isActive('heading', { level: 4 }),
+ action: () => editor.value.chain().focus().toggleHeading({ level: 3 }).run(),
+ isActive: () => editor.value.isActive('heading', { level: 3 }),
},
{
type: 'button',
diff --git a/src/tools/html-wysiwyg-editor/index.ts b/src/tools/html-wysiwyg-editor/index.ts
index 461ad235..3a2ab007 100644
--- a/src/tools/html-wysiwyg-editor/index.ts
+++ b/src/tools/html-wysiwyg-editor/index.ts
@@ -1,10 +1,11 @@
import { Edit } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'HTML WYSIWYG editor',
+ name: translate('tools.html-wysiwyg-editor.title'),
path: '/html-wysiwyg-editor',
- description: 'Online HTML editor with feature-rich WYSIWYG editor, get the source code of the content immediately.',
+ description: translate('tools.html-wysiwyg-editor.description'),
keywords: ['html', 'wysiwyg', 'editor', 'p', 'ul', 'ol', 'converter', 'live'],
component: () => import('./html-wysiwyg-editor.vue'),
icon: Edit,
diff --git a/src/tools/http-status-codes/index.ts b/src/tools/http-status-codes/index.ts
index 43afae83..b3138943 100644
--- a/src/tools/http-status-codes/index.ts
+++ b/src/tools/http-status-codes/index.ts
@@ -2,11 +2,12 @@ import { HttpRound } from '@vicons/material';
import { defineTool } from '../tool';
import { codesByCategories } from './http-status-codes.constants';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'HTTP status codes',
+ name: translate('tools.http-status-codes.title'),
path: '/http-status-codes',
- description: 'The list of all HTTP status codes their name and their meaning.',
+ description: translate('tools.http-status-codes.description'),
keywords: [
'http',
'status',
diff --git a/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue b/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue
index 647be983..6844dc5a 100644
--- a/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue
+++ b/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue
@@ -60,9 +60,11 @@ const ibanExamples = [
-
+
+
+
-
+
diff --git a/src/tools/iban-validator-and-parser/index.ts b/src/tools/iban-validator-and-parser/index.ts
index b0cae50d..ff7ff135 100644
--- a/src/tools/iban-validator-and-parser/index.ts
+++ b/src/tools/iban-validator-and-parser/index.ts
@@ -1,10 +1,11 @@
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
import Bank from '~icons/mdi/bank';
export const tool = defineTool({
- name: 'IBAN validator and parser',
+ name: translate('tools.iban-validator-and-parser.title'),
path: '/iban-validator-and-parser',
- description: 'Validate and parse IBAN numbers. Check if IBAN is valid and get the country, BBAN, if it is a QR-IBAN and the IBAN friendly format.',
+ description: translate('tools.iban-validator-and-parser.description'),
keywords: ['iban', 'validator', 'and', 'parser', 'bic', 'bank'],
component: () => import('./iban-validator-and-parser.vue'),
icon: Bank,
diff --git a/src/tools/index.ts b/src/tools/index.ts
index 22db0770..388cfaf4 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -1,6 +1,19 @@
import { tool as base64FileConverter } from './base64-file-converter';
import { tool as base64StringConverter } from './base64-string-converter';
import { tool as basicAuthGenerator } from './basic-auth-generator';
+import { tool as emailNormalizer } from './email-normalizer';
+
+import { tool as asciiTextDrawer } from './ascii-text-drawer';
+
+import { tool as textToUnicode } from './text-to-unicode';
+import { tool as safelinkDecoder } from './safelink-decoder';
+import { tool as xmlToJson } from './xml-to-json';
+import { tool as jsonToXml } from './json-to-xml';
+import { tool as regexTester } from './regex-tester';
+import { tool as regexMemo } from './regex-memo';
+import { tool as markdownToHtml } from './markdown-to-html';
+import { tool as pdfSignatureChecker } from './pdf-signature-checker';
+import { tool as numeronymGenerator } from './numeronym-generator';
import { tool as macAddressGenerator } from './mac-address-generator';
import { tool as textToBinary } from './text-to-binary';
import { tool as ulidGenerator } from './ulid-generator';
@@ -73,11 +86,12 @@ import { tool as urlParser } from './url-parser';
import { tool as uuidGenerator } from './uuid-generator';
import { tool as macAddressLookup } from './mac-address-lookup';
import { tool as xmlFormatter } from './xml-formatter';
+import { tool as yamlViewer } from './yaml-viewer';
export const toolsByCategory: ToolCategory[] = [
{
name: 'Crypto',
- components: [tokenGenerator, hashText, bcrypt, uuidGenerator, ulidGenerator, cypher, bip39, hmacGenerator, rsaKeyPairGenerator, passwordStrengthAnalyser],
+ components: [tokenGenerator, hashText, bcrypt, uuidGenerator, ulidGenerator, cypher, bip39, hmacGenerator, rsaKeyPairGenerator, passwordStrengthAnalyser, pdfSignatureChecker],
},
{
name: 'Converter',
@@ -91,6 +105,7 @@ export const toolsByCategory: ToolCategory[] = [
caseConverter,
textToNatoAlphabet,
textToBinary,
+ textToUnicode,
yamlToJson,
yamlToToml,
jsonToYaml,
@@ -98,6 +113,9 @@ export const toolsByCategory: ToolCategory[] = [
listConverter,
tomlToJson,
tomlToYaml,
+ xmlToJson,
+ jsonToXml,
+ markdownToHtml,
],
},
{
@@ -118,6 +136,7 @@ export const toolsByCategory: ToolCategory[] = [
userAgentParser,
httpStatusCodes,
jsonDiff,
+ safelinkDecoder,
],
},
{
@@ -137,6 +156,10 @@ export const toolsByCategory: ToolCategory[] = [
chmodCalculator,
dockerRunToDockerComposeConverter,
xmlFormatter,
+ yamlViewer,
+ emailNormalizer,
+ regexTester,
+ regexMemo,
],
},
{
@@ -153,7 +176,15 @@ export const toolsByCategory: ToolCategory[] = [
},
{
name: 'Text',
- components: [loremIpsumGenerator, textStatistics, emojiPicker, stringObfuscator, textDiff],
+ components: [
+ loremIpsumGenerator,
+ textStatistics,
+ emojiPicker,
+ stringObfuscator,
+ textDiff,
+ numeronymGenerator,
+ asciiTextDrawer,
+ ],
},
{
name: 'Data',
diff --git a/src/tools/integer-base-converter/index.ts b/src/tools/integer-base-converter/index.ts
index 0008568c..f60d996d 100644
--- a/src/tools/integer-base-converter/index.ts
+++ b/src/tools/integer-base-converter/index.ts
@@ -1,10 +1,11 @@
import { ArrowsLeftRight } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Integer base converter',
+ name: translate('tools.base-converter.title'),
path: '/base-converter',
- description: 'Convert number between different bases (decimal, hexadecimal, binary, octal, base64, ...)',
+ description: translate('tools.base-converter.description'),
keywords: ['integer', 'number', 'base', 'conversion', 'decimal', 'hexadecimal', 'binary', 'octal', 'base64'],
component: () => import('./integer-base-converter.vue'),
icon: ArrowsLeftRight,
diff --git a/src/tools/integer-base-converter/integer-base-converter.model.test.ts b/src/tools/integer-base-converter/integer-base-converter.model.test.ts
index d0387b64..c7d7db79 100644
--- a/src/tools/integer-base-converter/integer-base-converter.model.test.ts
+++ b/src/tools/integer-base-converter/integer-base-converter.model.test.ts
@@ -11,6 +11,9 @@ describe('integer-base-converter', () => {
expect(convertBase({ value: '10100101', fromBase: 2, toBase: 16 })).toEqual('a5');
expect(convertBase({ value: '192654', fromBase: 10, toBase: 8 })).toEqual('570216');
expect(convertBase({ value: 'zz', fromBase: 64, toBase: 10 })).toEqual('2275');
+ expect(convertBase({ value: '42540766411283223938465490632011909384', fromBase: 10, toBase: 10 })).toEqual('42540766411283223938465490632011909384');
+ expect(convertBase({ value: '42540766411283223938465490632011909384', fromBase: 10, toBase: 16 })).toEqual('20010db8000085a300000000ac1f8908');
+ expect(convertBase({ value: '20010db8000085a300000000ac1f8908', fromBase: 16, toBase: 10 })).toEqual('42540766411283223938465490632011909384');
});
});
});
diff --git a/src/tools/integer-base-converter/integer-base-converter.model.ts b/src/tools/integer-base-converter/integer-base-converter.model.ts
index b4470e57..da0fe77f 100644
--- a/src/tools/integer-base-converter/integer-base-converter.model.ts
+++ b/src/tools/integer-base-converter/integer-base-converter.model.ts
@@ -5,16 +5,16 @@ export function convertBase({ value, fromBase, toBase }: { value: string; fromBa
let decValue = value
.split('')
.reverse()
- .reduce((carry: number, digit: string, index: number) => {
+ .reduce((carry: bigint, digit: string, index: number) => {
if (!fromRange.includes(digit)) {
throw new Error(`Invalid digit "${digit}" for base ${fromBase}.`);
}
- return (carry += fromRange.indexOf(digit) * fromBase ** index);
- }, 0);
+ return (carry += BigInt(fromRange.indexOf(digit)) * BigInt(fromBase) ** BigInt(index));
+ }, 0n);
let newValue = '';
while (decValue > 0) {
- newValue = toRange[decValue % toBase] + newValue;
- decValue = (decValue - (decValue % toBase)) / toBase;
+ newValue = toRange[Number(decValue % BigInt(toBase))] + newValue;
+ decValue = (decValue - (decValue % BigInt(toBase))) / BigInt(toBase);
}
return newValue || '0';
}
diff --git a/src/tools/ipv4-address-converter/index.ts b/src/tools/ipv4-address-converter/index.ts
index 62d2daf1..66ae03a3 100644
--- a/src/tools/ipv4-address-converter/index.ts
+++ b/src/tools/ipv4-address-converter/index.ts
@@ -1,10 +1,11 @@
import { Binary } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Ipv4 address converter',
+ name: translate('tools.ipv4-address-converter.title'),
path: '/ipv4-address-converter',
- description: 'Convert an ip address into decimal, binary, hexadecimal or event in ipv6',
+ description: translate('tools.ipv4-address-converter.description'),
keywords: ['ipv4', 'address', 'converter', 'decimal', 'hexadecimal', 'binary', 'ipv6'],
component: () => import('./ipv4-address-converter.vue'),
icon: Binary,
diff --git a/src/tools/ipv4-range-expander/index.ts b/src/tools/ipv4-range-expander/index.ts
index 233f7cc4..49dfae95 100644
--- a/src/tools/ipv4-range-expander/index.ts
+++ b/src/tools/ipv4-range-expander/index.ts
@@ -1,11 +1,11 @@
import { UnfoldMoreOutlined } from '@vicons/material';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'IPv4 range expander',
+ name: translate('tools.ipv4-range-expander.title'),
path: '/ipv4-range-expander',
- description:
- 'Given a start and an end IPv4 address this tool calculates a valid IPv4 network with its CIDR notation.',
+ description: translate('tools.ipv4-range-expander.description'),
keywords: ['ipv4', 'range', 'expander', 'subnet', 'creator', 'cidr'],
component: () => import('./ipv4-range-expander.vue'),
icon: UnfoldMoreOutlined,
diff --git a/src/tools/ipv4-subnet-calculator/index.ts b/src/tools/ipv4-subnet-calculator/index.ts
index fb4bfb43..1bae7282 100644
--- a/src/tools/ipv4-subnet-calculator/index.ts
+++ b/src/tools/ipv4-subnet-calculator/index.ts
@@ -1,10 +1,11 @@
import { RouterOutlined } from '@vicons/material';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'IPv4 subnet calculator',
+ name: translate('tools.ipv4-subnet-calculator.title'),
path: '/ipv4-subnet-calculator',
- description: 'Parse your IPv4 CIDR blocks and get all the info you need about your sub network.',
+ description: translate('tools.ipv4-subnet-calculator.description'),
keywords: ['ipv4', 'subnet', 'calculator', 'mask', 'network', 'cidr', 'netmask', 'bitmask', 'broadcast', 'address'],
component: () => import('./ipv4-subnet-calculator.vue'),
icon: RouterOutlined,
diff --git a/src/tools/ipv6-ula-generator/index.ts b/src/tools/ipv6-ula-generator/index.ts
index 24efaeba..51bfd6fc 100644
--- a/src/tools/ipv6-ula-generator/index.ts
+++ b/src/tools/ipv6-ula-generator/index.ts
@@ -1,10 +1,11 @@
import { BuildingFactory } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'IPv6 ULA generator',
+ name: translate('tools.ipv6-ula-generator.title'),
path: '/ipv6-ula-generator',
- description: 'Generate your own local, non-routable IP addresses on your network according to RFC4193.',
+ description: translate('tools.ipv6-ula-generator.description'),
keywords: ['ipv6', 'ula', 'generator', 'rfc4193', 'network', 'private'],
component: () => import('./ipv6-ula-generator.vue'),
icon: BuildingFactory,
diff --git a/src/tools/json-diff/index.ts b/src/tools/json-diff/index.ts
index 7c4c1eee..a4c0319c 100644
--- a/src/tools/json-diff/index.ts
+++ b/src/tools/json-diff/index.ts
@@ -1,10 +1,11 @@
import { CompareArrowsRound } from '@vicons/material';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'JSON diff',
+ name: translate('tools.json-diff.title'),
path: '/json-diff',
- description: 'Compare two JSON objects and get the differences between them.',
+ description: translate('tools.json-diff.description'),
keywords: ['json', 'diff', 'compare', 'difference', 'object', 'data'],
component: () => import('./json-diff.vue'),
icon: CompareArrowsRound,
diff --git a/src/tools/json-minify/index.ts b/src/tools/json-minify/index.ts
index e6a02dbe..fbe5831b 100644
--- a/src/tools/json-minify/index.ts
+++ b/src/tools/json-minify/index.ts
@@ -1,10 +1,11 @@
import { Braces } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'JSON minify',
+ name: translate('tools.json-minify.title'),
path: '/json-minify',
- description: 'Minify and compress your JSON by removing unnecessary white spaces.',
+ description: translate('tools.json-minify.description'),
keywords: ['json', 'minify', 'format'],
component: () => import('./json-minify.vue'),
icon: Braces,
diff --git a/src/tools/json-to-csv/index.ts b/src/tools/json-to-csv/index.ts
index acfef02f..9f38b82f 100644
--- a/src/tools/json-to-csv/index.ts
+++ b/src/tools/json-to-csv/index.ts
@@ -1,10 +1,11 @@
import { List } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'JSON to CSV',
+ name: translate('tools.json-to-csv.title'),
path: '/json-to-csv',
- description: 'Convert JSON to CSV with automatic header detection.',
+ description: translate('tools.json-to-csv.description'),
keywords: ['json', 'to', 'csv', 'convert'],
component: () => import('./json-to-csv.vue'),
icon: List,
diff --git a/src/tools/json-to-toml/index.ts b/src/tools/json-to-toml/index.ts
index 13e45eaf..da42c18d 100644
--- a/src/tools/json-to-toml/index.ts
+++ b/src/tools/json-to-toml/index.ts
@@ -1,10 +1,11 @@
import { Braces } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'JSON to TOML',
+ name: translate('tools.json-to-toml.title'),
path: '/json-to-toml',
- description: 'Parse and convert JSON to TOML.',
+ description: translate('tools.json-to-toml.description'),
keywords: ['json', 'parse', 'toml', 'convert', 'transform'],
component: () => import('./json-to-toml.vue'),
icon: Braces,
diff --git a/src/tools/json-to-xml/index.ts b/src/tools/json-to-xml/index.ts
new file mode 100644
index 00000000..c35ace2b
--- /dev/null
+++ b/src/tools/json-to-xml/index.ts
@@ -0,0 +1,12 @@
+import { Braces } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'JSON to XML',
+ path: '/json-to-xml',
+ description: 'Convert JSON to XML',
+ keywords: ['json', 'xml'],
+ component: () => import('./json-to-xml.vue'),
+ icon: Braces,
+ createdAt: new Date('2024-08-09'),
+});
diff --git a/src/tools/json-to-xml/json-to-xml.vue b/src/tools/json-to-xml/json-to-xml.vue
new file mode 100644
index 00000000..96a7cf16
--- /dev/null
+++ b/src/tools/json-to-xml/json-to-xml.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
diff --git a/src/tools/json-to-yaml-converter/index.ts b/src/tools/json-to-yaml-converter/index.ts
index 9db09d3e..c01e3ec0 100644
--- a/src/tools/json-to-yaml-converter/index.ts
+++ b/src/tools/json-to-yaml-converter/index.ts
@@ -1,10 +1,11 @@
import { Braces } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'JSON to YAML converter',
+ name: translate('tools.json-to-yaml-converter.title'),
path: '/json-to-yaml-converter',
- description: 'Simply convert JSON to YAML with this live online converter.',
+ description: translate('tools.json-to-yaml-converter.description'),
keywords: ['yaml', 'to', 'json'],
component: () => import('./json-to-yaml.vue'),
icon: Braces,
diff --git a/src/tools/json-viewer/index.ts b/src/tools/json-viewer/index.ts
index 6b5b8812..bc488245 100644
--- a/src/tools/json-viewer/index.ts
+++ b/src/tools/json-viewer/index.ts
@@ -1,10 +1,11 @@
import { Braces } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'JSON prettify and format',
+ name: translate('tools.json-prettify.title'),
path: '/json-prettify',
- description: 'Prettify your JSON string to a human friendly readable format.',
+ description: translate('tools.json-prettify.description'),
keywords: ['json', 'viewer', 'prettify', 'format'],
component: () => import('./json-viewer.vue'),
icon: Braces,
diff --git a/src/tools/jwt-parser/index.ts b/src/tools/jwt-parser/index.ts
index 7249ace0..939b4b34 100644
--- a/src/tools/jwt-parser/index.ts
+++ b/src/tools/jwt-parser/index.ts
@@ -1,10 +1,11 @@
import { Key } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'JWT parser',
+ name: translate('tools.jwt-parser.title'),
path: '/jwt-parser',
- description: 'Parse and decode your JSON Web Token (jwt) and display its content.',
+ description: translate('tools.jwt-parser.description'),
keywords: [
'jwt',
'parser',
diff --git a/src/tools/jwt-parser/jwt-parser.service.ts b/src/tools/jwt-parser/jwt-parser.service.ts
index cc39145a..543f4c8b 100644
--- a/src/tools/jwt-parser/jwt-parser.service.ts
+++ b/src/tools/jwt-parser/jwt-parser.service.ts
@@ -19,7 +19,7 @@ function decodeJwt({ jwt }: { jwt: string }) {
function parseClaims({ claim, value }: { claim: string; value: unknown }) {
const claimDescription = CLAIM_DESCRIPTIONS[claim];
- const formattedValue = _.isPlainObject(value) ? JSON.stringify(value, null, 3) : _.toString(value);
+ const formattedValue = _.isPlainObject(value) || _.isArray(value) ? JSON.stringify(value, null, 3) : _.toString(value);
const friendlyValue = getFriendlyValue({ claim, value });
return {
diff --git a/src/tools/jwt-parser/jwt-parser.vue b/src/tools/jwt-parser/jwt-parser.vue
index 6b30fc0c..a26064d7 100644
--- a/src/tools/jwt-parser/jwt-parser.vue
+++ b/src/tools/jwt-parser/jwt-parser.vue
@@ -39,7 +39,7 @@ const validation = useValidation({
{{ section.title }}
+
diff --git a/src/tools/percentage-calculator/index.ts b/src/tools/percentage-calculator/index.ts
index 736f5706..33c5b2f1 100644
--- a/src/tools/percentage-calculator/index.ts
+++ b/src/tools/percentage-calculator/index.ts
@@ -1,10 +1,11 @@
import { Percentage } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Percentage calculator',
+ name: translate('tools.percentage-calculator.title'),
path: '/percentage-calculator',
- description: 'Easily calculate percentages from a value to another value, or from a percentage to a value.',
+ description: translate('tools.percentage-calculator.description'),
keywords: ['percentage', 'calculator', 'calculate', 'value', 'number', '%'],
component: () => import('./percentage-calculator.vue'),
icon: Percentage,
diff --git a/src/tools/phone-parser-and-formatter/index.ts b/src/tools/phone-parser-and-formatter/index.ts
index 5b19ae61..094b21e8 100644
--- a/src/tools/phone-parser-and-formatter/index.ts
+++ b/src/tools/phone-parser-and-formatter/index.ts
@@ -1,11 +1,11 @@
import { Phone } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Phone parser and formatter',
+ name: translate('tools.phone-parser-and-formatter.title'),
path: '/phone-parser-and-formatter',
- description:
- 'Parse, validate and format phone numbers. Get information about the phone number, like the country code, type, etc.',
+ description: translate('tools.phone-parser-and-formatter.description'),
keywords: [
'phone',
'parser',
diff --git a/src/tools/qr-code-generator/index.ts b/src/tools/qr-code-generator/index.ts
index 4c2f86bb..b97b4cbc 100644
--- a/src/tools/qr-code-generator/index.ts
+++ b/src/tools/qr-code-generator/index.ts
@@ -1,11 +1,11 @@
import { Qrcode } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'QR Code generator',
+ name: translate('tools.qrcode-generator.title'),
path: '/qrcode-generator',
- description:
- 'Generate and download QR-code for an url or just a text and customize the background and foreground colors.',
+ description: translate('tools.qrcode-generator.description'),
keywords: ['qr', 'code', 'generator', 'square', 'color', 'link', 'low', 'medium', 'quartile', 'high', 'transparent'],
component: () => import('./qr-code-generator.vue'),
icon: Qrcode,
diff --git a/src/tools/random-port-generator/index.ts b/src/tools/random-port-generator/index.ts
index febdc2a4..e300b8f0 100644
--- a/src/tools/random-port-generator/index.ts
+++ b/src/tools/random-port-generator/index.ts
@@ -1,10 +1,11 @@
import { Server } from '@vicons/tabler';
import { defineTool } from '../tool';
+import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
- name: 'Random port generator',
+ name: translate('tools.random-port-generator.title'),
path: '/random-port-generator',
- description: 'Generate random port numbers outside of the range of "known" ports (0-1023).',
+ description: translate('tools.random-port-generator.description'),
keywords: ['system', 'port', 'lan', 'generator', 'random', 'development', 'computer'],
component: () => import('./random-port-generator.vue'),
icon: Server,
diff --git a/src/tools/regex-memo/index.ts b/src/tools/regex-memo/index.ts
new file mode 100644
index 00000000..f1f56489
--- /dev/null
+++ b/src/tools/regex-memo/index.ts
@@ -0,0 +1,12 @@
+import { BrandJavascript } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'Regex cheatsheet',
+ path: '/regex-memo',
+ description: 'Javascript Regex/Regular Expression cheatsheet',
+ keywords: ['regex', 'regular', 'expression', 'javascript', 'memo', 'cheatsheet'],
+ component: () => import('./regex-memo.vue'),
+ icon: BrandJavascript,
+ createdAt: new Date('2024-09-20'),
+});
diff --git a/src/tools/regex-memo/regex-memo.content.md b/src/tools/regex-memo/regex-memo.content.md
new file mode 100644
index 00000000..0f779401
--- /dev/null
+++ b/src/tools/regex-memo/regex-memo.content.md
@@ -0,0 +1,121 @@
+### Normal characters
+
+Expression | Description
+:--|:--
+`.` or `[^\n\r]` | any character *excluding* a newline or carriage return
+`[A-Za-z]` | alphabet
+`[a-z]` | lowercase alphabet
+`[A-Z]` | uppercase alphabet
+`\d` or `[0-9]` | digit
+`\D` or `[^0-9]` | non-digit
+`_` | underscore
+`\w` or `[A-Za-z0-9_]` | alphabet, digit or underscore
+`\W` or `[^A-Za-z0-9_]` | inverse of `\w`
+`\S` | inverse of `\s`
+
+### Whitespace characters
+
+Expression | Description
+:--|:--
+` ` | space
+`\t` | tab
+`\n` | newline
+`\r` | carriage return
+`\s` | space, tab, newline or carriage return
+
+### Character set
+
+Expression | Description
+:--|:--
+`[xyz]` | either `x`, `y` or `z`
+`[^xyz]` | neither `x`, `y` nor `z`
+`[1-3]` | either `1`, `2` or `3`
+`[^1-3]` | neither `1`, `2` nor `3`
+
+- Think of a character set as an `OR` operation on the single characters that are enclosed between the square brackets.
+- Use `^` after the opening `[` to “negate” the character set.
+- Within a character set, `.` means a literal period.
+
+### Characters that require escaping
+
+#### Outside a character set
+
+Expression | Description
+:--|:--
+`\.` | period
+`\^` | caret
+`\$` | dollar sign
+`\|` | pipe
+`\\` | back slash
+`\/` | forward slash
+`\(` | opening bracket
+`\)` | closing bracket
+`\[` | opening square bracket
+`\]` | closing square bracket
+`\{` | opening curly bracket
+`\}` | closing curly bracket
+
+#### Inside a character set
+
+Expression | Description
+:--|:--
+`\\` | back slash
+`\]` | closing square bracket
+
+- A `^` must be escaped only if it occurs immediately after the opening `[` of the character set.
+- A `-` must be escaped only if it occurs between two alphabets or two digits.
+
+### Quantifiers
+
+Expression | Description
+:--|:--
+`{2}` | exactly 2
+`{2,}` | at least 2
+`{2,7}` | at least 2 but no more than 7
+`*` | 0 or more
+`+` | 1 or more
+`?` | exactly 0 or 1
+
+- The quantifier goes *after* the expression to be quantified.
+
+### Boundaries
+
+Expression | Description
+:--|:--
+`^` | start of string
+`$` | end of string
+`\b` | word boundary
+
+- How word boundary matching works:
+ - At the beginning of the string if the first character is `\w`.
+ - Between two adjacent characters within the string, if the first character is `\w` and the second character is `\W`.
+ - At the end of the string if the last character is `\w`.
+
+### Matching
+
+Expression | Description
+:--|:--
+`foo\|bar` | match either `foo` or `bar`
+`foo(?=bar)` | match `foo` if it’s before `bar`
+`foo(?!bar)` | match `foo` if it’s *not* before `bar`
+`(?<=bar)foo` | match `foo` if it’s after `bar`
+`(?
+import { useThemeVars } from 'naive-ui';
+import Memo from './regex-memo.content.md';
+
+const themeVars = useThemeVars();
+
+
+
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
+ Molestias, quisquam vitae saepe dolores quas debitis ab r
+ ecusandae suscipit ex dignissimos minus quam repellat sunt.
+ Molestiae culpa blanditiis totam sapiente dignissimos.
+