mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-07 14:57:12 -04:00
Merge d20c027957
into 07eea0f484
This commit is contained in:
commit
0d85581ef3
26 changed files with 368 additions and 102 deletions
130
locales/de.yml
130
locales/de.yml
|
@ -1,16 +1,9 @@
|
||||||
'404':
|
|
||||||
notFound: 404 Nicht gefunden
|
|
||||||
sorry: Entschuldigung, diese Seite scheint nicht zu existieren
|
|
||||||
maybe: >-
|
|
||||||
Vielleicht macht der Cache etwas Seltsames. Mit einem erzwungenen Neuladen
|
|
||||||
versuchen?
|
|
||||||
backHome: Zurück zur Startseite
|
|
||||||
home:
|
home:
|
||||||
categories:
|
categories:
|
||||||
newestTools: Neueste Tools
|
newestTools: Neueste Tools
|
||||||
favoriteTools: Deine Lieblingstools
|
favoriteTools: Deine Lieblingstools
|
||||||
allTools: Alle Tools
|
allTools: Alle Tools
|
||||||
favoritesDndToolTip: 'Ziehen und Ablegen, um Favoriten neu zu ordnen'
|
favoritesDndToolTip: Drag and Drop, um Favoriten neu zu ordnen
|
||||||
subtitle: Praktische Tools für Entwickler
|
subtitle: Praktische Tools für Entwickler
|
||||||
toggleMenu: Menü umschalten
|
toggleMenu: Menü umschalten
|
||||||
home: Startseite
|
home: Startseite
|
||||||
|
@ -72,6 +65,13 @@ about:
|
||||||
funktioniert, melde bitte einen Fehler im
|
funktioniert, melde bitte einen Fehler im
|
||||||
[Issues-Bereich](https://github.com/CorentinTh/it-tools/issues/new/choose)
|
[Issues-Bereich](https://github.com/CorentinTh/it-tools/issues/new/choose)
|
||||||
im GitHub-Repository.
|
im GitHub-Repository.
|
||||||
|
404:
|
||||||
|
notFound: 404 Nicht gefunden
|
||||||
|
sorry: Entschuldigung, diese Seite scheint nicht zu existieren
|
||||||
|
maybe: >-
|
||||||
|
Vielleicht macht der Cache etwas Seltsames. Mit einem erzwungenen Neuladen
|
||||||
|
versuchen?
|
||||||
|
backHome: Zurück zur Startseite
|
||||||
favoriteButton:
|
favoriteButton:
|
||||||
remove: Aus Favoriten entfernen
|
remove: Aus Favoriten entfernen
|
||||||
add: Zu Favoriten hinzufügen
|
add: Zu Favoriten hinzufügen
|
||||||
|
@ -79,6 +79,20 @@ toolCard:
|
||||||
new: Neu
|
new: Neu
|
||||||
search:
|
search:
|
||||||
label: Suche
|
label: Suche
|
||||||
|
placeholder: Tippe, um ein Tool oder einen Befehl zu suchen...
|
||||||
|
textareaCopyable:
|
||||||
|
copy: In die Zwischenablage kopieren
|
||||||
|
copied: Kopiert!
|
||||||
|
spanCopyable:
|
||||||
|
copy: In die Zwischenablage kopieren
|
||||||
|
copied: Kopiert!
|
||||||
|
inputCopyable:
|
||||||
|
copy: In die Zwischenablage kopieren
|
||||||
|
copied: Kopiert!
|
||||||
|
formatTransformer:
|
||||||
|
input: Eingabe
|
||||||
|
input-placeholder: Eingabe...
|
||||||
|
output: Ausgabe
|
||||||
tools:
|
tools:
|
||||||
categories:
|
categories:
|
||||||
favorite-tools: Deine Lieblingstools
|
favorite-tools: Deine Lieblingstools
|
||||||
|
@ -102,6 +116,10 @@ tools:
|
||||||
description: >-
|
description: >-
|
||||||
Überwache die Dauer einer Sache. Im Grunde ein Chronometer mit einfachen
|
Überwache die Dauer einer Sache. Im Grunde ein Chronometer mit einfachen
|
||||||
Chronometerfunktionen.
|
Chronometerfunktionen.
|
||||||
|
button:
|
||||||
|
start: Start
|
||||||
|
stop: Stopp
|
||||||
|
reset: Zurücksetzen
|
||||||
token-generator:
|
token-generator:
|
||||||
title: Token-Generator
|
title: Token-Generator
|
||||||
description: >-
|
description: >-
|
||||||
|
@ -296,6 +314,13 @@ tools:
|
||||||
description: >-
|
description: >-
|
||||||
Generiere und downloade QR-Codes für eine URL oder einfach einen Text und
|
Generiere und downloade QR-Codes für eine URL oder einfach einen Text und
|
||||||
passe die Hintergrund- und Vordergrundfarben an.
|
passe die Hintergrund- und Vordergrundfarben an.
|
||||||
|
text: 'Text:'
|
||||||
|
placeholder: Dein Link oder Text...
|
||||||
|
foreground-color: 'Vordergrundfarbe:'
|
||||||
|
background-color: 'Hintergrundfarbe:'
|
||||||
|
error-resistance: 'Fehlerresistenz:'
|
||||||
|
button:
|
||||||
|
download: QR-Code herunterladen
|
||||||
wifi-qrcode-generator:
|
wifi-qrcode-generator:
|
||||||
title: WLAN-QR-Code-Generator
|
title: WLAN-QR-Code-Generator
|
||||||
description: >-
|
description: >-
|
||||||
|
@ -420,6 +445,11 @@ tools:
|
||||||
description: >-
|
description: >-
|
||||||
Informationen zu einem Text erhalten, wie die Anzahl der Zeichen, die
|
Informationen zu einem Text erhalten, wie die Anzahl der Zeichen, die
|
||||||
Anzahl der Wörter, die Größe usw.
|
Anzahl der Wörter, die Größe usw.
|
||||||
|
characters: Anzahl Zeichen
|
||||||
|
words: Anzahl Wörter
|
||||||
|
lines: Anzahl Zeilen
|
||||||
|
bytes: Bytegröße
|
||||||
|
placeholder: Dein Text...
|
||||||
text-to-nato-alphabet:
|
text-to-nato-alphabet:
|
||||||
title: Text zu NATO-Alphabet
|
title: Text zu NATO-Alphabet
|
||||||
description: >-
|
description: >-
|
||||||
|
@ -430,6 +460,13 @@ tools:
|
||||||
description: >-
|
description: >-
|
||||||
Generiere einen Base64-Basic-Auth-Header aus einem Benutzernamen und einem
|
Generiere einen Base64-Basic-Auth-Header aus einem Benutzernamen und einem
|
||||||
Passwort.
|
Passwort.
|
||||||
|
button:
|
||||||
|
copy: Header kopieren
|
||||||
|
copied: Header in die Zwischenablage kopiert
|
||||||
|
password: Passwort
|
||||||
|
username: Benutzername
|
||||||
|
yourpassword: Dein Passwort...
|
||||||
|
yourusername: Dein Benutzername...
|
||||||
text-to-unicode:
|
text-to-unicode:
|
||||||
title: Text zu Unicode
|
title: Text zu Unicode
|
||||||
description: Parse und konvertiere Text in Unicode und umgekehrt.
|
description: Parse und konvertiere Text in Unicode und umgekehrt.
|
||||||
|
@ -454,3 +491,80 @@ tools:
|
||||||
text-to-binary:
|
text-to-binary:
|
||||||
title: Text zu ASCII-Binär
|
title: Text zu ASCII-Binär
|
||||||
description: Konvertiere Text in seine ASCII-Binärrepräsentation und umgekehrt.
|
description: Konvertiere Text in seine ASCII-Binärrepräsentation und umgekehrt.
|
||||||
|
safelink-decoder:
|
||||||
|
title: Outlook Safelink-Decoder
|
||||||
|
description: Outlook Safelinks decodieren
|
||||||
|
input: 'Eingabe einer Outlook Safelink-URL:'
|
||||||
|
input-placeholder: Deine eingegebene Outlook Safelink-URL...
|
||||||
|
output: 'Ausgabe der decodierten URL:'
|
||||||
|
ascii-text-drawer:
|
||||||
|
title: ASCII-Art-Text-Generator
|
||||||
|
description: ASCII-Art-Text mit vielen Schriftarten und Stilen erstellen.
|
||||||
|
text: 'Dein Text:'
|
||||||
|
placeholder: Dein zu zeichnender Text
|
||||||
|
font: 'Schriftart:'
|
||||||
|
width: 'Breite:'
|
||||||
|
loading: Schriftart wird geladen...
|
||||||
|
error: Die aktuellen Einstellungen führten zu einem Fehler.
|
||||||
|
output: 'ASCII-Art-Text:'
|
||||||
|
json-to-xml:
|
||||||
|
title: JSON zu XML
|
||||||
|
description: JSON in XML konvertieren
|
||||||
|
input: Dein JSON-Inhalt
|
||||||
|
input-placeholder: Füge hier deinen JSON-Inhalt ein...
|
||||||
|
output: Konvertiertes XML
|
||||||
|
error: Bereitgestelltes JSON ist ungültig.
|
||||||
|
xml-to-json:
|
||||||
|
title: XML zu JSON
|
||||||
|
description: XML in JSON konvertieren
|
||||||
|
input: Dein XML-Inhalt
|
||||||
|
input-placeholder: Füge hier deinen XML-Inhalt ein...
|
||||||
|
output: Konvertiertes JSON
|
||||||
|
error: Bereitgestelltes XML ist ungültig.
|
||||||
|
email-normalizer:
|
||||||
|
title: E-Mail-Normalisierung
|
||||||
|
description: >-
|
||||||
|
Vereinheitlichen von E-Mail-Adressen auf ein Standardformat für einen
|
||||||
|
einfacheren Vergleich. Nützlich für Deduplizierung und Datenbereinigung.
|
||||||
|
input: 'Unbearbeitete E-Mails zur Normalisierung:'
|
||||||
|
input-placeholder: Gib hier deine E-Mails ein (eine pro Zeile)...
|
||||||
|
output: 'Normalisierte E-Mails:'
|
||||||
|
output-placeholder: Hier werden normalisierte E-Mails angezeigt...
|
||||||
|
button:
|
||||||
|
clear: E-Mails leeren
|
||||||
|
copy: Kopiere normalisierte E-Mails
|
||||||
|
copied: Normalisierte E-Mails in die Zwischenablage kopiert
|
||||||
|
markdown-to-html:
|
||||||
|
title: Markdown zu HTML
|
||||||
|
description: Markdown in HTML konvertieren und (als PDF) ausdrucken
|
||||||
|
markdown: 'Dein zu konvertierender Markdown-Inhalt:'
|
||||||
|
markdownInput: Dein Markdown-Inhalt...
|
||||||
|
html: 'HTML-Ausgabe:'
|
||||||
|
button:
|
||||||
|
print: Als PDF drucken
|
||||||
|
regex-memo:
|
||||||
|
title: Regex-Spickzettel
|
||||||
|
description: Spickzettel für Javascript Regex/Regulärer Ausdruck
|
||||||
|
regex-tester:
|
||||||
|
title: Regex-Tester
|
||||||
|
description: Teste deine regulären Ausdrücke mit Beispieltext.
|
||||||
|
regex: Regex
|
||||||
|
regex-input: 'Regex zum Testen:'
|
||||||
|
regex-input-placeholder: Eingabe des zu testenden regulären Ausdrucks
|
||||||
|
link: Siehe Spickzettel für reguläre Ausdrücke
|
||||||
|
text-input: 'Zu prüfender Text:'
|
||||||
|
text-input-placeholder: Eingabe des zu prüfenden Texts
|
||||||
|
matches: Treffer
|
||||||
|
text-index: Index im Text
|
||||||
|
value: Wert
|
||||||
|
captures: Erfassungen
|
||||||
|
groups: Gruppen
|
||||||
|
sample: Beispiel für passenden Text
|
||||||
|
diagram: Regex-Diagramm
|
||||||
|
global: Globale Suche.
|
||||||
|
ignoreCase: Suche ohne Berücksichtigung der Groß-/Kleinschreibung.
|
||||||
|
multiline: Ermöglicht die Übereinstimmung von ^ und $ neben Zeilenumbruchzeichen.
|
||||||
|
dotAll: Lässt . als Treffer für Zeilenumbruchzeichen zu.
|
||||||
|
unicode: Unicode; behandelt ein Muster als eine Folge von Unicode-Codepunkten.
|
||||||
|
unicodeSets: Ein Upgrade zum u-Modus mit mehr Unicode-Funktionen.
|
||||||
|
no-match: Kein Treffer
|
||||||
|
|
124
locales/en.yml
124
locales/en.yml
|
@ -57,6 +57,20 @@ toolCard:
|
||||||
new: New
|
new: New
|
||||||
search:
|
search:
|
||||||
label: Search
|
label: Search
|
||||||
|
placeholder: Type to search a tool or a command...
|
||||||
|
textareaCopyable:
|
||||||
|
copy: Copy to clipboard
|
||||||
|
copied: Copied!
|
||||||
|
spanCopyable:
|
||||||
|
copy: Copy to clipboard
|
||||||
|
copied: Copied!
|
||||||
|
inputCopyable:
|
||||||
|
copy: Copy to clipboard
|
||||||
|
copied: Copied!
|
||||||
|
formatTransformer:
|
||||||
|
input: Input
|
||||||
|
input-placeholder: Input...
|
||||||
|
output: Output
|
||||||
tools:
|
tools:
|
||||||
categories:
|
categories:
|
||||||
favorite-tools: 'Your favorite tools'
|
favorite-tools: 'Your favorite tools'
|
||||||
|
@ -78,7 +92,11 @@ tools:
|
||||||
chronometer:
|
chronometer:
|
||||||
title: Chronometer
|
title: Chronometer
|
||||||
description: Monitor the duration of a thing. Basically a chronometer with simple chronometer features.
|
description: Monitor the duration of a thing. Basically a chronometer with simple chronometer features.
|
||||||
|
button:
|
||||||
|
start: Start
|
||||||
|
stop: Stop
|
||||||
|
reset: Reset
|
||||||
|
|
||||||
token-generator:
|
token-generator:
|
||||||
title: Token generator
|
title: Token generator
|
||||||
description: Generate random string with the chars you want, uppercase or lowercase letters, numbers and/or symbols.
|
description: Generate random string with the chars you want, uppercase or lowercase letters, numbers and/or symbols.
|
||||||
|
@ -252,6 +270,13 @@ tools:
|
||||||
qrcode-generator:
|
qrcode-generator:
|
||||||
title: QR Code generator
|
title: QR Code generator
|
||||||
description: Generate and download a QR code for a URL (or just plain text), and customize the background and foreground colors.
|
description: Generate and download a QR code for a URL (or just plain text), and customize the background and foreground colors.
|
||||||
|
error-resistance: 'Error resistance:'
|
||||||
|
background-color: 'Background color:'
|
||||||
|
foreground-color: 'Foreground color:'
|
||||||
|
text: 'Text:'
|
||||||
|
placeholder: Your link or text...
|
||||||
|
button:
|
||||||
|
download: Download QR code
|
||||||
|
|
||||||
wifi-qrcode-generator:
|
wifi-qrcode-generator:
|
||||||
title: WiFi QR Code generator
|
title: WiFi QR Code generator
|
||||||
|
@ -360,6 +385,11 @@ tools:
|
||||||
text-statistics:
|
text-statistics:
|
||||||
title: Text statistics
|
title: Text statistics
|
||||||
description: Get information about a text, the number of characters, the number of words, its size in bytes, ...
|
description: Get information about a text, the number of characters, the number of words, its size in bytes, ...
|
||||||
|
characters: Character count
|
||||||
|
words: Word count
|
||||||
|
lines: Line count
|
||||||
|
bytes: Byte size
|
||||||
|
placeholder: Your text...
|
||||||
|
|
||||||
text-to-nato-alphabet:
|
text-to-nato-alphabet:
|
||||||
title: Text to NATO alphabet
|
title: Text to NATO alphabet
|
||||||
|
@ -368,6 +398,13 @@ tools:
|
||||||
basic-auth-generator:
|
basic-auth-generator:
|
||||||
title: Basic auth generator
|
title: Basic auth generator
|
||||||
description: Generate a base64 basic auth header from a username and password.
|
description: Generate a base64 basic auth header from a username and password.
|
||||||
|
button:
|
||||||
|
copy: Copy header
|
||||||
|
username: Username
|
||||||
|
yourusername: Your username...
|
||||||
|
password: Password
|
||||||
|
yourpassword: Your password...
|
||||||
|
copied: Header copied to the clipboard
|
||||||
|
|
||||||
text-to-unicode:
|
text-to-unicode:
|
||||||
title: Text to Unicode
|
title: Text to Unicode
|
||||||
|
@ -392,3 +429,88 @@ tools:
|
||||||
text-to-binary:
|
text-to-binary:
|
||||||
title: Text to ASCII binary
|
title: Text to ASCII binary
|
||||||
description: Convert text to its ASCII binary representation and vice-versa.
|
description: Convert text to its ASCII binary representation and vice-versa.
|
||||||
|
|
||||||
|
safelink-decoder:
|
||||||
|
title: Outlook Safelink decoder
|
||||||
|
description: Decode Outlook SafeLink links
|
||||||
|
input: 'Your input Outlook SafeLink Url:'
|
||||||
|
input-placeholder: Your input Outlook SafeLink Url...
|
||||||
|
output: 'Output decoded URL:'
|
||||||
|
|
||||||
|
ascii-text-drawer:
|
||||||
|
title: ASCII Art Text Generator
|
||||||
|
description: Create ASCII art text with many fonts and styles.
|
||||||
|
text: 'Your text:'
|
||||||
|
placeholder: Your text to draw
|
||||||
|
output: 'Ascii Art text:'
|
||||||
|
font: 'Font:'
|
||||||
|
width: 'Width:'
|
||||||
|
loading: Loading font...
|
||||||
|
error: Current settings resulted in error.
|
||||||
|
|
||||||
|
json-to-xml:
|
||||||
|
title: JSON to XML
|
||||||
|
description: Convert JSON to XML
|
||||||
|
input: Your JSON content
|
||||||
|
input-placeholder: Paste your JSON content here...
|
||||||
|
output: Converted XML
|
||||||
|
error: Provided JSON is not valid.
|
||||||
|
|
||||||
|
xml-to-json:
|
||||||
|
title: XML to JSON
|
||||||
|
description: Convert XML to JSON
|
||||||
|
input: Your XML content
|
||||||
|
input-placeholder: Paste your XML content here...
|
||||||
|
output: Converted JSON
|
||||||
|
error: Provided XML is not valid.
|
||||||
|
|
||||||
|
email-normalizer:
|
||||||
|
title: Email normalizer
|
||||||
|
description: >-
|
||||||
|
Normalize email addresses to a standard format for easier comparison.
|
||||||
|
Useful for deduplication and data cleaning.
|
||||||
|
input: 'Raw emails to normalize:'
|
||||||
|
output: 'Normalized emails:'
|
||||||
|
input-placeholder: Put your emails here (one per line)...
|
||||||
|
output-placeholder: Normalized emails will appear here...
|
||||||
|
button:
|
||||||
|
clear: Clear emails
|
||||||
|
copy: Copy normalized emails
|
||||||
|
copied: Normalized emails copied to the clipboard
|
||||||
|
|
||||||
|
markdown-to-html:
|
||||||
|
title: Markdown to HTML
|
||||||
|
description: Convert Markdown to HTML and allow to print (as PDF)
|
||||||
|
markdown: 'Your Markdown to convert:'
|
||||||
|
markdownInput: Your Markdown content...
|
||||||
|
html: 'Output HTML:'
|
||||||
|
button:
|
||||||
|
print: Print as PDF
|
||||||
|
|
||||||
|
regex-memo:
|
||||||
|
title: Regex cheatsheet
|
||||||
|
description: Javascript Regex/Regular Expression cheatsheet
|
||||||
|
|
||||||
|
regex-tester:
|
||||||
|
title: Regex Tester
|
||||||
|
description: Test your regular expressions with sample text.
|
||||||
|
regex-input: 'Regex to test:'
|
||||||
|
regex-input-placeholder: Put the regex to test
|
||||||
|
link: See Regular Expression Cheatsheet
|
||||||
|
text-input: 'Text to match:'
|
||||||
|
text-input-placeholder: Put the text to match
|
||||||
|
matches: Matches
|
||||||
|
text-index: Index in text
|
||||||
|
value: Value
|
||||||
|
captures: Captures
|
||||||
|
groups: Groups
|
||||||
|
sample: Sample matching text
|
||||||
|
diagram: Regex Diagram
|
||||||
|
global: Global search
|
||||||
|
ignoreCase: Case-insensitive search
|
||||||
|
multiline: Allows ^ and $ to match next to newline characters.
|
||||||
|
dotAll: Allows . to match newline characters.
|
||||||
|
unicode: Unicode; treat a pattern as a sequence of Unicode code points.
|
||||||
|
unicodeSets: An upgrade to the u mode with more Unicode features.
|
||||||
|
regex: Regex
|
||||||
|
no-match: No match
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import type { UseValidationRule } from '@/composable/validation';
|
import type { UseValidationRule } from '@/composable/validation';
|
||||||
import CInputText from '@/ui/c-input-text/c-input-text.vue';
|
import CInputText from '@/ui/c-input-text/c-input-text.vue';
|
||||||
|
import { translate as t } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
@ -16,10 +17,10 @@ const props = withDefaults(
|
||||||
{
|
{
|
||||||
transformer: _.identity,
|
transformer: _.identity,
|
||||||
inputValidationRules: () => [],
|
inputValidationRules: () => [],
|
||||||
inputLabel: 'Input',
|
inputLabel: t('formatTransformer.input'),
|
||||||
inputDefault: '',
|
inputDefault: '',
|
||||||
inputPlaceholder: 'Input...',
|
inputPlaceholder: t('formatTransformer.input-placeholder'),
|
||||||
outputLabel: 'Output',
|
outputLabel: t('formatTransformer.output'),
|
||||||
outputLanguage: '',
|
outputLanguage: '',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
import { useCopy } from '@/composable/copy';
|
import { useCopy } from '@/composable/copy';
|
||||||
|
import { translate as t } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
const props = defineProps<{ value: string }>();
|
const props = defineProps<{ value: string }>();
|
||||||
const emit = defineEmits(['update:value']);
|
const emit = defineEmits(['update:value']);
|
||||||
|
|
||||||
const value = useVModel(props, 'value', emit);
|
const value = useVModel(props, 'value', emit);
|
||||||
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
|
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
|
||||||
const tooltipText = computed(() => isJustCopied.value ? 'Copied!' : 'Copy to clipboard');
|
const tooltipText = computed(() => isJustCopied.value ? t('inputCopyable.copied') : t('inputCopyable.copy'));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useCopy } from '@/composable/copy';
|
import { useCopy } from '@/composable/copy';
|
||||||
|
import { translate as t } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{ value?: string }>(), { value: '' });
|
const props = withDefaults(defineProps<{ value?: string }>(), { value: '' });
|
||||||
const { value } = toRefs(props);
|
const { value } = toRefs(props);
|
||||||
|
|
||||||
const initialText = 'Copy to clipboard';
|
const initialText = t('spanCopyable.copy');
|
||||||
|
|
||||||
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
|
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
|
||||||
const tooltipText = computed(() => isJustCopied.value ? 'Copied!' : initialText);
|
const tooltipText = computed(() => isJustCopied.value ? t('spanCopyable.copied') : initialText);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -9,6 +9,7 @@ import yamlHljs from 'highlight.js/lib/languages/yaml';
|
||||||
import iniHljs from 'highlight.js/lib/languages/ini';
|
import iniHljs from 'highlight.js/lib/languages/ini';
|
||||||
import markdownHljs from 'highlight.js/lib/languages/markdown';
|
import markdownHljs from 'highlight.js/lib/languages/markdown';
|
||||||
import { useCopy } from '@/composable/copy';
|
import { useCopy } from '@/composable/copy';
|
||||||
|
import { translate as t } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
@ -22,7 +23,7 @@ const props = withDefaults(
|
||||||
followHeightOf: null,
|
followHeightOf: null,
|
||||||
language: 'txt',
|
language: 'txt',
|
||||||
copyPlacement: 'top-right',
|
copyPlacement: 'top-right',
|
||||||
copyMessage: 'Copy to clipboard',
|
copyMessage: t('textareaCopyable.copy'),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
hljs.registerLanguage('sql', sqlHljs);
|
hljs.registerLanguage('sql', sqlHljs);
|
||||||
|
@ -37,7 +38,7 @@ const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(p
|
||||||
const { height } = followHeightOf.value ? useElementSize(followHeightOf) : { height: ref(null) };
|
const { height } = followHeightOf.value ? useElementSize(followHeightOf) : { height: ref(null) };
|
||||||
|
|
||||||
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
|
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
|
||||||
const tooltipText = computed(() => isJustCopied.value ? 'Copied!' : copyMessage.value);
|
const tooltipText = computed(() => isJustCopied.value ? t('textareaCopyable.copied') : copyMessage.value);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -125,7 +125,7 @@ function activateOption(option: PaletteOption) {
|
||||||
</c-button>
|
</c-button>
|
||||||
|
|
||||||
<c-modal v-model:open="isModalOpen" class="palette-modal" shadow-xl important:max-w-650px important:pa-12px @keydown="handleKeydown">
|
<c-modal v-model:open="isModalOpen" class="palette-modal" shadow-xl important:max-w-650px important:pa-12px @keydown="handleKeydown">
|
||||||
<c-input-text ref="inputRef" v-model:value="searchPrompt" raw-text placeholder="Type to search a tool or a command..." autofocus clearable />
|
<c-input-text ref="inputRef" v-model:value="searchPrompt" raw-text :placeholder="$t('search.placeholder')" autofocus clearable />
|
||||||
|
|
||||||
<div v-for="(options, category) in filteredSearchResult" :key="category">
|
<div v-for="(options, category) in filteredSearchResult" :key="category">
|
||||||
<div ml-3 mt-3 text-sm font-bold text-primary op-60>
|
<div ml-3 mt-3 text-sm font-bold text-primary op-60>
|
||||||
|
|
|
@ -8,6 +8,7 @@ const width = useStorage('ascii-text-drawer:width', 80);
|
||||||
const output = ref('');
|
const output = ref('');
|
||||||
const errored = ref(false);
|
const errored = ref(false);
|
||||||
const processing = ref(false);
|
const processing = ref(false);
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
figlet.defaults({ fontPath: '//unpkg.com/figlet@1.6.0/fonts/' });
|
figlet.defaults({ fontPath: '//unpkg.com/figlet@1.6.0/fonts/' });
|
||||||
|
|
||||||
|
@ -44,8 +45,8 @@ const fonts = ['1Row', '3-D', '3D Diagonal', '3D-ASCII', '3x5', '4Max', '5 Line
|
||||||
<c-card style="max-width: 600px;">
|
<c-card style="max-width: 600px;">
|
||||||
<c-input-text
|
<c-input-text
|
||||||
v-model:value="input"
|
v-model:value="input"
|
||||||
label="Your text:"
|
:label="t('tools.ascii-text-drawer.text')"
|
||||||
placeholder="Your text to draw"
|
:placeholder="t('tools.ascii-text-drawer.placeholder')"
|
||||||
raw-text
|
raw-text
|
||||||
multiline
|
multiline
|
||||||
rows="4"
|
rows="4"
|
||||||
|
@ -58,14 +59,14 @@ const fonts = ['1Row', '3-D', '3D Diagonal', '3D-ASCII', '3x5', '4Max', '5 Line
|
||||||
<c-select
|
<c-select
|
||||||
v-model:value="font"
|
v-model:value="font"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
label="Font:"
|
:label="t('tools.ascii-text-drawer.font')"
|
||||||
:options="fonts"
|
:options="fonts"
|
||||||
searchable="true"
|
searchable="true"
|
||||||
placeholder="Select font to use"
|
placeholder="Select font to use"
|
||||||
/>
|
/>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
<n-gi span="2">
|
<n-gi span="2">
|
||||||
<n-form-item label="Width:" label-placement="top" label-width="100" :show-feedback="false">
|
<n-form-item :label="t('tools.ascii-text-drawer.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-input-number v-model:value="width" min="0" max="10000" w-full placeholder="Width of the text" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
|
@ -75,14 +76,14 @@ const fonts = ['1Row', '3-D', '3D Diagonal', '3D-ASCII', '3x5', '4Max', '5 Line
|
||||||
|
|
||||||
<div v-if="processing" flex items-center justify-center>
|
<div v-if="processing" flex items-center justify-center>
|
||||||
<n-spin size="medium" />
|
<n-spin size="medium" />
|
||||||
<span class="ml-2">Loading font...</span>
|
<span class="ml-2">{{ t('tools.ascii-text-drawer.loading') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<c-alert v-if="errored" mt-1 text-center type="error">
|
<c-alert v-if="errored" mt-1 text-center type="error">
|
||||||
Current settings resulted in error.
|
{{ t('tools.ascii-text-drawer.error') }}
|
||||||
</c-alert>
|
</c-alert>
|
||||||
|
|
||||||
<n-form-item v-if="!processing && !errored" label="Ascii Art text:">
|
<n-form-item v-if="!processing && !errored" :label="t('tools.ascii-text-drawer.output')">
|
||||||
<TextareaCopyable
|
<TextareaCopyable
|
||||||
:value="output"
|
:value="output"
|
||||||
mb-1 mt-1
|
mb-1 mt-1
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Artboard } from '@vicons/tabler';
|
import { Artboard } from '@vicons/tabler';
|
||||||
import { defineTool } from '../tool';
|
import { defineTool } from '../tool';
|
||||||
|
import { translate } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
export const tool = defineTool({
|
export const tool = defineTool({
|
||||||
name: 'ASCII Art Text Generator',
|
name: translate('tools.ascii-text-drawer.title'),
|
||||||
path: '/ascii-text-drawer',
|
path: '/ascii-text-drawer',
|
||||||
description: 'Create ASCII art text with many fonts and styles.',
|
description: translate('tools.ascii-text-drawer.description'),
|
||||||
keywords: ['ascii', 'asciiart', 'text', 'drawer'],
|
keywords: ['ascii', 'asciiart', 'text', 'drawer'],
|
||||||
component: () => import('./ascii-text-drawer.vue'),
|
component: () => import('./ascii-text-drawer.vue'),
|
||||||
icon: Artboard,
|
icon: Artboard,
|
||||||
|
|
|
@ -5,17 +5,25 @@ import { textToBase64 } from '@/utils/base64';
|
||||||
const username = ref('');
|
const username = ref('');
|
||||||
const password = ref('');
|
const password = ref('');
|
||||||
const header = computed(() => `Authorization: Basic ${textToBase64(`${username.value}:${password.value}`)}`);
|
const header = computed(() => `Authorization: Basic ${textToBase64(`${username.value}:${password.value}`)}`);
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const { copy } = useCopy({ source: header, text: 'Header copied to the clipboard' });
|
const { copy } = useCopy({ source: header, text: t('tools.basic-auth-generator.copied') });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<c-input-text v-model:value="username" label="Username" placeholder="Your username..." clearable raw-text mb-5 />
|
<c-input-text
|
||||||
|
v-model:value="username"
|
||||||
|
:label="t('tools.basic-auth-generator.username')"
|
||||||
|
:placeholder="t('tools.basic-auth-generator.yourusername')"
|
||||||
|
clearable
|
||||||
|
raw-text
|
||||||
|
mb-5
|
||||||
|
/>
|
||||||
<c-input-text
|
<c-input-text
|
||||||
v-model:value="password"
|
v-model:value="password"
|
||||||
label="Password"
|
:label="t('tools.basic-auth-generator.password')"
|
||||||
placeholder="Your password..."
|
:placeholder="t('tools.basic-auth-generator.yourpassword')"
|
||||||
clearable
|
clearable
|
||||||
raw-text
|
raw-text
|
||||||
mb-2
|
mb-2
|
||||||
|
@ -31,7 +39,7 @@ const { copy } = useCopy({ source: header, text: 'Header copied to the clipboard
|
||||||
</c-card>
|
</c-card>
|
||||||
<div mt-5 flex justify-center>
|
<div mt-5 flex justify-center>
|
||||||
<c-button @click="copy()">
|
<c-button @click="copy()">
|
||||||
Copy header
|
{{ t('tools.basic-auth-generator.button.copy') }}
|
||||||
</c-button>
|
</c-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { formatMs } from './chronometer.service';
|
||||||
|
|
||||||
const isRunning = ref(false);
|
const isRunning = ref(false);
|
||||||
const counter = ref(0);
|
const counter = ref(0);
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
let previousRafDate = Date.now();
|
let previousRafDate = Date.now();
|
||||||
const { pause: pauseRaf, resume: resumeRaf } = useRafFn(
|
const { pause: pauseRaf, resume: resumeRaf } = useRafFn(
|
||||||
|
@ -37,14 +38,14 @@ function pause() {
|
||||||
</c-card>
|
</c-card>
|
||||||
<div mt-5 flex justify-center gap-3>
|
<div mt-5 flex justify-center gap-3>
|
||||||
<c-button v-if="!isRunning" type="primary" @click="resume">
|
<c-button v-if="!isRunning" type="primary" @click="resume">
|
||||||
Start
|
{{ t('tools.chronometer.button.start') }}
|
||||||
</c-button>
|
</c-button>
|
||||||
<c-button v-else type="warning" @click="pause">
|
<c-button v-else type="warning" @click="pause">
|
||||||
Stop
|
{{ t('tools.chronometer.button.stop') }}
|
||||||
</c-button>
|
</c-button>
|
||||||
|
|
||||||
<c-button @click="counter = 0">
|
<c-button @click="counter = 0">
|
||||||
Reset
|
{{ t('tools.chronometer.button.reset') }}
|
||||||
</c-button>
|
</c-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { normalizeEmail } from 'email-normalizer';
|
||||||
import { withDefaultOnError } from '@/utils/defaults';
|
import { withDefaultOnError } from '@/utils/defaults';
|
||||||
import { useCopy } from '@/composable/copy';
|
import { useCopy } from '@/composable/copy';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
const emails = ref('');
|
const emails = ref('');
|
||||||
const normalizedEmails = computed(() => {
|
const normalizedEmails = computed(() => {
|
||||||
if (!emails.value) {
|
if (!emails.value) {
|
||||||
|
@ -17,17 +18,17 @@ const normalizedEmails = computed(() => {
|
||||||
.join('\n');
|
.join('\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
const { copy } = useCopy({ source: normalizedEmails, text: 'Normalized emails copied to the clipboard', createToast: true });
|
const { copy } = useCopy({ source: normalizedEmails, text: t('tools.email-normalizer.copied'), createToast: true });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
Raw emails to normalize:
|
{{ t('tools.email-normalizer.input') }}
|
||||||
</div>
|
</div>
|
||||||
<c-input-text
|
<c-input-text
|
||||||
v-model:value="emails"
|
v-model:value="emails"
|
||||||
placeholder="Put your emails here (one per line)..."
|
:placeholder="t('tools.email-normalizer.input-placeholder')"
|
||||||
rows="3"
|
rows="3"
|
||||||
multiline
|
multiline
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
|
@ -39,11 +40,11 @@ const { copy } = useCopy({ source: normalizedEmails, text: 'Normalized emails co
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="mb-2 mt-4">
|
<div class="mb-2 mt-4">
|
||||||
Normalized emails:
|
{{ t('tools.email-normalizer.output') }}
|
||||||
</div>
|
</div>
|
||||||
<c-input-text
|
<c-input-text
|
||||||
:value="normalizedEmails"
|
:value="normalizedEmails"
|
||||||
placeholder="Normalized emails will appear here..."
|
:placeholder="t('tools.email-normalizer.output-placeholder')"
|
||||||
rows="3"
|
rows="3"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
autocorrect="off"
|
autocorrect="off"
|
||||||
|
@ -55,10 +56,10 @@ const { copy } = useCopy({ source: normalizedEmails, text: 'Normalized emails co
|
||||||
/>
|
/>
|
||||||
<div class="mt-4 flex justify-center gap-2">
|
<div class="mt-4 flex justify-center gap-2">
|
||||||
<c-button @click="emails = ''">
|
<c-button @click="emails = ''">
|
||||||
Clear emails
|
{{ t('tools.email-normalizer.button.clear') }}
|
||||||
</c-button>
|
</c-button>
|
||||||
<c-button :disabled="!normalizedEmails" @click="copy()">
|
<c-button :disabled="!normalizedEmails" @click="copy()">
|
||||||
Copy normalized emails
|
{{ t('tools.email-normalizer.button.copy') }}
|
||||||
</c-button>
|
</c-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Mail } from '@vicons/tabler';
|
import { Mail } from '@vicons/tabler';
|
||||||
import { defineTool } from '../tool';
|
import { defineTool } from '../tool';
|
||||||
|
import { translate } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
export const tool = defineTool({
|
export const tool = defineTool({
|
||||||
name: 'Email normalizer',
|
name: translate('tools.email-normalizer.title'),
|
||||||
path: '/email-normalizer',
|
path: '/email-normalizer',
|
||||||
description: 'Normalize email addresses to a standard format for easier comparison. Useful for deduplication and data cleaning.',
|
description: translate('tools.email-normalizer.description'),
|
||||||
keywords: ['email', 'normalizer'],
|
keywords: ['email', 'normalizer'],
|
||||||
component: () => import('./email-normalizer.vue'),
|
component: () => import('./email-normalizer.vue'),
|
||||||
icon: Mail,
|
icon: Mail,
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Braces } from '@vicons/tabler';
|
import { Braces } from '@vicons/tabler';
|
||||||
import { defineTool } from '../tool';
|
import { defineTool } from '../tool';
|
||||||
|
import { translate } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
export const tool = defineTool({
|
export const tool = defineTool({
|
||||||
name: 'JSON to XML',
|
name: translate('tools.json-to-xml.title'),
|
||||||
path: '/json-to-xml',
|
path: '/json-to-xml',
|
||||||
description: 'Convert JSON to XML',
|
description: translate('tools.json-to-xml.description'),
|
||||||
keywords: ['json', 'xml'],
|
keywords: ['json', 'xml'],
|
||||||
component: () => import('./json-to-xml.vue'),
|
component: () => import('./json-to-xml.vue'),
|
||||||
icon: Braces,
|
icon: Braces,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import JSON5 from 'json5';
|
||||||
import { withDefaultOnError } from '@/utils/defaults';
|
import { withDefaultOnError } from '@/utils/defaults';
|
||||||
import type { UseValidationRule } from '@/composable/validation';
|
import type { UseValidationRule } from '@/composable/validation';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
const defaultValue = '{"a":{"_attributes":{"x":"1.234","y":"It\'s"}}}';
|
const defaultValue = '{"a":{"_attributes":{"x":"1.234","y":"It\'s"}}}';
|
||||||
function transformer(value: string) {
|
function transformer(value: string) {
|
||||||
return withDefaultOnError(() => {
|
return withDefaultOnError(() => {
|
||||||
|
@ -14,17 +15,17 @@ function transformer(value: string) {
|
||||||
const rules: UseValidationRule<string>[] = [
|
const rules: UseValidationRule<string>[] = [
|
||||||
{
|
{
|
||||||
validator: (v: string) => v === '' || JSON5.parse(v),
|
validator: (v: string) => v === '' || JSON5.parse(v),
|
||||||
message: 'Provided JSON is not valid.',
|
message: t('tools.json-to-xml.error'),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<format-transformer
|
<format-transformer
|
||||||
input-label="Your JSON content"
|
:input-label="t('tools.json-to-xml.input')"
|
||||||
:input-default="defaultValue"
|
:input-default="defaultValue"
|
||||||
input-placeholder="Paste your JSON content here..."
|
:input-placeholder="t('tools.json-to-xml.input-placeholder')"
|
||||||
output-label="Converted XML"
|
:output-label="t('tools.json-to-xml.output')"
|
||||||
output-language="xml"
|
output-language="xml"
|
||||||
:transformer="transformer"
|
:transformer="transformer"
|
||||||
:input-validation-rules="rules"
|
:input-validation-rules="rules"
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Markdown } from '@vicons/tabler';
|
import { Markdown } from '@vicons/tabler';
|
||||||
import { defineTool } from '../tool';
|
import { defineTool } from '../tool';
|
||||||
|
import { translate } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
export const tool = defineTool({
|
export const tool = defineTool({
|
||||||
name: 'Markdown to HTML',
|
name: translate('tools.markdown-to-html.title'),
|
||||||
path: '/markdown-to-html',
|
path: '/markdown-to-html',
|
||||||
description: 'Convert Markdown to Html and allow to print (as PDF)',
|
description: translate('tools.markdown-to-html.description'),
|
||||||
keywords: ['markdown', 'html', 'converter', 'pdf'],
|
keywords: ['markdown', 'html', 'converter', 'pdf'],
|
||||||
component: () => import('./markdown-to-html.vue'),
|
component: () => import('./markdown-to-html.vue'),
|
||||||
icon: Markdown,
|
icon: Markdown,
|
||||||
|
|
|
@ -7,6 +7,7 @@ const outputHtml = computed(() => {
|
||||||
const md = markdownit();
|
const md = markdownit();
|
||||||
return md.render(inputMarkdown.value);
|
return md.render(inputMarkdown.value);
|
||||||
});
|
});
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
function printHtml() {
|
function printHtml() {
|
||||||
const w = window.open();
|
const w = window.open();
|
||||||
|
@ -23,21 +24,21 @@ function printHtml() {
|
||||||
<c-input-text
|
<c-input-text
|
||||||
v-model:value="inputMarkdown"
|
v-model:value="inputMarkdown"
|
||||||
multiline raw-text
|
multiline raw-text
|
||||||
placeholder="Your Markdown content..."
|
:placeholder="t('tools.markdown-to-html.markdownInput')"
|
||||||
rows="8"
|
rows="8"
|
||||||
autofocus
|
autofocus
|
||||||
label="Your Markdown to convert:"
|
:label="t('tools.markdown-to-html.markdown')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<n-divider />
|
<n-divider />
|
||||||
|
|
||||||
<n-form-item label="Output HTML:">
|
<n-form-item :label="t('tools.markdown-to-html.html')">
|
||||||
<TextareaCopyable :value="outputHtml" :word-wrap="true" language="html" />
|
<TextareaCopyable :value="outputHtml" :word-wrap="true" language="html" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
|
||||||
<div flex justify-center>
|
<div flex justify-center>
|
||||||
<n-button @click="printHtml">
|
<n-button @click="printHtml">
|
||||||
Print as PDF
|
{{ t('tools.markdown-to-html.button.print') }}
|
||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import type { QRCodeErrorCorrectionLevel } from 'qrcode';
|
||||||
import { useQRCode } from './useQRCode';
|
import { useQRCode } from './useQRCode';
|
||||||
import { useDownloadFileFromBase64 } from '@/composable/downloadBase64';
|
import { useDownloadFileFromBase64 } from '@/composable/downloadBase64';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
const foreground = ref('#000000ff');
|
const foreground = ref('#000000ff');
|
||||||
const background = ref('#ffffffff');
|
const background = ref('#ffffffff');
|
||||||
const errorCorrectionLevel = ref<QRCodeErrorCorrectionLevel>('medium');
|
const errorCorrectionLevel = ref<QRCodeErrorCorrectionLevel>('medium');
|
||||||
|
@ -32,23 +33,23 @@ const { download } = useDownloadFileFromBase64({ source: qrcode, filename: 'qr-c
|
||||||
label-position="left"
|
label-position="left"
|
||||||
label-width="130px"
|
label-width="130px"
|
||||||
label-align="right"
|
label-align="right"
|
||||||
label="Text:"
|
:label="t('tools.qrcode-generator.text')"
|
||||||
multiline
|
multiline
|
||||||
rows="1"
|
rows="1"
|
||||||
autosize
|
autosize
|
||||||
placeholder="Your link or text..."
|
:placeholder="t('tools.qrcode-generator.placeholder')"
|
||||||
mb-6
|
mb-6
|
||||||
/>
|
/>
|
||||||
<n-form label-width="130" label-placement="left">
|
<n-form label-width="130" label-placement="left">
|
||||||
<n-form-item label="Foreground color:">
|
<n-form-item :label="t('tools.qrcode-generator.foreground-color')">
|
||||||
<n-color-picker v-model:value="foreground" :modes="['hex']" />
|
<n-color-picker v-model:value="foreground" :modes="['hex']" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="Background color:">
|
<n-form-item :label="t('tools.qrcode-generator.background-color')">
|
||||||
<n-color-picker v-model:value="background" :modes="['hex']" />
|
<n-color-picker v-model:value="background" :modes="['hex']" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<c-select
|
<c-select
|
||||||
v-model:value="errorCorrectionLevel"
|
v-model:value="errorCorrectionLevel"
|
||||||
label="Error resistance:"
|
:label="t('tools.qrcode-generator.error-resistance')"
|
||||||
label-position="left"
|
label-position="left"
|
||||||
label-width="130px"
|
label-width="130px"
|
||||||
label-align="right"
|
label-align="right"
|
||||||
|
@ -60,7 +61,7 @@ const { download } = useDownloadFileFromBase64({ source: qrcode, filename: 'qr-c
|
||||||
<div flex flex-col items-center gap-3>
|
<div flex flex-col items-center gap-3>
|
||||||
<n-image :src="qrcode" width="200" />
|
<n-image :src="qrcode" width="200" />
|
||||||
<c-button @click="download">
|
<c-button @click="download">
|
||||||
Download qr-code
|
{{ t('tools.qrcode-generator.button.download') }}
|
||||||
</c-button>
|
</c-button>
|
||||||
</div>
|
</div>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { BrandJavascript } from '@vicons/tabler';
|
import { BrandJavascript } from '@vicons/tabler';
|
||||||
import { defineTool } from '../tool';
|
import { defineTool } from '../tool';
|
||||||
|
import { translate } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
export const tool = defineTool({
|
export const tool = defineTool({
|
||||||
name: 'Regex cheatsheet',
|
name: translate('tools.regex-memo.title'),
|
||||||
path: '/regex-memo',
|
path: '/regex-memo',
|
||||||
description: 'Javascript Regex/Regular Expression cheatsheet',
|
description: translate('tools.regex-memo.description'),
|
||||||
keywords: ['regex', 'regular', 'expression', 'javascript', 'memo', 'cheatsheet'],
|
keywords: ['regex', 'regular', 'expression', 'javascript', 'memo', 'cheatsheet'],
|
||||||
component: () => import('./regex-memo.vue'),
|
component: () => import('./regex-memo.vue'),
|
||||||
icon: BrandJavascript,
|
icon: BrandJavascript,
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Language } from '@vicons/tabler';
|
import { Language } from '@vicons/tabler';
|
||||||
import { defineTool } from '../tool';
|
import { defineTool } from '../tool';
|
||||||
|
import { translate } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
export const tool = defineTool({
|
export const tool = defineTool({
|
||||||
name: 'Regex Tester',
|
name: translate('tools.regex-tester.title'),
|
||||||
path: '/regex-tester',
|
path: '/regex-tester',
|
||||||
description: 'Test your regular expressions with sample text.',
|
description: translate('tools.regex-tester.description'),
|
||||||
keywords: ['regex', 'tester', 'sample', 'expression'],
|
keywords: ['regex', 'tester', 'sample', 'expression'],
|
||||||
component: () => import('./regex-tester.vue'),
|
component: () => import('./regex-tester.vue'),
|
||||||
icon: Language,
|
icon: Language,
|
||||||
|
|
|
@ -15,6 +15,7 @@ const dotAll = ref(true);
|
||||||
const unicode = ref(true);
|
const unicode = ref(true);
|
||||||
const unicodeSets = ref(false);
|
const unicodeSets = ref(false);
|
||||||
const visualizerSVG = ref<ShadowRootExpose>();
|
const visualizerSVG = ref<ShadowRootExpose>();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const regexValidation = useValidation({
|
const regexValidation = useValidation({
|
||||||
source: regex,
|
source: regex,
|
||||||
|
@ -92,36 +93,36 @@ watchEffect(
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div max-w-600px>
|
<div max-w-600px>
|
||||||
<c-card title="Regex" mb-1>
|
<c-card :title="t('tools.regex-tester.regex')" mb-1>
|
||||||
<c-input-text
|
<c-input-text
|
||||||
v-model:value="regex"
|
v-model:value="regex"
|
||||||
label="Regex to test:"
|
:label="t('tools.regex-tester.regex-input')"
|
||||||
placeholder="Put the regex to test"
|
:placeholder="t('tools.regex-tester.regex-input-placeholder')"
|
||||||
multiline
|
multiline
|
||||||
rows="3"
|
rows="3"
|
||||||
:validation="regexValidation"
|
:validation="regexValidation"
|
||||||
/>
|
/>
|
||||||
<router-link target="_blank" to="/regex-memo" mb-1 mt-1>
|
<router-link target="_blank" to="/regex-memo" mb-1 mt-1>
|
||||||
See Regular Expression Cheatsheet
|
{{ t('tools.regex-tester.link') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
<n-space>
|
<n-space>
|
||||||
<n-checkbox v-model:checked="global">
|
<n-checkbox v-model:checked="global">
|
||||||
<span title="Global search">Global search. (<code>g</code>)</span>
|
<span :title="t('tools.regex-tester.global')">Global search (<code>g</code>)</span>
|
||||||
</n-checkbox>
|
</n-checkbox>
|
||||||
<n-checkbox v-model:checked="ignoreCase">
|
<n-checkbox v-model:checked="ignoreCase">
|
||||||
<span title="Case-insensitive search">Case-insensitive search. (<code>i</code>)</span>
|
<span :title="t('tools.regex-tester.ignoreCase')">Case-insensitive search (<code>i</code>)</span>
|
||||||
</n-checkbox>
|
</n-checkbox>
|
||||||
<n-checkbox v-model:checked="multiline">
|
<n-checkbox v-model:checked="multiline">
|
||||||
<span title="Allows ^ and $ to match next to newline characters.">Multiline(<code>m</code>)</span>
|
<span :title="t('tools.regex-tester.multiline')">Multiline (<code>m</code>)</span>
|
||||||
</n-checkbox>
|
</n-checkbox>
|
||||||
<n-checkbox v-model:checked="dotAll">
|
<n-checkbox v-model:checked="dotAll">
|
||||||
<span title="Allows . to match newline characters.">Singleline(<code>s</code>)</span>
|
<span :title="t('tools.regex-tester.dotAll')">Singleline (<code>s</code>)</span>
|
||||||
</n-checkbox>
|
</n-checkbox>
|
||||||
<n-checkbox v-model:checked="unicode">
|
<n-checkbox v-model:checked="unicode">
|
||||||
<span title="Unicode; treat a pattern as a sequence of Unicode code points.">Unicode(<code>u</code>)</span>
|
<span :title="t('tools.regex-tester.unicode')">Unicode (<code>u</code>)</span>
|
||||||
</n-checkbox>
|
</n-checkbox>
|
||||||
<n-checkbox v-model:checked="unicodeSets">
|
<n-checkbox v-model:checked="unicodeSets">
|
||||||
<span title="An upgrade to the u mode with more Unicode features.">Unicode Sets (<code>v</code>)</span>
|
<span :title="t('tools.regex-tester.unicodeSets')">Unicode Sets (<code>v</code>)</span>
|
||||||
</n-checkbox>
|
</n-checkbox>
|
||||||
</n-space>
|
</n-space>
|
||||||
|
|
||||||
|
@ -129,28 +130,28 @@ watchEffect(
|
||||||
|
|
||||||
<c-input-text
|
<c-input-text
|
||||||
v-model:value="text"
|
v-model:value="text"
|
||||||
label="Text to match:"
|
:label="t('tools.regex-tester.text-input')"
|
||||||
placeholder="Put the text to match"
|
:placeholder="t('tools.regex-tester.text-input-placeholder')"
|
||||||
multiline
|
multiline
|
||||||
rows="5"
|
rows="5"
|
||||||
/>
|
/>
|
||||||
</c-card>
|
</c-card>
|
||||||
|
|
||||||
<c-card title="Matches" mb-1 mt-3>
|
<c-card :title="t('tools.regex-tester.matches')" mb-1 mt-3>
|
||||||
<n-table v-if="results?.length > 0">
|
<n-table v-if="results?.length > 0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
Index in text
|
{{ t('tools.regex-tester.text-index') }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
Value
|
{{ t('tools.regex-tester.value') }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
Captures
|
{{ t('tools.regex-tester.captures') }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
Groups
|
{{ t('tools.regex-tester.groups') }}
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -176,15 +177,15 @@ watchEffect(
|
||||||
</tbody>
|
</tbody>
|
||||||
</n-table>
|
</n-table>
|
||||||
<c-alert v-else>
|
<c-alert v-else>
|
||||||
No match
|
{{ t('tools.regex-tester.no-match') }}
|
||||||
</c-alert>
|
</c-alert>
|
||||||
</c-card>
|
</c-card>
|
||||||
|
|
||||||
<c-card title="Sample matching text" mt-3>
|
<c-card :title="t('tools.regex-tester.sample')" mt-3>
|
||||||
<pre style="white-space: pre-wrap; word-break: break-all;">{{ sample }}</pre>
|
<pre style="white-space: pre-wrap; word-break: break-all;">{{ sample }}</pre>
|
||||||
</c-card>
|
</c-card>
|
||||||
|
|
||||||
<c-card title="Regex Diagram" style="overflow-x: scroll;" mt-3>
|
<c-card :title="t('tools.regex-tester.diagram')" style="overflow-x: scroll;" mt-3>
|
||||||
<shadow-root ref="visualizerSVG">
|
<shadow-root ref="visualizerSVG">
|
||||||
 
|
 
|
||||||
</shadow-root>
|
</shadow-root>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Mailbox } from '@vicons/tabler';
|
import { Mailbox } from '@vicons/tabler';
|
||||||
import { defineTool } from '../tool';
|
import { defineTool } from '../tool';
|
||||||
|
import { translate } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
export const tool = defineTool({
|
export const tool = defineTool({
|
||||||
name: 'Outlook Safelink decoder',
|
name: translate('tools.safelink-decoder.title'),
|
||||||
path: '/safelink-decoder',
|
path: '/safelink-decoder',
|
||||||
description: 'Decode Outlook SafeLink links',
|
description: translate('tools.safelink-decoder.description'),
|
||||||
keywords: ['outlook', 'safelink', 'decoder'],
|
keywords: ['outlook', 'safelink', 'decoder'],
|
||||||
component: () => import('./safelink-decoder.vue'),
|
component: () => import('./safelink-decoder.vue'),
|
||||||
icon: Mailbox,
|
icon: Mailbox,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { decodeSafeLinksURL } from './safelink-decoder.service';
|
import { decodeSafeLinksURL } from './safelink-decoder.service';
|
||||||
import TextareaCopyable from '@/components/TextareaCopyable.vue';
|
import TextareaCopyable from '@/components/TextareaCopyable.vue';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
const inputSafeLinkUrl = ref('');
|
const inputSafeLinkUrl = ref('');
|
||||||
const outputDecodedUrl = computed(() => {
|
const outputDecodedUrl = computed(() => {
|
||||||
try {
|
try {
|
||||||
|
@ -18,14 +19,14 @@ const outputDecodedUrl = computed(() => {
|
||||||
<c-input-text
|
<c-input-text
|
||||||
v-model:value="inputSafeLinkUrl"
|
v-model:value="inputSafeLinkUrl"
|
||||||
raw-text
|
raw-text
|
||||||
placeholder="Your input Outlook SafeLink Url..."
|
:placeholder="t('tools.safelink-decoder.input-placeholder')"
|
||||||
autofocus
|
autofocus
|
||||||
label="Your input Outlook SafeLink Url:"
|
:label="t('tools.safelink-decoder.input')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<n-divider />
|
<n-divider />
|
||||||
|
|
||||||
<n-form-item label="Output decoded URL:">
|
<n-form-item :label="t('tools.safelink-decoder.output')">
|
||||||
<TextareaCopyable :value="outputDecodedUrl" :word-wrap="true" />
|
<TextareaCopyable :value="outputDecodedUrl" :word-wrap="true" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,17 +3,18 @@ import { getStringSizeInBytes } from './text-statistics.service';
|
||||||
import { formatBytes } from '@/utils/convert';
|
import { formatBytes } from '@/utils/convert';
|
||||||
|
|
||||||
const text = ref('');
|
const text = ref('');
|
||||||
|
const { t } = useI18n();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<c-card>
|
<c-card>
|
||||||
<c-input-text v-model:value="text" multiline placeholder="Your text..." rows="5" />
|
<c-input-text v-model:value="text" multiline :placeholder="t('tools.text-statistics.placeholder')" rows="5" />
|
||||||
|
|
||||||
<div mt-5 flex>
|
<div mt-5 flex>
|
||||||
<n-statistic label="Character count" :value="text.length" flex-1 />
|
<n-statistic :label="t('tools.text-statistics.characters')" :value="text.length" flex-1 />
|
||||||
<n-statistic label="Word count" :value="text === '' ? 0 : text.split(/\s+/).length" flex-1 />
|
<n-statistic :label="t('tools.text-statistics.words')" :value="text === '' ? 0 : text.split(/\s+/).length" flex-1 />
|
||||||
<n-statistic label="Line count" :value="text === '' ? 0 : text.split(/\r\n|\r|\n/).length" flex-1 />
|
<n-statistic :label="t('tools.text-statistics.lines')" :value="text === '' ? 0 : text.split(/\r\n|\r|\n/).length" flex-1 />
|
||||||
<n-statistic label="Byte size" :value="formatBytes(getStringSizeInBytes(text))" flex-1 />
|
<n-statistic :label="t('tools.text-statistics.bytes')" :value="formatBytes(getStringSizeInBytes(text))" flex-1 />
|
||||||
</div>
|
</div>
|
||||||
</c-card>
|
</c-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Braces } from '@vicons/tabler';
|
import { Braces } from '@vicons/tabler';
|
||||||
import { defineTool } from '../tool';
|
import { defineTool } from '../tool';
|
||||||
|
import { translate } from '@/plugins/i18n.plugin';
|
||||||
|
|
||||||
export const tool = defineTool({
|
export const tool = defineTool({
|
||||||
name: 'XML to JSON',
|
name: translate('tools.xml-to-json.title'),
|
||||||
path: '/xml-to-json',
|
path: '/xml-to-json',
|
||||||
description: 'Convert XML to JSON',
|
description: translate('tools.xml-to-json.description'),
|
||||||
keywords: ['xml', 'json'],
|
keywords: ['xml', 'json'],
|
||||||
component: () => import('./xml-to-json.vue'),
|
component: () => import('./xml-to-json.vue'),
|
||||||
icon: Braces,
|
icon: Braces,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { isValidXML } from '../xml-formatter/xml-formatter.service';
|
||||||
import { withDefaultOnError } from '@/utils/defaults';
|
import { withDefaultOnError } from '@/utils/defaults';
|
||||||
import type { UseValidationRule } from '@/composable/validation';
|
import type { UseValidationRule } from '@/composable/validation';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
const defaultValue = '<a x="1.234" y="It\'s"/>';
|
const defaultValue = '<a x="1.234" y="It\'s"/>';
|
||||||
function transformer(value: string) {
|
function transformer(value: string) {
|
||||||
return withDefaultOnError(() => {
|
return withDefaultOnError(() => {
|
||||||
|
@ -14,17 +15,17 @@ function transformer(value: string) {
|
||||||
const rules: UseValidationRule<string>[] = [
|
const rules: UseValidationRule<string>[] = [
|
||||||
{
|
{
|
||||||
validator: isValidXML,
|
validator: isValidXML,
|
||||||
message: 'Provided XML is not valid.',
|
message: t('tools.xml-to-json.error'),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<format-transformer
|
<format-transformer
|
||||||
input-label="Your XML content"
|
:input-label="t('tools.xml-to-json.input')"
|
||||||
:input-default="defaultValue"
|
:input-default="defaultValue"
|
||||||
input-placeholder="Paste your XML content here..."
|
:input-placeholder="t('tools.xml-to-json.input-placeholder')"
|
||||||
output-label="Converted JSON"
|
:output-label="t('tools.xml-to-json.output')"
|
||||||
output-language="json"
|
output-language="json"
|
||||||
:transformer="transformer"
|
:transformer="transformer"
|
||||||
:input-validation-rules="rules"
|
:input-validation-rules="rules"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue