diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json index 4084d922c4..789adf0eb6 100644 --- a/.eslintrc-auto-import.json +++ b/.eslintrc-auto-import.json @@ -286,6 +286,20 @@ "watchTriggerable": true, "watchWithFilter": true, "whenever": true, - "toValue": true + "toValue": true, + "DirectiveBinding": true, + "ExtractDefaultPropTypes": true, + "ExtractPropTypes": true, + "ExtractPublicPropTypes": true, + "MaybeRef": true, + "MaybeRefOrGetter": true, + "WritableComputedRef": true, + "injectLocal": true, + "onWatcherCleanup": true, + "provideLocal": true, + "useClipboardItems": true, + "useId": true, + "useModel": true, + "useTemplateRef": true } } diff --git a/.gitignore b/.gitignore index a3bbd94386..4590f7c582 100644 --- a/.gitignore +++ b/.gitignore @@ -28,8 +28,19 @@ coverage *.sw? .env +.env.* /test-results/ /playwright-report/ /playwright/.cache/ # Webkit with playwright creates a salt file -salt \ No newline at end of file +salt + +# Cloudflare / Wrangler +.wrangler/ +wrangler.toml + +# Claude Code +.claude/ + +# Lock files (choose one to keep; delete this line if you want to commit yours) +package-lock.json diff --git a/.playwright-mcp/page-2026-06-12T07-21-42-619Z.yml b/.playwright-mcp/page-2026-06-12T07-21-42-619Z.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.playwright-mcp/page-2026-06-12T07-24-10-708Z.yml b/.playwright-mcp/page-2026-06-12T07-24-10-708Z.yml new file mode 100644 index 0000000000..64a53325c5 --- /dev/null +++ b/.playwright-mcp/page-2026-06-12T07-24-10-708Z.yml @@ -0,0 +1,574 @@ +- generic [ref=e5]: + - complementary [ref=e6]: + - link "IT - TOOLS Handy tools for developers" [ref=e7] [cursor=pointer]: + - /url: / + - img [ref=e8] + - generic [ref=e13]: + - generic [ref=e14]: IT - TOOLS + - generic [ref=e16]: Handy tools for developers + - generic [ref=e17]: + - generic [ref=e18]: + - generic [ref=e19] [cursor=pointer]: + - img [ref=e21] + - generic [ref=e23]: Crypto + - menu [ref=e27]: + - menuitem "Token generator" [ref=e28]: + - img [ref=e30] [cursor=pointer]: + - img [ref=e31] + - link "Token generator" [ref=e37] [cursor=pointer]: + - /url: /token-generator + - menuitem "Hash text" [ref=e38]: + - img [ref=e40] [cursor=pointer]: + - img [ref=e41] + - link "Hash text" [ref=e46] [cursor=pointer]: + - /url: /hash-text + - menuitem "Bcrypt" [ref=e47]: + - img [ref=e49] [cursor=pointer]: + - img [ref=e50] + - link "Bcrypt" [ref=e55] [cursor=pointer]: + - /url: /bcrypt + - menuitem "UUIDs generator" [ref=e56]: + - img [ref=e58] [cursor=pointer]: + - img [ref=e59] + - link "UUIDs generator" [ref=e66] [cursor=pointer]: + - /url: /uuid-generator + - menuitem "ULID generator" [ref=e67]: + - img [ref=e69] [cursor=pointer]: + - img [ref=e70] + - link "ULID generator" [ref=e76] [cursor=pointer]: + - /url: /ulid-generator + - menuitem "Encrypt / decrypt text" [ref=e77]: + - img [ref=e79] [cursor=pointer]: + - img [ref=e80] + - link "Encrypt / decrypt text" [ref=e85] [cursor=pointer]: + - /url: /encryption + - menuitem "BIP39 passphrase generator" [ref=e86]: + - img [ref=e88] [cursor=pointer]: + - img [ref=e89] + - link "BIP39 passphrase generator" [ref=e91] [cursor=pointer]: + - /url: /bip39-generator + - menuitem "Hmac generator" [ref=e92]: + - img [ref=e94] [cursor=pointer]: + - img [ref=e95] + - link "Hmac generator" [ref=e97] [cursor=pointer]: + - /url: /hmac-generator + - menuitem "RSA key pair generator" [ref=e98]: + - img [ref=e100] [cursor=pointer]: + - img [ref=e101] + - link "RSA key pair generator" [ref=e106] [cursor=pointer]: + - /url: /rsa-key-pair-generator + - menuitem "Password strength analyser" [ref=e107]: + - img [ref=e109] [cursor=pointer]: + - img [ref=e110] + - link "Password strength analyser" [ref=e112] [cursor=pointer]: + - /url: /password-strength-analyser + - menuitem "PDF signature checker" [ref=e113]: + - img [ref=e115] [cursor=pointer]: + - img [ref=e116] + - link "PDF signature checker" [ref=e118] [cursor=pointer]: + - /url: /pdf-signature-checker + - menuitem "SSL Certificate Parser" [ref=e119]: + - img [ref=e121] [cursor=pointer]: + - img [ref=e122] + - link "SSL Certificate Parser" [ref=e129] [cursor=pointer]: + - /url: /ssl-certificate-parser + - generic [ref=e130]: + - generic [ref=e131] [cursor=pointer]: + - img [ref=e133] + - generic [ref=e135]: Converter + - menu [ref=e139]: + - menuitem "Date-time converter" [ref=e140]: + - img [ref=e142] [cursor=pointer]: + - img [ref=e143] + - link "Date-time converter" [ref=e146] [cursor=pointer]: + - /url: /date-converter + - menuitem "Integer base converter" [ref=e147]: + - img [ref=e149] [cursor=pointer]: + - img [ref=e150] + - link "Integer base converter" [ref=e154] [cursor=pointer]: + - /url: /base-converter + - menuitem "Roman numeral converter" [ref=e155]: + - img [ref=e157] [cursor=pointer]: + - img [ref=e158] + - link "Roman numeral converter" [ref=e162] [cursor=pointer]: + - /url: /roman-numeral-converter + - menuitem "Base64 string encoder/decoder" [ref=e163]: + - img [ref=e165] [cursor=pointer]: + - img [ref=e166] + - link "Base64 string encoder/decoder" [ref=e171] [cursor=pointer]: + - /url: /base64-string-converter + - menuitem "Base64 file converter" [ref=e172]: + - img [ref=e174] [cursor=pointer]: + - img [ref=e175] + - link "Base64 file converter" [ref=e180] [cursor=pointer]: + - /url: /base64-file-converter + - menuitem "Color converter" [ref=e181]: + - img [ref=e183] [cursor=pointer]: + - img [ref=e184] + - link "Color converter" [ref=e190] [cursor=pointer]: + - /url: /color-converter + - menuitem "Case converter" [ref=e191]: + - img [ref=e193] [cursor=pointer]: + - img [ref=e194] + - link "Case converter" [ref=e198] [cursor=pointer]: + - /url: /case-converter + - menuitem "Text to NATO alphabet" [ref=e199]: + - img [ref=e201] [cursor=pointer]: + - img [ref=e202] + - link "Text to NATO alphabet" [ref=e207] [cursor=pointer]: + - /url: /text-to-nato-alphabet + - menuitem "Text to ASCII binary" [ref=e208]: + - img [ref=e210] [cursor=pointer]: + - img [ref=e211] + - link "Text to ASCII binary" [ref=e217] [cursor=pointer]: + - /url: /text-to-binary + - menuitem "Text to Unicode" [ref=e218]: + - img [ref=e220] [cursor=pointer]: + - img [ref=e221] + - link "Text to Unicode" [ref=e224] [cursor=pointer]: + - /url: /text-to-unicode + - menuitem "YAML to JSON converter" [ref=e225]: + - img [ref=e227] [cursor=pointer]: + - img [ref=e228] + - link "YAML to JSON converter" [ref=e230] [cursor=pointer]: + - /url: /yaml-to-json-converter + - menuitem "YAML to TOML" [ref=e231]: + - img [ref=e233] [cursor=pointer]: + - img [ref=e234] + - link "YAML to TOML" [ref=e236] [cursor=pointer]: + - /url: /yaml-to-toml + - menuitem "JSON to YAML converter" [ref=e237]: + - img [ref=e239] [cursor=pointer]: + - img [ref=e240] + - link "JSON to YAML converter" [ref=e244] [cursor=pointer]: + - /url: /json-to-yaml-converter + - menuitem "JSON to TOML" [ref=e245]: + - img [ref=e247] [cursor=pointer]: + - img [ref=e248] + - link "JSON to TOML" [ref=e252] [cursor=pointer]: + - /url: /json-to-toml + - menuitem "List converter" [ref=e253]: + - img [ref=e255] [cursor=pointer]: + - img [ref=e256] + - link "List converter" [ref=e258] [cursor=pointer]: + - /url: /list-converter + - menuitem "TOML to JSON" [ref=e259]: + - img [ref=e261] [cursor=pointer]: + - img [ref=e262] + - link "TOML to JSON" [ref=e264] [cursor=pointer]: + - /url: /toml-to-json + - menuitem "TOML to YAML" [ref=e265]: + - img [ref=e267] [cursor=pointer]: + - img [ref=e268] + - link "TOML to YAML" [ref=e270] [cursor=pointer]: + - /url: /toml-to-yaml + - menuitem "XML to JSON" [ref=e271]: + - img [ref=e273] [cursor=pointer]: + - img [ref=e274] + - link "XML to JSON" [ref=e278] [cursor=pointer]: + - /url: /xml-to-json + - menuitem "JSON to XML" [ref=e279]: + - img [ref=e281] [cursor=pointer]: + - img [ref=e282] + - link "JSON to XML" [ref=e286] [cursor=pointer]: + - /url: /json-to-xml + - menuitem "Markdown to HTML" [ref=e287]: + - img [ref=e289] [cursor=pointer]: + - img [ref=e290] + - link "Markdown to HTML" [ref=e295] [cursor=pointer]: + - /url: /markdown-to-html + - menuitem "HTML to Markdown" [ref=e296]: + - img [ref=e298] [cursor=pointer]: + - img [ref=e299] + - link "HTML to Markdown" [ref=e305] [cursor=pointer]: + - /url: /html-to-markdown + - generic [ref=e306]: + - generic [ref=e307] [cursor=pointer]: + - img [ref=e309] + - generic [ref=e311]: Web + - menu [ref=e315]: + - menuitem "Encode/decode URL-formatted strings" [ref=e316]: + - img [ref=e318] [cursor=pointer]: + - img [ref=e319] + - link "Encode/decode URL-formatted strings" [ref=e323] [cursor=pointer]: + - /url: /url-encoder + - menuitem "Escape HTML entities" [ref=e324]: + - img [ref=e326] [cursor=pointer]: + - img [ref=e327] + - link "Escape HTML entities" [ref=e332] [cursor=pointer]: + - /url: /html-entities + - menuitem "URL parser" [ref=e333]: + - img [ref=e335] [cursor=pointer]: + - img [ref=e336] + - link "URL parser" [ref=e340] [cursor=pointer]: + - /url: /url-parser + - menuitem "Device information" [ref=e341]: + - img [ref=e343] [cursor=pointer]: + - img [ref=e344] + - link "Device information" [ref=e347] [cursor=pointer]: + - /url: /device-information + - menuitem "Basic auth generator" [ref=e348]: + - img [ref=e350] [cursor=pointer]: + - img [ref=e351] + - link "Basic auth generator" [ref=e353] [cursor=pointer]: + - /url: /basic-auth-generator + - menuitem "Open graph meta generator" [ref=e354]: + - img [ref=e356] [cursor=pointer]: + - img [ref=e357] + - link "Open graph meta generator" [ref=e361] [cursor=pointer]: + - /url: /og-meta-generator + - menuitem "OTP code generator" [ref=e362]: + - img [ref=e364] [cursor=pointer]: + - img [ref=e365] + - link "OTP code generator" [ref=e368] [cursor=pointer]: + - /url: /otp-generator + - menuitem "MIME types" [ref=e369]: + - img [ref=e371] [cursor=pointer]: + - img [ref=e372] + - link "MIME types" [ref=e377] [cursor=pointer]: + - /url: /mime-types + - menuitem "JWT parser" [ref=e378]: + - img [ref=e380] [cursor=pointer]: + - img [ref=e381] + - link "JWT parser" [ref=e387] [cursor=pointer]: + - /url: /jwt-parser + - menuitem "Keycode info" [ref=e388]: + - img [ref=e390] [cursor=pointer]: + - img [ref=e391] + - link "Keycode info" [ref=e394] [cursor=pointer]: + - /url: /keycode-info + - menuitem "Slugify string" [ref=e395]: + - img [ref=e397] [cursor=pointer]: + - img [ref=e398] + - link "Slugify string" [ref=e400] [cursor=pointer]: + - /url: /slugify-string + - menuitem "HTML WYSIWYG editor" [ref=e401]: + - img [ref=e403] [cursor=pointer]: + - img [ref=e404] + - link "HTML WYSIWYG editor" [ref=e409] [cursor=pointer]: + - /url: /html-wysiwyg-editor + - menuitem "User-agent parser" [ref=e410]: + - img [ref=e412] [cursor=pointer]: + - img [ref=e413] + - link "User-agent parser" [ref=e416] [cursor=pointer]: + - /url: /user-agent-parser + - menuitem "HTTP status codes" [ref=e417]: + - img [ref=e419] [cursor=pointer]: + - img [ref=e420] + - link "HTTP status codes" [ref=e422] [cursor=pointer]: + - /url: /http-status-codes + - menuitem "JSON diff" [ref=e423]: + - img [ref=e425] [cursor=pointer]: + - img [ref=e426] + - link "JSON diff" [ref=e428] [cursor=pointer]: + - /url: /json-diff + - menuitem "Outlook Safelink decoder" [ref=e429]: + - img [ref=e431] [cursor=pointer]: + - img [ref=e432] + - link "Outlook Safelink decoder" [ref=e436] [cursor=pointer]: + - /url: /safelink-decoder + - generic [ref=e437]: + - generic [ref=e438] [cursor=pointer]: + - img [ref=e440] + - generic [ref=e442]: Images & Videos + - menu [ref=e446]: + - menuitem "QR Code generator" [ref=e447]: + - img [ref=e449] [cursor=pointer]: + - img [ref=e450] + - link "QR Code generator" [ref=e455] [cursor=pointer]: + - /url: /qrcode-generator + - menuitem "WiFi QR Code generator" [ref=e456]: + - img [ref=e458] [cursor=pointer]: + - img [ref=e459] + - link "WiFi QR Code generator" [ref=e464] [cursor=pointer]: + - /url: /wifi-qrcode-generator + - menuitem "SVG placeholder generator" [ref=e465]: + - img [ref=e467] [cursor=pointer]: + - img [ref=e468] + - link "SVG placeholder generator" [ref=e470] [cursor=pointer]: + - /url: /svg-placeholder-generator + - menuitem "Camera recorder" [ref=e471]: + - img [ref=e473] [cursor=pointer]: + - img [ref=e474] + - link "Camera recorder" [ref=e478] [cursor=pointer]: + - /url: /camera-recorder + - generic [ref=e479]: + - generic [ref=e480] [cursor=pointer]: + - img [ref=e482] + - generic [ref=e484]: Development + - menu [ref=e488]: + - menuitem "Git cheatsheet" [ref=e489]: + - img [ref=e491] [cursor=pointer]: + - img [ref=e492] + - link "Git cheatsheet" [ref=e500] [cursor=pointer]: + - /url: /git-memo + - menuitem "Random port generator" [ref=e501]: + - img [ref=e503] [cursor=pointer]: + - img [ref=e504] + - link "Random port generator" [ref=e508] [cursor=pointer]: + - /url: /random-port-generator + - menuitem "Crontab generator" [ref=e509]: + - img [ref=e511] [cursor=pointer]: + - img [ref=e512] + - link "Crontab generator" [ref=e518] [cursor=pointer]: + - /url: /crontab-generator + - menuitem "JSON prettify and format" [ref=e519]: + - img [ref=e521] [cursor=pointer]: + - img [ref=e522] + - link "JSON prettify and format" [ref=e526] [cursor=pointer]: + - /url: /json-prettify + - menuitem "JSON minify" [ref=e527]: + - img [ref=e529] [cursor=pointer]: + - img [ref=e530] + - link "JSON minify" [ref=e534] [cursor=pointer]: + - /url: /json-minify + - menuitem "JSON to CSV" [ref=e535]: + - img [ref=e537] [cursor=pointer]: + - img [ref=e538] + - link "JSON to CSV" [ref=e540] [cursor=pointer]: + - /url: /json-to-csv + - menuitem "SQL prettify and format" [ref=e541]: + - img [ref=e543] [cursor=pointer]: + - img [ref=e544] + - link "SQL prettify and format" [ref=e549] [cursor=pointer]: + - /url: /sql-prettify + - menuitem "Chmod calculator" [ref=e550]: + - img [ref=e552] [cursor=pointer]: + - img [ref=e553] + - link "Chmod calculator" [ref=e557] [cursor=pointer]: + - /url: /chmod-calculator + - menuitem "Docker run to Docker compose converter" [ref=e558]: + - img [ref=e560] [cursor=pointer]: + - img [ref=e561] + - link "Docker run to Docker compose converter" [ref=e571] [cursor=pointer]: + - /url: /docker-run-to-docker-compose-converter + - menuitem "XML formatter" [ref=e572]: + - img [ref=e574] [cursor=pointer]: + - img [ref=e575] + - link "XML formatter" [ref=e580] [cursor=pointer]: + - /url: /xml-formatter + - menuitem "YAML prettify and format" [ref=e581]: + - img [ref=e583] [cursor=pointer]: + - img [ref=e584] + - link "YAML prettify and format" [ref=e586] [cursor=pointer]: + - /url: /yaml-prettify + - menuitem "Email normalizer" [ref=e587]: + - img [ref=e589] [cursor=pointer]: + - img [ref=e590] + - link "Email normalizer" [ref=e594] [cursor=pointer]: + - /url: /email-normalizer + - menuitem "Regex Tester" [ref=e595]: + - img [ref=e597] [cursor=pointer]: + - img [ref=e598] + - link "Regex Tester" [ref=e603] [cursor=pointer]: + - /url: /regex-tester + - menuitem "Regex cheatsheet" [ref=e604]: + - img [ref=e606] [cursor=pointer]: + - img [ref=e607] + - link "Regex cheatsheet" [ref=e612] [cursor=pointer]: + - /url: /regex-memo + - menuitem "cURL to Code" [ref=e613]: + - img [ref=e615] [cursor=pointer]: + - img [ref=e616] + - link "cURL to Code" [ref=e620] [cursor=pointer]: + - /url: /curl-to-code + - menuitem "JSON to TypeScript/Go" [ref=e621]: + - img [ref=e623] [cursor=pointer]: + - img [ref=e624] + - link "JSON to TypeScript/Go" [ref=e629] [cursor=pointer]: + - /url: /json-to-types + - menuitem "CSS/JS Prettify & Minify" [ref=e630]: + - img [ref=e632] [cursor=pointer]: + - img [ref=e633] + - link "CSS/JS Prettify & Minify" [ref=e639] [cursor=pointer]: + - /url: /css-js-prettify-minify + - generic [ref=e640]: + - generic [ref=e641] [cursor=pointer]: + - img [ref=e643] + - generic [ref=e645]: Network + - menu [ref=e649]: + - menuitem "IPv4 subnet calculator" [ref=e650]: + - img [ref=e652] [cursor=pointer]: + - img [ref=e653] + - link "IPv4 subnet calculator" [ref=e655] [cursor=pointer]: + - /url: /ipv4-subnet-calculator + - menuitem "IPv4 address converter" [ref=e656]: + - img [ref=e658] [cursor=pointer]: + - img [ref=e659] + - link "IPv4 address converter" [ref=e665] [cursor=pointer]: + - /url: /ipv4-address-converter + - menuitem "IPv4 range expander" [ref=e666]: + - img [ref=e668] [cursor=pointer]: + - img [ref=e669] + - link "IPv4 range expander" [ref=e671] [cursor=pointer]: + - /url: /ipv4-range-expander + - menuitem "MAC address lookup" [ref=e672]: + - img [ref=e674] [cursor=pointer]: + - img [ref=e675] + - link "MAC address lookup" [ref=e679] [cursor=pointer]: + - /url: /mac-address-lookup + - menuitem "MAC address generator" [ref=e680]: + - img [ref=e682] [cursor=pointer]: + - img [ref=e683] + - link "MAC address generator" [ref=e687] [cursor=pointer]: + - /url: /mac-address-generator + - menuitem "IPv6 ULA generator" [ref=e688]: + - img [ref=e690] [cursor=pointer]: + - img [ref=e691] + - link "IPv6 ULA generator" [ref=e696] [cursor=pointer]: + - /url: /ipv6-ula-generator + - menuitem "DNS Query" [ref=e697]: + - img [ref=e699] [cursor=pointer]: + - img [ref=e700] + - link "DNS Query" [ref=e706] [cursor=pointer]: + - /url: /dns-query + - generic [ref=e707]: + - generic [ref=e708] [cursor=pointer]: + - img [ref=e710] + - generic [ref=e712]: Math + - menu [ref=e716]: + - menuitem "Math evaluator" [ref=e717]: + - img [ref=e719] [cursor=pointer]: + - img [ref=e720] + - link "Math evaluator" [ref=e724] [cursor=pointer]: + - /url: /math-evaluator + - menuitem "ETA calculator" [ref=e725]: + - img [ref=e727] [cursor=pointer]: + - img [ref=e728] + - link "ETA calculator" [ref=e732] [cursor=pointer]: + - /url: /eta-calculator + - menuitem "Percentage calculator" [ref=e733]: + - img [ref=e735] [cursor=pointer]: + - img [ref=e736] + - link "Percentage calculator" [ref=e741] [cursor=pointer]: + - /url: /percentage-calculator + - generic [ref=e742]: + - generic [ref=e743] [cursor=pointer]: + - img [ref=e745] + - generic [ref=e747]: Measurement + - menu [ref=e751]: + - menuitem "Chronometer" [ref=e752]: + - img [ref=e754] [cursor=pointer]: + - img [ref=e755] + - link "Chronometer" [ref=e757] [cursor=pointer]: + - /url: /chronometer + - menuitem "Temperature converter" [ref=e758]: + - img [ref=e760] [cursor=pointer]: + - img [ref=e761] + - link "Temperature converter" [ref=e764] [cursor=pointer]: + - /url: /temperature-converter + - menuitem "Benchmark builder" [ref=e765]: + - img [ref=e767] [cursor=pointer]: + - img [ref=e768] + - link "Benchmark builder" [ref=e770] [cursor=pointer]: + - /url: /benchmark-builder + - menuitem "Byte unit converter" [ref=e771]: + - img [ref=e773] [cursor=pointer]: + - img [ref=e774] + - link "Byte unit converter" [ref=e781] [cursor=pointer]: + - /url: /byte-unit-converter + - generic [ref=e782]: + - generic [ref=e783] [cursor=pointer]: + - img [ref=e785] + - generic [ref=e787]: Text + - menu [ref=e791]: + - menuitem "Lorem ipsum generator" [ref=e792]: + - img [ref=e794] [cursor=pointer]: + - img [ref=e795] + - link "Lorem ipsum generator" [ref=e797] [cursor=pointer]: + - /url: /lorem-ipsum-generator + - menuitem "Text statistics" [ref=e798]: + - img [ref=e800] [cursor=pointer]: + - img [ref=e801] + - link "Text statistics" [ref=e805] [cursor=pointer]: + - /url: /text-statistics + - menuitem "Emoji picker" [ref=e806]: + - img [ref=e808] [cursor=pointer]: + - img [ref=e809] + - link "Emoji picker" [ref=e813] [cursor=pointer]: + - /url: /emoji-picker + - menuitem "String obfuscator" [ref=e814]: + - img [ref=e816] [cursor=pointer]: + - img [ref=e817] + - link "String obfuscator" [ref=e822] [cursor=pointer]: + - /url: /string-obfuscator + - menuitem "Text diff" [ref=e823]: + - img [ref=e825] [cursor=pointer]: + - img [ref=e826] + - link "Text diff" [ref=e830] [cursor=pointer]: + - /url: /text-diff + - menuitem "Numeronym generator" [ref=e831]: + - img [ref=e833] [cursor=pointer]: + - img [ref=e834]: + - generic "n7m" [ref=e835] + - link "Numeronym generator" [ref=e836] [cursor=pointer]: + - /url: /numeronym-generator + - menuitem "ASCII Art Text Generator" [ref=e837]: + - img [ref=e839] [cursor=pointer]: + - img [ref=e840] + - link "ASCII Art Text Generator" [ref=e843] [cursor=pointer]: + - /url: /ascii-text-drawer + - generic [ref=e844]: + - generic [ref=e845] [cursor=pointer]: + - img [ref=e847] + - generic [ref=e849]: Data + - menu [ref=e853]: + - menuitem "Phone parser and formatter" [ref=e854]: + - img [ref=e856] [cursor=pointer]: + - img [ref=e857] + - link "Phone parser and formatter" [ref=e859] [cursor=pointer]: + - /url: /phone-parser-and-formatter + - menuitem "IBAN validator and parser" [ref=e860]: + - img [ref=e862] [cursor=pointer]: + - img [ref=e863] + - link "IBAN validator and parser" [ref=e865] [cursor=pointer]: + - /url: /iban-validator-and-parser + - generic [ref=e866]: + - generic [ref=e867]: + - text: IT-Tools + - link "v2024.10.22-7ca5933" [ref=e868] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools/tree/v2024.10.22-7ca5933 + - generic [ref=e869]: + - text: © 2026 + - link "Corentin Thomasset" [ref=e870] [cursor=pointer]: + - /url: https://corentin.tech?utm_source=it-tools&utm_medium=footer + - generic [ref=e874]: + - button "Toggle menu" [ref=e875] [cursor=pointer]: + - img [ref=e876]: + - img [ref=e877] + - link "Home" [ref=e881] [cursor=pointer]: + - /url: / + - img [ref=e882]: + - img [ref=e883] + - link "UI Lib" [ref=e890] [cursor=pointer]: + - /url: /c-lib + - img [ref=e891] + - button "Search Cmd + K" [ref=e894] [cursor=pointer]: + - generic [ref=e895]: + - img [ref=e896] + - text: Search + - generic [ref=e898]: Cmd + K + - generic [ref=e901] [cursor=pointer]: + - generic [ref=e902]: English + - img [ref=e903] + - generic [ref=e905]: + - link "IT-Tools GitHub repository" [ref=e908] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools + - img [ref=e909]: + - img [ref=e910] + - link "IT Tools X account" [ref=e914] [cursor=pointer]: + - /url: https://x.com/ittoolsdottech + - img [ref=e915]: + - img [ref=e916] + - link "About" [ref=e921] [cursor=pointer]: + - /url: /about + - img [ref=e922]: + - img [ref=e923] + - button "Toggle dark/light mode" [ref=e928] [cursor=pointer]: + - img [ref=e929]: + - img [ref=e930] + - link "Buy me a coffee" [ref=e934] [cursor=pointer]: + - /url: https://www.buymeacoffee.com/cthmsst + - text: Buy me a coffee + - img [ref=e935]: + - img [ref=e936] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-06-12T07-24-44-587Z.yml b/.playwright-mcp/page-2026-06-12T07-24-44-587Z.yml new file mode 100644 index 0000000000..43bd94fbee --- /dev/null +++ b/.playwright-mcp/page-2026-06-12T07-24-44-587Z.yml @@ -0,0 +1,616 @@ +- generic [ref=e5]: + - complementary [ref=e6]: + - link "IT - TOOLS Handy tools for developers" [ref=e7] [cursor=pointer]: + - /url: / + - img [ref=e8] + - generic [ref=e13]: + - generic [ref=e14]: IT - TOOLS + - generic [ref=e16]: Handy tools for developers + - generic [ref=e17]: + - generic [ref=e18]: + - generic [ref=e19] [cursor=pointer]: + - img [ref=e21] + - generic [ref=e23]: Crypto + - menu [ref=e27]: + - menuitem "Token generator" [ref=e28]: + - img [ref=e30] [cursor=pointer]: + - img [ref=e31] + - link "Token generator" [ref=e37] [cursor=pointer]: + - /url: /token-generator + - menuitem "Hash text" [ref=e38]: + - img [ref=e40] [cursor=pointer]: + - img [ref=e41] + - link "Hash text" [ref=e46] [cursor=pointer]: + - /url: /hash-text + - menuitem "Bcrypt" [ref=e47]: + - img [ref=e49] [cursor=pointer]: + - img [ref=e50] + - link "Bcrypt" [ref=e55] [cursor=pointer]: + - /url: /bcrypt + - menuitem "UUIDs generator" [ref=e56]: + - img [ref=e58] [cursor=pointer]: + - img [ref=e59] + - link "UUIDs generator" [ref=e66] [cursor=pointer]: + - /url: /uuid-generator + - menuitem "ULID generator" [ref=e67]: + - img [ref=e69] [cursor=pointer]: + - img [ref=e70] + - link "ULID generator" [ref=e76] [cursor=pointer]: + - /url: /ulid-generator + - menuitem "Encrypt / decrypt text" [ref=e77]: + - img [ref=e79] [cursor=pointer]: + - img [ref=e80] + - link "Encrypt / decrypt text" [ref=e85] [cursor=pointer]: + - /url: /encryption + - menuitem "BIP39 passphrase generator" [ref=e86]: + - img [ref=e88] [cursor=pointer]: + - img [ref=e89] + - link "BIP39 passphrase generator" [ref=e91] [cursor=pointer]: + - /url: /bip39-generator + - menuitem "Hmac generator" [ref=e92]: + - img [ref=e94] [cursor=pointer]: + - img [ref=e95] + - link "Hmac generator" [ref=e97] [cursor=pointer]: + - /url: /hmac-generator + - menuitem "RSA key pair generator" [ref=e98]: + - img [ref=e100] [cursor=pointer]: + - img [ref=e101] + - link "RSA key pair generator" [ref=e106] [cursor=pointer]: + - /url: /rsa-key-pair-generator + - menuitem "Password strength analyser" [ref=e107]: + - img [ref=e109] [cursor=pointer]: + - img [ref=e110] + - link "Password strength analyser" [ref=e112] [cursor=pointer]: + - /url: /password-strength-analyser + - menuitem "PDF signature checker" [ref=e113]: + - img [ref=e115] [cursor=pointer]: + - img [ref=e116] + - link "PDF signature checker" [ref=e118] [cursor=pointer]: + - /url: /pdf-signature-checker + - menuitem "SSL Certificate Parser" [ref=e119]: + - img [ref=e121] [cursor=pointer]: + - img [ref=e122] + - link "SSL Certificate Parser" [ref=e129] [cursor=pointer]: + - /url: /ssl-certificate-parser + - generic [ref=e130]: + - generic [ref=e131] [cursor=pointer]: + - img [ref=e133] + - generic [ref=e135]: Converter + - menu [ref=e139]: + - menuitem "Date-time converter" [ref=e140]: + - img [ref=e142] [cursor=pointer]: + - img [ref=e143] + - link "Date-time converter" [ref=e146] [cursor=pointer]: + - /url: /date-converter + - menuitem "Integer base converter" [ref=e147]: + - img [ref=e149] [cursor=pointer]: + - img [ref=e150] + - link "Integer base converter" [ref=e154] [cursor=pointer]: + - /url: /base-converter + - menuitem "Roman numeral converter" [ref=e155]: + - img [ref=e157] [cursor=pointer]: + - img [ref=e158] + - link "Roman numeral converter" [ref=e162] [cursor=pointer]: + - /url: /roman-numeral-converter + - menuitem "Base64 string encoder/decoder" [ref=e163]: + - img [ref=e165] [cursor=pointer]: + - img [ref=e166] + - link "Base64 string encoder/decoder" [ref=e171] [cursor=pointer]: + - /url: /base64-string-converter + - menuitem "Base64 file converter" [ref=e172]: + - img [ref=e174] [cursor=pointer]: + - img [ref=e175] + - link "Base64 file converter" [ref=e180] [cursor=pointer]: + - /url: /base64-file-converter + - menuitem "Color converter" [ref=e181]: + - img [ref=e183] [cursor=pointer]: + - img [ref=e184] + - link "Color converter" [ref=e190] [cursor=pointer]: + - /url: /color-converter + - menuitem "Case converter" [ref=e191]: + - img [ref=e193] [cursor=pointer]: + - img [ref=e194] + - link "Case converter" [ref=e198] [cursor=pointer]: + - /url: /case-converter + - menuitem "Text to NATO alphabet" [ref=e199]: + - img [ref=e201] [cursor=pointer]: + - img [ref=e202] + - link "Text to NATO alphabet" [ref=e207] [cursor=pointer]: + - /url: /text-to-nato-alphabet + - menuitem "Text to ASCII binary" [ref=e208]: + - img [ref=e210] [cursor=pointer]: + - img [ref=e211] + - link "Text to ASCII binary" [ref=e217] [cursor=pointer]: + - /url: /text-to-binary + - menuitem "Text to Unicode" [ref=e218]: + - img [ref=e220] [cursor=pointer]: + - img [ref=e221] + - link "Text to Unicode" [ref=e224] [cursor=pointer]: + - /url: /text-to-unicode + - menuitem "YAML to JSON converter" [ref=e225]: + - img [ref=e227] [cursor=pointer]: + - img [ref=e228] + - link "YAML to JSON converter" [ref=e230] [cursor=pointer]: + - /url: /yaml-to-json-converter + - menuitem "YAML to TOML" [ref=e231]: + - img [ref=e233] [cursor=pointer]: + - img [ref=e234] + - link "YAML to TOML" [ref=e236] [cursor=pointer]: + - /url: /yaml-to-toml + - menuitem "JSON to YAML converter" [ref=e237]: + - img [ref=e239] [cursor=pointer]: + - img [ref=e240] + - link "JSON to YAML converter" [ref=e244] [cursor=pointer]: + - /url: /json-to-yaml-converter + - menuitem "JSON to TOML" [ref=e245]: + - img [ref=e247] [cursor=pointer]: + - img [ref=e248] + - link "JSON to TOML" [ref=e252] [cursor=pointer]: + - /url: /json-to-toml + - menuitem "List converter" [ref=e253]: + - img [ref=e255] [cursor=pointer]: + - img [ref=e256] + - link "List converter" [ref=e258] [cursor=pointer]: + - /url: /list-converter + - menuitem "TOML to JSON" [ref=e259]: + - img [ref=e261] [cursor=pointer]: + - img [ref=e262] + - link "TOML to JSON" [ref=e264] [cursor=pointer]: + - /url: /toml-to-json + - menuitem "TOML to YAML" [ref=e265]: + - img [ref=e267] [cursor=pointer]: + - img [ref=e268] + - link "TOML to YAML" [ref=e270] [cursor=pointer]: + - /url: /toml-to-yaml + - menuitem "XML to JSON" [ref=e271]: + - img [ref=e273] [cursor=pointer]: + - img [ref=e274] + - link "XML to JSON" [ref=e278] [cursor=pointer]: + - /url: /xml-to-json + - menuitem "JSON to XML" [ref=e279]: + - img [ref=e281] [cursor=pointer]: + - img [ref=e282] + - link "JSON to XML" [ref=e286] [cursor=pointer]: + - /url: /json-to-xml + - menuitem "Markdown to HTML" [ref=e287]: + - img [ref=e289] [cursor=pointer]: + - img [ref=e290] + - link "Markdown to HTML" [ref=e295] [cursor=pointer]: + - /url: /markdown-to-html + - menuitem "HTML to Markdown" [ref=e296]: + - img [ref=e298] [cursor=pointer]: + - img [ref=e299] + - link "HTML to Markdown" [ref=e305] [cursor=pointer]: + - /url: /html-to-markdown + - generic [ref=e306]: + - generic [ref=e307] [cursor=pointer]: + - img [ref=e309] + - generic [ref=e311]: Web + - menu [ref=e315]: + - menuitem "Encode/decode URL-formatted strings" [ref=e316]: + - img [ref=e318] [cursor=pointer]: + - img [ref=e319] + - link "Encode/decode URL-formatted strings" [ref=e323] [cursor=pointer]: + - /url: /url-encoder + - menuitem "Escape HTML entities" [ref=e324]: + - img [ref=e326] [cursor=pointer]: + - img [ref=e327] + - link "Escape HTML entities" [ref=e332] [cursor=pointer]: + - /url: /html-entities + - menuitem "URL parser" [ref=e333]: + - img [ref=e335] [cursor=pointer]: + - img [ref=e336] + - link "URL parser" [ref=e340] [cursor=pointer]: + - /url: /url-parser + - menuitem "Device information" [ref=e341]: + - img [ref=e343] [cursor=pointer]: + - img [ref=e344] + - link "Device information" [ref=e347] [cursor=pointer]: + - /url: /device-information + - menuitem "Basic auth generator" [ref=e348]: + - img [ref=e350] [cursor=pointer]: + - img [ref=e351] + - link "Basic auth generator" [ref=e353] [cursor=pointer]: + - /url: /basic-auth-generator + - menuitem "Open graph meta generator" [ref=e354]: + - img [ref=e356] [cursor=pointer]: + - img [ref=e357] + - link "Open graph meta generator" [ref=e361] [cursor=pointer]: + - /url: /og-meta-generator + - menuitem "OTP code generator" [ref=e362]: + - img [ref=e364] [cursor=pointer]: + - img [ref=e365] + - link "OTP code generator" [ref=e368] [cursor=pointer]: + - /url: /otp-generator + - menuitem "MIME types" [ref=e369]: + - img [ref=e371] [cursor=pointer]: + - img [ref=e372] + - link "MIME types" [ref=e377] [cursor=pointer]: + - /url: /mime-types + - menuitem "JWT parser" [ref=e378]: + - img [ref=e380] [cursor=pointer]: + - img [ref=e381] + - link "JWT parser" [ref=e387] [cursor=pointer]: + - /url: /jwt-parser + - menuitem "Keycode info" [ref=e388]: + - img [ref=e390] [cursor=pointer]: + - img [ref=e391] + - link "Keycode info" [ref=e394] [cursor=pointer]: + - /url: /keycode-info + - menuitem "Slugify string" [ref=e395]: + - img [ref=e397] [cursor=pointer]: + - img [ref=e398] + - link "Slugify string" [ref=e400] [cursor=pointer]: + - /url: /slugify-string + - menuitem "HTML WYSIWYG editor" [ref=e401]: + - img [ref=e403] [cursor=pointer]: + - img [ref=e404] + - link "HTML WYSIWYG editor" [ref=e409] [cursor=pointer]: + - /url: /html-wysiwyg-editor + - menuitem "User-agent parser" [ref=e410]: + - img [ref=e412] [cursor=pointer]: + - img [ref=e413] + - link "User-agent parser" [ref=e416] [cursor=pointer]: + - /url: /user-agent-parser + - menuitem "HTTP status codes" [ref=e417]: + - img [ref=e419] [cursor=pointer]: + - img [ref=e420] + - link "HTTP status codes" [ref=e422] [cursor=pointer]: + - /url: /http-status-codes + - menuitem "JSON diff" [ref=e423]: + - img [ref=e425] [cursor=pointer]: + - img [ref=e426] + - link "JSON diff" [ref=e428] [cursor=pointer]: + - /url: /json-diff + - menuitem "Outlook Safelink decoder" [ref=e429]: + - img [ref=e431] [cursor=pointer]: + - img [ref=e432] + - link "Outlook Safelink decoder" [ref=e436] [cursor=pointer]: + - /url: /safelink-decoder + - generic [ref=e437]: + - generic [ref=e438] [cursor=pointer]: + - img [ref=e440] + - generic [ref=e442]: Images & Videos + - menu [ref=e446]: + - menuitem "QR Code generator" [ref=e447]: + - img [ref=e449] [cursor=pointer]: + - img [ref=e450] + - link "QR Code generator" [ref=e455] [cursor=pointer]: + - /url: /qrcode-generator + - menuitem "WiFi QR Code generator" [ref=e456]: + - img [ref=e458] [cursor=pointer]: + - img [ref=e459] + - link "WiFi QR Code generator" [ref=e464] [cursor=pointer]: + - /url: /wifi-qrcode-generator + - menuitem "SVG placeholder generator" [ref=e465]: + - img [ref=e467] [cursor=pointer]: + - img [ref=e468] + - link "SVG placeholder generator" [ref=e470] [cursor=pointer]: + - /url: /svg-placeholder-generator + - menuitem "Camera recorder" [ref=e471]: + - img [ref=e473] [cursor=pointer]: + - img [ref=e474] + - link "Camera recorder" [ref=e478] [cursor=pointer]: + - /url: /camera-recorder + - generic [ref=e479]: + - generic [ref=e480] [cursor=pointer]: + - img [ref=e482] + - generic [ref=e484]: Development + - menu [ref=e488]: + - menuitem "Git cheatsheet" [ref=e489]: + - img [ref=e491] [cursor=pointer]: + - img [ref=e492] + - link "Git cheatsheet" [ref=e500] [cursor=pointer]: + - /url: /git-memo + - menuitem "Random port generator" [ref=e501]: + - img [ref=e503] [cursor=pointer]: + - img [ref=e504] + - link "Random port generator" [ref=e508] [cursor=pointer]: + - /url: /random-port-generator + - menuitem "Crontab generator" [ref=e509]: + - img [ref=e511] [cursor=pointer]: + - img [ref=e512] + - link "Crontab generator" [ref=e518] [cursor=pointer]: + - /url: /crontab-generator + - menuitem "JSON prettify and format" [ref=e519]: + - img [ref=e521] [cursor=pointer]: + - img [ref=e522] + - link "JSON prettify and format" [ref=e526] [cursor=pointer]: + - /url: /json-prettify + - menuitem "JSON minify" [ref=e527]: + - img [ref=e529] [cursor=pointer]: + - img [ref=e530] + - link "JSON minify" [ref=e534] [cursor=pointer]: + - /url: /json-minify + - menuitem "JSON to CSV" [ref=e535]: + - img [ref=e537] [cursor=pointer]: + - img [ref=e538] + - link "JSON to CSV" [ref=e540] [cursor=pointer]: + - /url: /json-to-csv + - menuitem "SQL prettify and format" [ref=e541]: + - img [ref=e543] [cursor=pointer]: + - img [ref=e544] + - link "SQL prettify and format" [ref=e549] [cursor=pointer]: + - /url: /sql-prettify + - menuitem "Chmod calculator" [ref=e550]: + - img [ref=e552] [cursor=pointer]: + - img [ref=e553] + - link "Chmod calculator" [ref=e557] [cursor=pointer]: + - /url: /chmod-calculator + - menuitem "Docker run to Docker compose converter" [ref=e558]: + - img [ref=e560] [cursor=pointer]: + - img [ref=e561] + - link "Docker run to Docker compose converter" [ref=e571] [cursor=pointer]: + - /url: /docker-run-to-docker-compose-converter + - menuitem "XML formatter" [ref=e572]: + - img [ref=e574] [cursor=pointer]: + - img [ref=e575] + - link "XML formatter" [ref=e580] [cursor=pointer]: + - /url: /xml-formatter + - menuitem "YAML prettify and format" [ref=e581]: + - img [ref=e583] [cursor=pointer]: + - img [ref=e584] + - link "YAML prettify and format" [ref=e586] [cursor=pointer]: + - /url: /yaml-prettify + - menuitem "Email normalizer" [ref=e587]: + - img [ref=e589] [cursor=pointer]: + - img [ref=e590] + - link "Email normalizer" [ref=e594] [cursor=pointer]: + - /url: /email-normalizer + - menuitem "Regex Tester" [ref=e595]: + - img [ref=e597] [cursor=pointer]: + - img [ref=e598] + - link "Regex Tester" [ref=e603] [cursor=pointer]: + - /url: /regex-tester + - menuitem "Regex cheatsheet" [ref=e604]: + - img [ref=e606] [cursor=pointer]: + - img [ref=e607] + - link "Regex cheatsheet" [ref=e612] [cursor=pointer]: + - /url: /regex-memo + - menuitem "cURL to Code" [ref=e613]: + - img [ref=e615] [cursor=pointer]: + - img [ref=e616] + - link "cURL to Code" [ref=e620] [cursor=pointer]: + - /url: /curl-to-code + - menuitem "JSON to TypeScript/Go" [ref=e621]: + - img [ref=e623] [cursor=pointer]: + - img [ref=e624] + - link "JSON to TypeScript/Go" [ref=e629] [cursor=pointer]: + - /url: /json-to-types + - menuitem "CSS/JS Prettify & Minify" [ref=e630]: + - img [ref=e632] [cursor=pointer]: + - img [ref=e633] + - link "CSS/JS Prettify & Minify" [ref=e639] [cursor=pointer]: + - /url: /css-js-prettify-minify + - generic [ref=e640]: + - generic [ref=e641] [cursor=pointer]: + - img [ref=e643] + - generic [ref=e645]: Network + - menu [ref=e649]: + - menuitem "IPv4 subnet calculator" [ref=e650]: + - img [ref=e652] [cursor=pointer]: + - img [ref=e653] + - link "IPv4 subnet calculator" [ref=e655] [cursor=pointer]: + - /url: /ipv4-subnet-calculator + - menuitem "IPv4 address converter" [ref=e656]: + - img [ref=e658] [cursor=pointer]: + - img [ref=e659] + - link "IPv4 address converter" [ref=e665] [cursor=pointer]: + - /url: /ipv4-address-converter + - menuitem "IPv4 range expander" [ref=e666]: + - img [ref=e668] [cursor=pointer]: + - img [ref=e669] + - link "IPv4 range expander" [ref=e671] [cursor=pointer]: + - /url: /ipv4-range-expander + - menuitem "MAC address lookup" [ref=e672]: + - img [ref=e674] [cursor=pointer]: + - img [ref=e675] + - link "MAC address lookup" [ref=e679] [cursor=pointer]: + - /url: /mac-address-lookup + - menuitem "MAC address generator" [ref=e680]: + - img [ref=e682] [cursor=pointer]: + - img [ref=e683] + - link "MAC address generator" [ref=e687] [cursor=pointer]: + - /url: /mac-address-generator + - menuitem "IPv6 ULA generator" [ref=e688]: + - img [ref=e690] [cursor=pointer]: + - img [ref=e691] + - link "IPv6 ULA generator" [ref=e696] [cursor=pointer]: + - /url: /ipv6-ula-generator + - menuitem "DNS Query" [ref=e697]: + - img [ref=e699] [cursor=pointer]: + - img [ref=e700] + - link "DNS Query" [ref=e706] [cursor=pointer]: + - /url: /dns-query + - generic [ref=e707]: + - generic [ref=e708] [cursor=pointer]: + - img [ref=e710] + - generic [ref=e712]: Math + - menu [ref=e716]: + - menuitem "Math evaluator" [ref=e717]: + - img [ref=e719] [cursor=pointer]: + - img [ref=e720] + - link "Math evaluator" [ref=e724] [cursor=pointer]: + - /url: /math-evaluator + - menuitem "ETA calculator" [ref=e725]: + - img [ref=e727] [cursor=pointer]: + - img [ref=e728] + - link "ETA calculator" [ref=e732] [cursor=pointer]: + - /url: /eta-calculator + - menuitem "Percentage calculator" [ref=e733]: + - img [ref=e735] [cursor=pointer]: + - img [ref=e736] + - link "Percentage calculator" [ref=e741] [cursor=pointer]: + - /url: /percentage-calculator + - generic [ref=e742]: + - generic [ref=e743] [cursor=pointer]: + - img [ref=e745] + - generic [ref=e747]: Measurement + - menu [ref=e751]: + - menuitem "Chronometer" [ref=e752]: + - img [ref=e754] [cursor=pointer]: + - img [ref=e755] + - link "Chronometer" [ref=e757] [cursor=pointer]: + - /url: /chronometer + - menuitem "Temperature converter" [ref=e758]: + - img [ref=e760] [cursor=pointer]: + - img [ref=e761] + - link "Temperature converter" [ref=e764] [cursor=pointer]: + - /url: /temperature-converter + - menuitem "Benchmark builder" [ref=e765]: + - img [ref=e767] [cursor=pointer]: + - img [ref=e768] + - link "Benchmark builder" [ref=e770] [cursor=pointer]: + - /url: /benchmark-builder + - menuitem "Byte unit converter" [ref=e771]: + - img [ref=e773] [cursor=pointer]: + - img [ref=e774] + - link "Byte unit converter" [ref=e781] [cursor=pointer]: + - /url: /byte-unit-converter + - generic [ref=e782]: + - generic [ref=e783] [cursor=pointer]: + - img [ref=e785] + - generic [ref=e787]: Text + - menu [ref=e791]: + - menuitem "Lorem ipsum generator" [ref=e792]: + - img [ref=e794] [cursor=pointer]: + - img [ref=e795] + - link "Lorem ipsum generator" [ref=e797] [cursor=pointer]: + - /url: /lorem-ipsum-generator + - menuitem "Text statistics" [ref=e798]: + - img [ref=e800] [cursor=pointer]: + - img [ref=e801] + - link "Text statistics" [ref=e805] [cursor=pointer]: + - /url: /text-statistics + - menuitem "Emoji picker" [ref=e806]: + - img [ref=e808] [cursor=pointer]: + - img [ref=e809] + - link "Emoji picker" [ref=e813] [cursor=pointer]: + - /url: /emoji-picker + - menuitem "String obfuscator" [ref=e814]: + - img [ref=e816] [cursor=pointer]: + - img [ref=e817] + - link "String obfuscator" [ref=e822] [cursor=pointer]: + - /url: /string-obfuscator + - menuitem "Text diff" [ref=e823]: + - img [ref=e825] [cursor=pointer]: + - img [ref=e826] + - link "Text diff" [ref=e830] [cursor=pointer]: + - /url: /text-diff + - menuitem "Numeronym generator" [ref=e831]: + - img [ref=e833] [cursor=pointer]: + - img [ref=e834]: + - generic "n7m" [ref=e835] + - link "Numeronym generator" [ref=e836] [cursor=pointer]: + - /url: /numeronym-generator + - menuitem "ASCII Art Text Generator" [ref=e837]: + - img [ref=e839] [cursor=pointer]: + - img [ref=e840] + - link "ASCII Art Text Generator" [ref=e843] [cursor=pointer]: + - /url: /ascii-text-drawer + - generic [ref=e844]: + - generic [ref=e845] [cursor=pointer]: + - img [ref=e847] + - generic [ref=e849]: Data + - menu [ref=e853]: + - menuitem "Phone parser and formatter" [ref=e854]: + - img [ref=e856] [cursor=pointer]: + - img [ref=e857] + - link "Phone parser and formatter" [ref=e859] [cursor=pointer]: + - /url: /phone-parser-and-formatter + - menuitem "IBAN validator and parser" [ref=e860]: + - img [ref=e862] [cursor=pointer]: + - img [ref=e863] + - link "IBAN validator and parser" [ref=e865] [cursor=pointer]: + - /url: /iban-validator-and-parser + - generic [ref=e866]: + - generic [ref=e867]: + - text: IT-Tools + - link "v2024.10.22-7ca5933" [ref=e868] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools/tree/v2024.10.22-7ca5933 + - generic [ref=e869]: + - text: © 2026 + - link "Corentin Thomasset" [ref=e870] [cursor=pointer]: + - /url: https://corentin.tech?utm_source=it-tools&utm_medium=footer + - generic [ref=e873]: + - generic [ref=e874]: + - button "Toggle menu" [ref=e875] [cursor=pointer]: + - img [ref=e876]: + - img [ref=e877] + - link "Home" [ref=e881] [cursor=pointer]: + - /url: / + - img [ref=e882]: + - img [ref=e883] + - link "UI Lib" [ref=e890] [cursor=pointer]: + - /url: /c-lib + - img [ref=e891] + - button "Search Cmd + K" [ref=e894] [cursor=pointer]: + - generic [ref=e895]: + - img [ref=e896] + - text: Search + - generic [ref=e898]: Cmd + K + - generic [ref=e901] [cursor=pointer]: + - generic [ref=e902]: English + - img [ref=e903] + - generic [ref=e905]: + - link "IT-Tools GitHub repository" [ref=e908] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools + - img [ref=e909]: + - img [ref=e910] + - link "IT Tools X account" [ref=e914] [cursor=pointer]: + - /url: https://x.com/ittoolsdottech + - img [ref=e915]: + - img [ref=e916] + - link "About" [ref=e921] [cursor=pointer]: + - /url: /about + - img [ref=e922]: + - img [ref=e923] + - button "Toggle dark/light mode" [ref=e928] [cursor=pointer]: + - img [ref=e929]: + - img [ref=e930] + - link "Buy me a coffee" [ref=e934] [cursor=pointer]: + - /url: https://www.buymeacoffee.com/cthmsst + - text: Buy me a coffee + - img [ref=e935]: + - img [ref=e936] + - generic [ref=e939]: + - generic [ref=e940]: + - heading "DNS Query" [level=1] [ref=e941] + - button [ref=e945] [cursor=pointer]: + - img [ref=e946] + - generic [ref=e949]: Query DNS records (A, AAAA, CNAME, MX, TXT, NS, SOA, ...) for any domain name online using Cloudflare DNS. + - generic [ref=e951]: + - generic [ref=e952]: + - generic [ref=e953]: Domain name + - generic [ref=e955]: + - textbox "Domain name" [ref=e956]: + - /placeholder: e.g. example.com + - text: example.com + - button [ref=e957] [cursor=pointer]: + - img [ref=e958] + - generic [ref=e960]: + - generic [ref=e961]: Record type + - generic [ref=e963] [cursor=pointer]: + - generic [ref=e964]: A + - img [ref=e965] + - button "Query DNS" [active] [ref=e968] [cursor=pointer] + - generic [ref=e969]: + - generic [ref=e970]: + - generic [ref=e971]: "Status:" + - generic [ref=e972]: NOERROR + - table [ref=e973]: + - rowgroup [ref=e974]: + - row "Name TTL Data" [ref=e975]: + - columnheader "Name" [ref=e976] + - columnheader "TTL" [ref=e977] + - columnheader "Data" [ref=e978] + - rowgroup [ref=e979]: + - row "example.com 158s 104.20.23.154" [ref=e980]: + - cell "example.com" [ref=e981] + - cell "158s" [ref=e982] + - cell "104.20.23.154" [ref=e983] + - row "example.com 158s 172.66.147.243" [ref=e984]: + - cell "example.com" [ref=e985] + - cell "158s" [ref=e986] + - cell "172.66.147.243" [ref=e987] + - button "Copy results" [ref=e989] [cursor=pointer] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-06-12T07-24-51-311Z.yml b/.playwright-mcp/page-2026-06-12T07-24-51-311Z.yml new file mode 100644 index 0000000000..ab899c10fa --- /dev/null +++ b/.playwright-mcp/page-2026-06-12T07-24-51-311Z.yml @@ -0,0 +1,596 @@ +- generic [ref=e5]: + - complementary [ref=e6]: + - link "IT - TOOLS Handy tools for developers" [ref=e7] [cursor=pointer]: + - /url: / + - img [ref=e8] + - generic [ref=e13]: + - generic [ref=e14]: IT - TOOLS + - generic [ref=e16]: Handy tools for developers + - generic [ref=e17]: + - generic [ref=e18]: + - generic [ref=e19] [cursor=pointer]: + - img [ref=e21] + - generic [ref=e23]: Crypto + - menu [ref=e27]: + - menuitem "Token generator" [ref=e28]: + - img [ref=e30] [cursor=pointer]: + - img [ref=e31] + - link "Token generator" [ref=e37] [cursor=pointer]: + - /url: /token-generator + - menuitem "Hash text" [ref=e38]: + - img [ref=e40] [cursor=pointer]: + - img [ref=e41] + - link "Hash text" [ref=e46] [cursor=pointer]: + - /url: /hash-text + - menuitem "Bcrypt" [ref=e47]: + - img [ref=e49] [cursor=pointer]: + - img [ref=e50] + - link "Bcrypt" [ref=e55] [cursor=pointer]: + - /url: /bcrypt + - menuitem "UUIDs generator" [ref=e56]: + - img [ref=e58] [cursor=pointer]: + - img [ref=e59] + - link "UUIDs generator" [ref=e66] [cursor=pointer]: + - /url: /uuid-generator + - menuitem "ULID generator" [ref=e67]: + - img [ref=e69] [cursor=pointer]: + - img [ref=e70] + - link "ULID generator" [ref=e76] [cursor=pointer]: + - /url: /ulid-generator + - menuitem "Encrypt / decrypt text" [ref=e77]: + - img [ref=e79] [cursor=pointer]: + - img [ref=e80] + - link "Encrypt / decrypt text" [ref=e85] [cursor=pointer]: + - /url: /encryption + - menuitem "BIP39 passphrase generator" [ref=e86]: + - img [ref=e88] [cursor=pointer]: + - img [ref=e89] + - link "BIP39 passphrase generator" [ref=e91] [cursor=pointer]: + - /url: /bip39-generator + - menuitem "Hmac generator" [ref=e92]: + - img [ref=e94] [cursor=pointer]: + - img [ref=e95] + - link "Hmac generator" [ref=e97] [cursor=pointer]: + - /url: /hmac-generator + - menuitem "RSA key pair generator" [ref=e98]: + - img [ref=e100] [cursor=pointer]: + - img [ref=e101] + - link "RSA key pair generator" [ref=e106] [cursor=pointer]: + - /url: /rsa-key-pair-generator + - menuitem "Password strength analyser" [ref=e107]: + - img [ref=e109] [cursor=pointer]: + - img [ref=e110] + - link "Password strength analyser" [ref=e112] [cursor=pointer]: + - /url: /password-strength-analyser + - menuitem "PDF signature checker" [ref=e113]: + - img [ref=e115] [cursor=pointer]: + - img [ref=e116] + - link "PDF signature checker" [ref=e118] [cursor=pointer]: + - /url: /pdf-signature-checker + - menuitem "SSL Certificate Parser" [ref=e119]: + - img [ref=e121] [cursor=pointer]: + - img [ref=e122] + - link "SSL Certificate Parser" [ref=e129] [cursor=pointer]: + - /url: /ssl-certificate-parser + - generic [ref=e130]: + - generic [ref=e131] [cursor=pointer]: + - img [ref=e133] + - generic [ref=e135]: Converter + - menu [ref=e139]: + - menuitem "Date-time converter" [ref=e140]: + - img [ref=e142] [cursor=pointer]: + - img [ref=e143] + - link "Date-time converter" [ref=e146] [cursor=pointer]: + - /url: /date-converter + - menuitem "Integer base converter" [ref=e147]: + - img [ref=e149] [cursor=pointer]: + - img [ref=e150] + - link "Integer base converter" [ref=e154] [cursor=pointer]: + - /url: /base-converter + - menuitem "Roman numeral converter" [ref=e155]: + - img [ref=e157] [cursor=pointer]: + - img [ref=e158] + - link "Roman numeral converter" [ref=e162] [cursor=pointer]: + - /url: /roman-numeral-converter + - menuitem "Base64 string encoder/decoder" [ref=e163]: + - img [ref=e165] [cursor=pointer]: + - img [ref=e166] + - link "Base64 string encoder/decoder" [ref=e171] [cursor=pointer]: + - /url: /base64-string-converter + - menuitem "Base64 file converter" [ref=e172]: + - img [ref=e174] [cursor=pointer]: + - img [ref=e175] + - link "Base64 file converter" [ref=e180] [cursor=pointer]: + - /url: /base64-file-converter + - menuitem "Color converter" [ref=e181]: + - img [ref=e183] [cursor=pointer]: + - img [ref=e184] + - link "Color converter" [ref=e190] [cursor=pointer]: + - /url: /color-converter + - menuitem "Case converter" [ref=e191]: + - img [ref=e193] [cursor=pointer]: + - img [ref=e194] + - link "Case converter" [ref=e198] [cursor=pointer]: + - /url: /case-converter + - menuitem "Text to NATO alphabet" [ref=e199]: + - img [ref=e201] [cursor=pointer]: + - img [ref=e202] + - link "Text to NATO alphabet" [ref=e207] [cursor=pointer]: + - /url: /text-to-nato-alphabet + - menuitem "Text to ASCII binary" [ref=e208]: + - img [ref=e210] [cursor=pointer]: + - img [ref=e211] + - link "Text to ASCII binary" [ref=e217] [cursor=pointer]: + - /url: /text-to-binary + - menuitem "Text to Unicode" [ref=e218]: + - img [ref=e220] [cursor=pointer]: + - img [ref=e221] + - link "Text to Unicode" [ref=e224] [cursor=pointer]: + - /url: /text-to-unicode + - menuitem "YAML to JSON converter" [ref=e225]: + - img [ref=e227] [cursor=pointer]: + - img [ref=e228] + - link "YAML to JSON converter" [ref=e230] [cursor=pointer]: + - /url: /yaml-to-json-converter + - menuitem "YAML to TOML" [ref=e231]: + - img [ref=e233] [cursor=pointer]: + - img [ref=e234] + - link "YAML to TOML" [ref=e236] [cursor=pointer]: + - /url: /yaml-to-toml + - menuitem "JSON to YAML converter" [ref=e237]: + - img [ref=e239] [cursor=pointer]: + - img [ref=e240] + - link "JSON to YAML converter" [ref=e244] [cursor=pointer]: + - /url: /json-to-yaml-converter + - menuitem "JSON to TOML" [ref=e245]: + - img [ref=e247] [cursor=pointer]: + - img [ref=e248] + - link "JSON to TOML" [ref=e252] [cursor=pointer]: + - /url: /json-to-toml + - menuitem "List converter" [ref=e253]: + - img [ref=e255] [cursor=pointer]: + - img [ref=e256] + - link "List converter" [ref=e258] [cursor=pointer]: + - /url: /list-converter + - menuitem "TOML to JSON" [ref=e259]: + - img [ref=e261] [cursor=pointer]: + - img [ref=e262] + - link "TOML to JSON" [ref=e264] [cursor=pointer]: + - /url: /toml-to-json + - menuitem "TOML to YAML" [ref=e265]: + - img [ref=e267] [cursor=pointer]: + - img [ref=e268] + - link "TOML to YAML" [ref=e270] [cursor=pointer]: + - /url: /toml-to-yaml + - menuitem "XML to JSON" [ref=e271]: + - img [ref=e273] [cursor=pointer]: + - img [ref=e274] + - link "XML to JSON" [ref=e278] [cursor=pointer]: + - /url: /xml-to-json + - menuitem "JSON to XML" [ref=e279]: + - img [ref=e281] [cursor=pointer]: + - img [ref=e282] + - link "JSON to XML" [ref=e286] [cursor=pointer]: + - /url: /json-to-xml + - menuitem "Markdown to HTML" [ref=e287]: + - img [ref=e289] [cursor=pointer]: + - img [ref=e290] + - link "Markdown to HTML" [ref=e295] [cursor=pointer]: + - /url: /markdown-to-html + - menuitem "HTML to Markdown" [ref=e296]: + - img [ref=e298] [cursor=pointer]: + - img [ref=e299] + - link "HTML to Markdown" [ref=e305] [cursor=pointer]: + - /url: /html-to-markdown + - generic [ref=e306]: + - generic [ref=e307] [cursor=pointer]: + - img [ref=e309] + - generic [ref=e311]: Web + - menu [ref=e315]: + - menuitem "Encode/decode URL-formatted strings" [ref=e316]: + - img [ref=e318] [cursor=pointer]: + - img [ref=e319] + - link "Encode/decode URL-formatted strings" [ref=e323] [cursor=pointer]: + - /url: /url-encoder + - menuitem "Escape HTML entities" [ref=e324]: + - img [ref=e326] [cursor=pointer]: + - img [ref=e327] + - link "Escape HTML entities" [ref=e332] [cursor=pointer]: + - /url: /html-entities + - menuitem "URL parser" [ref=e333]: + - img [ref=e335] [cursor=pointer]: + - img [ref=e336] + - link "URL parser" [ref=e340] [cursor=pointer]: + - /url: /url-parser + - menuitem "Device information" [ref=e341]: + - img [ref=e343] [cursor=pointer]: + - img [ref=e344] + - link "Device information" [ref=e347] [cursor=pointer]: + - /url: /device-information + - menuitem "Basic auth generator" [ref=e348]: + - img [ref=e350] [cursor=pointer]: + - img [ref=e351] + - link "Basic auth generator" [ref=e353] [cursor=pointer]: + - /url: /basic-auth-generator + - menuitem "Open graph meta generator" [ref=e354]: + - img [ref=e356] [cursor=pointer]: + - img [ref=e357] + - link "Open graph meta generator" [ref=e361] [cursor=pointer]: + - /url: /og-meta-generator + - menuitem "OTP code generator" [ref=e362]: + - img [ref=e364] [cursor=pointer]: + - img [ref=e365] + - link "OTP code generator" [ref=e368] [cursor=pointer]: + - /url: /otp-generator + - menuitem "MIME types" [ref=e369]: + - img [ref=e371] [cursor=pointer]: + - img [ref=e372] + - link "MIME types" [ref=e377] [cursor=pointer]: + - /url: /mime-types + - menuitem "JWT parser" [ref=e378]: + - img [ref=e380] [cursor=pointer]: + - img [ref=e381] + - link "JWT parser" [ref=e387] [cursor=pointer]: + - /url: /jwt-parser + - menuitem "Keycode info" [ref=e388]: + - img [ref=e390] [cursor=pointer]: + - img [ref=e391] + - link "Keycode info" [ref=e394] [cursor=pointer]: + - /url: /keycode-info + - menuitem "Slugify string" [ref=e395]: + - img [ref=e397] [cursor=pointer]: + - img [ref=e398] + - link "Slugify string" [ref=e400] [cursor=pointer]: + - /url: /slugify-string + - menuitem "HTML WYSIWYG editor" [ref=e401]: + - img [ref=e403] [cursor=pointer]: + - img [ref=e404] + - link "HTML WYSIWYG editor" [ref=e409] [cursor=pointer]: + - /url: /html-wysiwyg-editor + - menuitem "User-agent parser" [ref=e410]: + - img [ref=e412] [cursor=pointer]: + - img [ref=e413] + - link "User-agent parser" [ref=e416] [cursor=pointer]: + - /url: /user-agent-parser + - menuitem "HTTP status codes" [ref=e417]: + - img [ref=e419] [cursor=pointer]: + - img [ref=e420] + - link "HTTP status codes" [ref=e422] [cursor=pointer]: + - /url: /http-status-codes + - menuitem "JSON diff" [ref=e423]: + - img [ref=e425] [cursor=pointer]: + - img [ref=e426] + - link "JSON diff" [ref=e428] [cursor=pointer]: + - /url: /json-diff + - menuitem "Outlook Safelink decoder" [ref=e429]: + - img [ref=e431] [cursor=pointer]: + - img [ref=e432] + - link "Outlook Safelink decoder" [ref=e436] [cursor=pointer]: + - /url: /safelink-decoder + - generic [ref=e437]: + - generic [ref=e438] [cursor=pointer]: + - img [ref=e440] + - generic [ref=e442]: Images & Videos + - menu [ref=e446]: + - menuitem "QR Code generator" [ref=e447]: + - img [ref=e449] [cursor=pointer]: + - img [ref=e450] + - link "QR Code generator" [ref=e455] [cursor=pointer]: + - /url: /qrcode-generator + - menuitem "WiFi QR Code generator" [ref=e456]: + - img [ref=e458] [cursor=pointer]: + - img [ref=e459] + - link "WiFi QR Code generator" [ref=e464] [cursor=pointer]: + - /url: /wifi-qrcode-generator + - menuitem "SVG placeholder generator" [ref=e465]: + - img [ref=e467] [cursor=pointer]: + - img [ref=e468] + - link "SVG placeholder generator" [ref=e470] [cursor=pointer]: + - /url: /svg-placeholder-generator + - menuitem "Camera recorder" [ref=e471]: + - img [ref=e473] [cursor=pointer]: + - img [ref=e474] + - link "Camera recorder" [ref=e478] [cursor=pointer]: + - /url: /camera-recorder + - generic [ref=e479]: + - generic [ref=e480] [cursor=pointer]: + - img [ref=e482] + - generic [ref=e484]: Development + - menu [ref=e488]: + - menuitem "Git cheatsheet" [ref=e489]: + - img [ref=e491] [cursor=pointer]: + - img [ref=e492] + - link "Git cheatsheet" [ref=e500] [cursor=pointer]: + - /url: /git-memo + - menuitem "Random port generator" [ref=e501]: + - img [ref=e503] [cursor=pointer]: + - img [ref=e504] + - link "Random port generator" [ref=e508] [cursor=pointer]: + - /url: /random-port-generator + - menuitem "Crontab generator" [ref=e509]: + - img [ref=e511] [cursor=pointer]: + - img [ref=e512] + - link "Crontab generator" [ref=e518] [cursor=pointer]: + - /url: /crontab-generator + - menuitem "JSON prettify and format" [ref=e519]: + - img [ref=e521] [cursor=pointer]: + - img [ref=e522] + - link "JSON prettify and format" [ref=e526] [cursor=pointer]: + - /url: /json-prettify + - menuitem "JSON minify" [ref=e527]: + - img [ref=e529] [cursor=pointer]: + - img [ref=e530] + - link "JSON minify" [ref=e534] [cursor=pointer]: + - /url: /json-minify + - menuitem "JSON to CSV" [ref=e535]: + - img [ref=e537] [cursor=pointer]: + - img [ref=e538] + - link "JSON to CSV" [ref=e540] [cursor=pointer]: + - /url: /json-to-csv + - menuitem "SQL prettify and format" [ref=e541]: + - img [ref=e543] [cursor=pointer]: + - img [ref=e544] + - link "SQL prettify and format" [ref=e549] [cursor=pointer]: + - /url: /sql-prettify + - menuitem "Chmod calculator" [ref=e550]: + - img [ref=e552] [cursor=pointer]: + - img [ref=e553] + - link "Chmod calculator" [ref=e557] [cursor=pointer]: + - /url: /chmod-calculator + - menuitem "Docker run to Docker compose converter" [ref=e558]: + - img [ref=e560] [cursor=pointer]: + - img [ref=e561] + - link "Docker run to Docker compose converter" [ref=e571] [cursor=pointer]: + - /url: /docker-run-to-docker-compose-converter + - menuitem "XML formatter" [ref=e572]: + - img [ref=e574] [cursor=pointer]: + - img [ref=e575] + - link "XML formatter" [ref=e580] [cursor=pointer]: + - /url: /xml-formatter + - menuitem "YAML prettify and format" [ref=e581]: + - img [ref=e583] [cursor=pointer]: + - img [ref=e584] + - link "YAML prettify and format" [ref=e586] [cursor=pointer]: + - /url: /yaml-prettify + - menuitem "Email normalizer" [ref=e587]: + - img [ref=e589] [cursor=pointer]: + - img [ref=e590] + - link "Email normalizer" [ref=e594] [cursor=pointer]: + - /url: /email-normalizer + - menuitem "Regex Tester" [ref=e595]: + - img [ref=e597] [cursor=pointer]: + - img [ref=e598] + - link "Regex Tester" [ref=e603] [cursor=pointer]: + - /url: /regex-tester + - menuitem "Regex cheatsheet" [ref=e604]: + - img [ref=e606] [cursor=pointer]: + - img [ref=e607] + - link "Regex cheatsheet" [ref=e612] [cursor=pointer]: + - /url: /regex-memo + - menuitem "cURL to Code" [ref=e613]: + - img [ref=e615] [cursor=pointer]: + - img [ref=e616] + - link "cURL to Code" [ref=e620] [cursor=pointer]: + - /url: /curl-to-code + - menuitem "JSON to TypeScript/Go" [ref=e621]: + - img [ref=e623] [cursor=pointer]: + - img [ref=e624] + - link "JSON to TypeScript/Go" [ref=e629] [cursor=pointer]: + - /url: /json-to-types + - menuitem "CSS/JS Prettify & Minify" [ref=e630]: + - img [ref=e632] [cursor=pointer]: + - img [ref=e633] + - link "CSS/JS Prettify & Minify" [ref=e639] [cursor=pointer]: + - /url: /css-js-prettify-minify + - generic [ref=e640]: + - generic [ref=e641] [cursor=pointer]: + - img [ref=e643] + - generic [ref=e645]: Network + - menu [ref=e649]: + - menuitem "IPv4 subnet calculator" [ref=e650]: + - img [ref=e652] [cursor=pointer]: + - img [ref=e653] + - link "IPv4 subnet calculator" [ref=e655] [cursor=pointer]: + - /url: /ipv4-subnet-calculator + - menuitem "IPv4 address converter" [ref=e656]: + - img [ref=e658] [cursor=pointer]: + - img [ref=e659] + - link "IPv4 address converter" [ref=e665] [cursor=pointer]: + - /url: /ipv4-address-converter + - menuitem "IPv4 range expander" [ref=e666]: + - img [ref=e668] [cursor=pointer]: + - img [ref=e669] + - link "IPv4 range expander" [ref=e671] [cursor=pointer]: + - /url: /ipv4-range-expander + - menuitem "MAC address lookup" [ref=e672]: + - img [ref=e674] [cursor=pointer]: + - img [ref=e675] + - link "MAC address lookup" [ref=e679] [cursor=pointer]: + - /url: /mac-address-lookup + - menuitem "MAC address generator" [ref=e680]: + - img [ref=e682] [cursor=pointer]: + - img [ref=e683] + - link "MAC address generator" [ref=e687] [cursor=pointer]: + - /url: /mac-address-generator + - menuitem "IPv6 ULA generator" [ref=e688]: + - img [ref=e690] [cursor=pointer]: + - img [ref=e691] + - link "IPv6 ULA generator" [ref=e696] [cursor=pointer]: + - /url: /ipv6-ula-generator + - menuitem "DNS Query" [ref=e697]: + - img [ref=e699] [cursor=pointer]: + - img [ref=e700] + - link "DNS Query" [ref=e706] [cursor=pointer]: + - /url: /dns-query + - generic [ref=e707]: + - generic [ref=e708] [cursor=pointer]: + - img [ref=e710] + - generic [ref=e712]: Math + - menu [ref=e716]: + - menuitem "Math evaluator" [ref=e717]: + - img [ref=e719] [cursor=pointer]: + - img [ref=e720] + - link "Math evaluator" [ref=e724] [cursor=pointer]: + - /url: /math-evaluator + - menuitem "ETA calculator" [ref=e725]: + - img [ref=e727] [cursor=pointer]: + - img [ref=e728] + - link "ETA calculator" [ref=e732] [cursor=pointer]: + - /url: /eta-calculator + - menuitem "Percentage calculator" [ref=e733]: + - img [ref=e735] [cursor=pointer]: + - img [ref=e736] + - link "Percentage calculator" [ref=e741] [cursor=pointer]: + - /url: /percentage-calculator + - generic [ref=e742]: + - generic [ref=e743] [cursor=pointer]: + - img [ref=e745] + - generic [ref=e747]: Measurement + - menu [ref=e751]: + - menuitem "Chronometer" [ref=e752]: + - img [ref=e754] [cursor=pointer]: + - img [ref=e755] + - link "Chronometer" [ref=e757] [cursor=pointer]: + - /url: /chronometer + - menuitem "Temperature converter" [ref=e758]: + - img [ref=e760] [cursor=pointer]: + - img [ref=e761] + - link "Temperature converter" [ref=e764] [cursor=pointer]: + - /url: /temperature-converter + - menuitem "Benchmark builder" [ref=e765]: + - img [ref=e767] [cursor=pointer]: + - img [ref=e768] + - link "Benchmark builder" [ref=e770] [cursor=pointer]: + - /url: /benchmark-builder + - menuitem "Byte unit converter" [ref=e771]: + - img [ref=e773] [cursor=pointer]: + - img [ref=e774] + - link "Byte unit converter" [ref=e781] [cursor=pointer]: + - /url: /byte-unit-converter + - generic [ref=e782]: + - generic [ref=e783] [cursor=pointer]: + - img [ref=e785] + - generic [ref=e787]: Text + - menu [ref=e791]: + - menuitem "Lorem ipsum generator" [ref=e792]: + - img [ref=e794] [cursor=pointer]: + - img [ref=e795] + - link "Lorem ipsum generator" [ref=e797] [cursor=pointer]: + - /url: /lorem-ipsum-generator + - menuitem "Text statistics" [ref=e798]: + - img [ref=e800] [cursor=pointer]: + - img [ref=e801] + - link "Text statistics" [ref=e805] [cursor=pointer]: + - /url: /text-statistics + - menuitem "Emoji picker" [ref=e806]: + - img [ref=e808] [cursor=pointer]: + - img [ref=e809] + - link "Emoji picker" [ref=e813] [cursor=pointer]: + - /url: /emoji-picker + - menuitem "String obfuscator" [ref=e814]: + - img [ref=e816] [cursor=pointer]: + - img [ref=e817] + - link "String obfuscator" [ref=e822] [cursor=pointer]: + - /url: /string-obfuscator + - menuitem "Text diff" [ref=e823]: + - img [ref=e825] [cursor=pointer]: + - img [ref=e826] + - link "Text diff" [ref=e830] [cursor=pointer]: + - /url: /text-diff + - menuitem "Numeronym generator" [ref=e831]: + - img [ref=e833] [cursor=pointer]: + - img [ref=e834]: + - generic "n7m" [ref=e835] + - link "Numeronym generator" [ref=e836] [cursor=pointer]: + - /url: /numeronym-generator + - menuitem "ASCII Art Text Generator" [ref=e837]: + - img [ref=e839] [cursor=pointer]: + - img [ref=e840] + - link "ASCII Art Text Generator" [ref=e843] [cursor=pointer]: + - /url: /ascii-text-drawer + - generic [ref=e844]: + - generic [ref=e845] [cursor=pointer]: + - img [ref=e847] + - generic [ref=e849]: Data + - menu [ref=e853]: + - menuitem "Phone parser and formatter" [ref=e854]: + - img [ref=e856] [cursor=pointer]: + - img [ref=e857] + - link "Phone parser and formatter" [ref=e859] [cursor=pointer]: + - /url: /phone-parser-and-formatter + - menuitem "IBAN validator and parser" [ref=e860]: + - img [ref=e862] [cursor=pointer]: + - img [ref=e863] + - link "IBAN validator and parser" [ref=e865] [cursor=pointer]: + - /url: /iban-validator-and-parser + - generic [ref=e866]: + - generic [ref=e867]: + - text: IT-Tools + - link "v2024.10.22-7ca5933" [ref=e868] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools/tree/v2024.10.22-7ca5933 + - generic [ref=e869]: + - text: © 2026 + - link "Corentin Thomasset" [ref=e870] [cursor=pointer]: + - /url: https://corentin.tech?utm_source=it-tools&utm_medium=footer + - generic [ref=e873]: + - generic [ref=e874]: + - button "Toggle menu" [ref=e875] [cursor=pointer]: + - img [ref=e876]: + - img [ref=e877] + - link "Home" [ref=e881] [cursor=pointer]: + - /url: / + - img [ref=e882]: + - img [ref=e883] + - link "UI Lib" [ref=e890] [cursor=pointer]: + - /url: /c-lib + - img [ref=e891] + - button "Search Cmd + K" [ref=e894] [cursor=pointer]: + - generic [ref=e895]: + - img [ref=e896] + - text: Search + - generic [ref=e898]: Cmd + K + - generic [ref=e901] [cursor=pointer]: + - generic [ref=e902]: English + - img [ref=e903] + - generic [ref=e905]: + - link "IT-Tools GitHub repository" [ref=e908] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools + - img [ref=e909]: + - img [ref=e910] + - link "IT Tools X account" [ref=e914] [cursor=pointer]: + - /url: https://x.com/ittoolsdottech + - img [ref=e915]: + - img [ref=e916] + - link "About" [ref=e921] [cursor=pointer]: + - /url: /about + - img [ref=e922]: + - img [ref=e923] + - button "Toggle dark/light mode" [ref=e928] [cursor=pointer]: + - img [ref=e929]: + - img [ref=e930] + - link "Buy me a coffee" [ref=e934] [cursor=pointer]: + - /url: https://www.buymeacoffee.com/cthmsst + - text: Buy me a coffee + - img [ref=e935]: + - img [ref=e936] + - generic [ref=e939]: + - generic [ref=e940]: + - heading "DNS Query" [level=1] [ref=e941] + - button [ref=e945] [cursor=pointer]: + - img [ref=e946] + - generic [ref=e949]: Query DNS records (A, AAAA, CNAME, MX, TXT, NS, SOA, ...) for any domain name online using Cloudflare DNS. + - generic [ref=e951]: + - generic [ref=e952]: + - generic [ref=e953]: Domain name + - generic [ref=e955]: + - textbox "Domain name" [ref=e956]: + - /placeholder: e.g. example.com + - text: example.com + - button [ref=e957] [cursor=pointer]: + - img [ref=e958] + - generic [ref=e960]: + - generic [ref=e961]: Record type + - generic [ref=e963] [cursor=pointer]: + - generic [ref=e964]: A + - img [ref=e965] + - button "Query DNS" [ref=e968] [cursor=pointer] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-06-12T07-25-13-336Z.yml b/.playwright-mcp/page-2026-06-12T07-25-13-336Z.yml new file mode 100644 index 0000000000..556d4062d6 --- /dev/null +++ b/.playwright-mcp/page-2026-06-12T07-25-13-336Z.yml @@ -0,0 +1,616 @@ +- generic [ref=e5]: + - complementary [ref=e6]: + - link "IT - TOOLS Handy tools for developers" [ref=e7] [cursor=pointer]: + - /url: / + - img [ref=e8] + - generic [ref=e13]: + - generic [ref=e14]: IT - TOOLS + - generic [ref=e16]: Handy tools for developers + - generic [ref=e17]: + - generic [ref=e18]: + - generic [ref=e19] [cursor=pointer]: + - img [ref=e21] + - generic [ref=e23]: Crypto + - menu [ref=e27]: + - menuitem "Token generator" [ref=e28]: + - img [ref=e30] [cursor=pointer]: + - img [ref=e31] + - link "Token generator" [ref=e37] [cursor=pointer]: + - /url: /token-generator + - menuitem "Hash text" [ref=e38]: + - img [ref=e40] [cursor=pointer]: + - img [ref=e41] + - link "Hash text" [ref=e46] [cursor=pointer]: + - /url: /hash-text + - menuitem "Bcrypt" [ref=e47]: + - img [ref=e49] [cursor=pointer]: + - img [ref=e50] + - link "Bcrypt" [ref=e55] [cursor=pointer]: + - /url: /bcrypt + - menuitem "UUIDs generator" [ref=e56]: + - img [ref=e58] [cursor=pointer]: + - img [ref=e59] + - link "UUIDs generator" [ref=e66] [cursor=pointer]: + - /url: /uuid-generator + - menuitem "ULID generator" [ref=e67]: + - img [ref=e69] [cursor=pointer]: + - img [ref=e70] + - link "ULID generator" [ref=e76] [cursor=pointer]: + - /url: /ulid-generator + - menuitem "Encrypt / decrypt text" [ref=e77]: + - img [ref=e79] [cursor=pointer]: + - img [ref=e80] + - link "Encrypt / decrypt text" [ref=e85] [cursor=pointer]: + - /url: /encryption + - menuitem "BIP39 passphrase generator" [ref=e86]: + - img [ref=e88] [cursor=pointer]: + - img [ref=e89] + - link "BIP39 passphrase generator" [ref=e91] [cursor=pointer]: + - /url: /bip39-generator + - menuitem "Hmac generator" [ref=e92]: + - img [ref=e94] [cursor=pointer]: + - img [ref=e95] + - link "Hmac generator" [ref=e97] [cursor=pointer]: + - /url: /hmac-generator + - menuitem "RSA key pair generator" [ref=e98]: + - img [ref=e100] [cursor=pointer]: + - img [ref=e101] + - link "RSA key pair generator" [ref=e106] [cursor=pointer]: + - /url: /rsa-key-pair-generator + - menuitem "Password strength analyser" [ref=e107]: + - img [ref=e109] [cursor=pointer]: + - img [ref=e110] + - link "Password strength analyser" [ref=e112] [cursor=pointer]: + - /url: /password-strength-analyser + - menuitem "PDF signature checker" [ref=e113]: + - img [ref=e115] [cursor=pointer]: + - img [ref=e116] + - link "PDF signature checker" [ref=e118] [cursor=pointer]: + - /url: /pdf-signature-checker + - menuitem "SSL Certificate Parser" [ref=e119]: + - img [ref=e121] [cursor=pointer]: + - img [ref=e122] + - link "SSL Certificate Parser" [ref=e129] [cursor=pointer]: + - /url: /ssl-certificate-parser + - generic [ref=e130]: + - generic [ref=e131] [cursor=pointer]: + - img [ref=e133] + - generic [ref=e135]: Converter + - menu [ref=e139]: + - menuitem "Date-time converter" [ref=e140]: + - img [ref=e142] [cursor=pointer]: + - img [ref=e143] + - link "Date-time converter" [ref=e146] [cursor=pointer]: + - /url: /date-converter + - menuitem "Integer base converter" [ref=e147]: + - img [ref=e149] [cursor=pointer]: + - img [ref=e150] + - link "Integer base converter" [ref=e154] [cursor=pointer]: + - /url: /base-converter + - menuitem "Roman numeral converter" [ref=e155]: + - img [ref=e157] [cursor=pointer]: + - img [ref=e158] + - link "Roman numeral converter" [ref=e162] [cursor=pointer]: + - /url: /roman-numeral-converter + - menuitem "Base64 string encoder/decoder" [ref=e163]: + - img [ref=e165] [cursor=pointer]: + - img [ref=e166] + - link "Base64 string encoder/decoder" [ref=e171] [cursor=pointer]: + - /url: /base64-string-converter + - menuitem "Base64 file converter" [ref=e172]: + - img [ref=e174] [cursor=pointer]: + - img [ref=e175] + - link "Base64 file converter" [ref=e180] [cursor=pointer]: + - /url: /base64-file-converter + - menuitem "Color converter" [ref=e181]: + - img [ref=e183] [cursor=pointer]: + - img [ref=e184] + - link "Color converter" [ref=e190] [cursor=pointer]: + - /url: /color-converter + - menuitem "Case converter" [ref=e191]: + - img [ref=e193] [cursor=pointer]: + - img [ref=e194] + - link "Case converter" [ref=e198] [cursor=pointer]: + - /url: /case-converter + - menuitem "Text to NATO alphabet" [ref=e199]: + - img [ref=e201] [cursor=pointer]: + - img [ref=e202] + - link "Text to NATO alphabet" [ref=e207] [cursor=pointer]: + - /url: /text-to-nato-alphabet + - menuitem "Text to ASCII binary" [ref=e208]: + - img [ref=e210] [cursor=pointer]: + - img [ref=e211] + - link "Text to ASCII binary" [ref=e217] [cursor=pointer]: + - /url: /text-to-binary + - menuitem "Text to Unicode" [ref=e218]: + - img [ref=e220] [cursor=pointer]: + - img [ref=e221] + - link "Text to Unicode" [ref=e224] [cursor=pointer]: + - /url: /text-to-unicode + - menuitem "YAML to JSON converter" [ref=e225]: + - img [ref=e227] [cursor=pointer]: + - img [ref=e228] + - link "YAML to JSON converter" [ref=e230] [cursor=pointer]: + - /url: /yaml-to-json-converter + - menuitem "YAML to TOML" [ref=e231]: + - img [ref=e233] [cursor=pointer]: + - img [ref=e234] + - link "YAML to TOML" [ref=e236] [cursor=pointer]: + - /url: /yaml-to-toml + - menuitem "JSON to YAML converter" [ref=e237]: + - img [ref=e239] [cursor=pointer]: + - img [ref=e240] + - link "JSON to YAML converter" [ref=e244] [cursor=pointer]: + - /url: /json-to-yaml-converter + - menuitem "JSON to TOML" [ref=e245]: + - img [ref=e247] [cursor=pointer]: + - img [ref=e248] + - link "JSON to TOML" [ref=e252] [cursor=pointer]: + - /url: /json-to-toml + - menuitem "List converter" [ref=e253]: + - img [ref=e255] [cursor=pointer]: + - img [ref=e256] + - link "List converter" [ref=e258] [cursor=pointer]: + - /url: /list-converter + - menuitem "TOML to JSON" [ref=e259]: + - img [ref=e261] [cursor=pointer]: + - img [ref=e262] + - link "TOML to JSON" [ref=e264] [cursor=pointer]: + - /url: /toml-to-json + - menuitem "TOML to YAML" [ref=e265]: + - img [ref=e267] [cursor=pointer]: + - img [ref=e268] + - link "TOML to YAML" [ref=e270] [cursor=pointer]: + - /url: /toml-to-yaml + - menuitem "XML to JSON" [ref=e271]: + - img [ref=e273] [cursor=pointer]: + - img [ref=e274] + - link "XML to JSON" [ref=e278] [cursor=pointer]: + - /url: /xml-to-json + - menuitem "JSON to XML" [ref=e279]: + - img [ref=e281] [cursor=pointer]: + - img [ref=e282] + - link "JSON to XML" [ref=e286] [cursor=pointer]: + - /url: /json-to-xml + - menuitem "Markdown to HTML" [ref=e287]: + - img [ref=e289] [cursor=pointer]: + - img [ref=e290] + - link "Markdown to HTML" [ref=e295] [cursor=pointer]: + - /url: /markdown-to-html + - menuitem "HTML to Markdown" [ref=e296]: + - img [ref=e298] [cursor=pointer]: + - img [ref=e299] + - link "HTML to Markdown" [ref=e305] [cursor=pointer]: + - /url: /html-to-markdown + - generic [ref=e306]: + - generic [ref=e307] [cursor=pointer]: + - img [ref=e309] + - generic [ref=e311]: Web + - menu [ref=e315]: + - menuitem "Encode/decode URL-formatted strings" [ref=e316]: + - img [ref=e318] [cursor=pointer]: + - img [ref=e319] + - link "Encode/decode URL-formatted strings" [ref=e323] [cursor=pointer]: + - /url: /url-encoder + - menuitem "Escape HTML entities" [ref=e324]: + - img [ref=e326] [cursor=pointer]: + - img [ref=e327] + - link "Escape HTML entities" [ref=e332] [cursor=pointer]: + - /url: /html-entities + - menuitem "URL parser" [ref=e333]: + - img [ref=e335] [cursor=pointer]: + - img [ref=e336] + - link "URL parser" [ref=e340] [cursor=pointer]: + - /url: /url-parser + - menuitem "Device information" [ref=e341]: + - img [ref=e343] [cursor=pointer]: + - img [ref=e344] + - link "Device information" [ref=e347] [cursor=pointer]: + - /url: /device-information + - menuitem "Basic auth generator" [ref=e348]: + - img [ref=e350] [cursor=pointer]: + - img [ref=e351] + - link "Basic auth generator" [ref=e353] [cursor=pointer]: + - /url: /basic-auth-generator + - menuitem "Open graph meta generator" [ref=e354]: + - img [ref=e356] [cursor=pointer]: + - img [ref=e357] + - link "Open graph meta generator" [ref=e361] [cursor=pointer]: + - /url: /og-meta-generator + - menuitem "OTP code generator" [ref=e362]: + - img [ref=e364] [cursor=pointer]: + - img [ref=e365] + - link "OTP code generator" [ref=e368] [cursor=pointer]: + - /url: /otp-generator + - menuitem "MIME types" [ref=e369]: + - img [ref=e371] [cursor=pointer]: + - img [ref=e372] + - link "MIME types" [ref=e377] [cursor=pointer]: + - /url: /mime-types + - menuitem "JWT parser" [ref=e378]: + - img [ref=e380] [cursor=pointer]: + - img [ref=e381] + - link "JWT parser" [ref=e387] [cursor=pointer]: + - /url: /jwt-parser + - menuitem "Keycode info" [ref=e388]: + - img [ref=e390] [cursor=pointer]: + - img [ref=e391] + - link "Keycode info" [ref=e394] [cursor=pointer]: + - /url: /keycode-info + - menuitem "Slugify string" [ref=e395]: + - img [ref=e397] [cursor=pointer]: + - img [ref=e398] + - link "Slugify string" [ref=e400] [cursor=pointer]: + - /url: /slugify-string + - menuitem "HTML WYSIWYG editor" [ref=e401]: + - img [ref=e403] [cursor=pointer]: + - img [ref=e404] + - link "HTML WYSIWYG editor" [ref=e409] [cursor=pointer]: + - /url: /html-wysiwyg-editor + - menuitem "User-agent parser" [ref=e410]: + - img [ref=e412] [cursor=pointer]: + - img [ref=e413] + - link "User-agent parser" [ref=e416] [cursor=pointer]: + - /url: /user-agent-parser + - menuitem "HTTP status codes" [ref=e417]: + - img [ref=e419] [cursor=pointer]: + - img [ref=e420] + - link "HTTP status codes" [ref=e422] [cursor=pointer]: + - /url: /http-status-codes + - menuitem "JSON diff" [ref=e423]: + - img [ref=e425] [cursor=pointer]: + - img [ref=e426] + - link "JSON diff" [ref=e428] [cursor=pointer]: + - /url: /json-diff + - menuitem "Outlook Safelink decoder" [ref=e429]: + - img [ref=e431] [cursor=pointer]: + - img [ref=e432] + - link "Outlook Safelink decoder" [ref=e436] [cursor=pointer]: + - /url: /safelink-decoder + - generic [ref=e437]: + - generic [ref=e438] [cursor=pointer]: + - img [ref=e440] + - generic [ref=e442]: Images & Videos + - menu [ref=e446]: + - menuitem "QR Code generator" [ref=e447]: + - img [ref=e449] [cursor=pointer]: + - img [ref=e450] + - link "QR Code generator" [ref=e455] [cursor=pointer]: + - /url: /qrcode-generator + - menuitem "WiFi QR Code generator" [ref=e456]: + - img [ref=e458] [cursor=pointer]: + - img [ref=e459] + - link "WiFi QR Code generator" [ref=e464] [cursor=pointer]: + - /url: /wifi-qrcode-generator + - menuitem "SVG placeholder generator" [ref=e465]: + - img [ref=e467] [cursor=pointer]: + - img [ref=e468] + - link "SVG placeholder generator" [ref=e470] [cursor=pointer]: + - /url: /svg-placeholder-generator + - menuitem "Camera recorder" [ref=e471]: + - img [ref=e473] [cursor=pointer]: + - img [ref=e474] + - link "Camera recorder" [ref=e478] [cursor=pointer]: + - /url: /camera-recorder + - generic [ref=e479]: + - generic [ref=e480] [cursor=pointer]: + - img [ref=e482] + - generic [ref=e484]: Development + - menu [ref=e488]: + - menuitem "Git cheatsheet" [ref=e489]: + - img [ref=e491] [cursor=pointer]: + - img [ref=e492] + - link "Git cheatsheet" [ref=e500] [cursor=pointer]: + - /url: /git-memo + - menuitem "Random port generator" [ref=e501]: + - img [ref=e503] [cursor=pointer]: + - img [ref=e504] + - link "Random port generator" [ref=e508] [cursor=pointer]: + - /url: /random-port-generator + - menuitem "Crontab generator" [ref=e509]: + - img [ref=e511] [cursor=pointer]: + - img [ref=e512] + - link "Crontab generator" [ref=e518] [cursor=pointer]: + - /url: /crontab-generator + - menuitem "JSON prettify and format" [ref=e519]: + - img [ref=e521] [cursor=pointer]: + - img [ref=e522] + - link "JSON prettify and format" [ref=e526] [cursor=pointer]: + - /url: /json-prettify + - menuitem "JSON minify" [ref=e527]: + - img [ref=e529] [cursor=pointer]: + - img [ref=e530] + - link "JSON minify" [ref=e534] [cursor=pointer]: + - /url: /json-minify + - menuitem "JSON to CSV" [ref=e535]: + - img [ref=e537] [cursor=pointer]: + - img [ref=e538] + - link "JSON to CSV" [ref=e540] [cursor=pointer]: + - /url: /json-to-csv + - menuitem "SQL prettify and format" [ref=e541]: + - img [ref=e543] [cursor=pointer]: + - img [ref=e544] + - link "SQL prettify and format" [ref=e549] [cursor=pointer]: + - /url: /sql-prettify + - menuitem "Chmod calculator" [ref=e550]: + - img [ref=e552] [cursor=pointer]: + - img [ref=e553] + - link "Chmod calculator" [ref=e557] [cursor=pointer]: + - /url: /chmod-calculator + - menuitem "Docker run to Docker compose converter" [ref=e558]: + - img [ref=e560] [cursor=pointer]: + - img [ref=e561] + - link "Docker run to Docker compose converter" [ref=e571] [cursor=pointer]: + - /url: /docker-run-to-docker-compose-converter + - menuitem "XML formatter" [ref=e572]: + - img [ref=e574] [cursor=pointer]: + - img [ref=e575] + - link "XML formatter" [ref=e580] [cursor=pointer]: + - /url: /xml-formatter + - menuitem "YAML prettify and format" [ref=e581]: + - img [ref=e583] [cursor=pointer]: + - img [ref=e584] + - link "YAML prettify and format" [ref=e586] [cursor=pointer]: + - /url: /yaml-prettify + - menuitem "Email normalizer" [ref=e587]: + - img [ref=e589] [cursor=pointer]: + - img [ref=e590] + - link "Email normalizer" [ref=e594] [cursor=pointer]: + - /url: /email-normalizer + - menuitem "Regex Tester" [ref=e595]: + - img [ref=e597] [cursor=pointer]: + - img [ref=e598] + - link "Regex Tester" [ref=e603] [cursor=pointer]: + - /url: /regex-tester + - menuitem "Regex cheatsheet" [ref=e604]: + - img [ref=e606] [cursor=pointer]: + - img [ref=e607] + - link "Regex cheatsheet" [ref=e612] [cursor=pointer]: + - /url: /regex-memo + - menuitem "cURL to Code" [ref=e613]: + - img [ref=e615] [cursor=pointer]: + - img [ref=e616] + - link "cURL to Code" [ref=e620] [cursor=pointer]: + - /url: /curl-to-code + - menuitem "JSON to TypeScript/Go" [ref=e621]: + - img [ref=e623] [cursor=pointer]: + - img [ref=e624] + - link "JSON to TypeScript/Go" [ref=e629] [cursor=pointer]: + - /url: /json-to-types + - menuitem "CSS/JS Prettify & Minify" [ref=e630]: + - img [ref=e632] [cursor=pointer]: + - img [ref=e633] + - link "CSS/JS Prettify & Minify" [ref=e639] [cursor=pointer]: + - /url: /css-js-prettify-minify + - generic [ref=e640]: + - generic [ref=e641] [cursor=pointer]: + - img [ref=e643] + - generic [ref=e645]: Network + - menu [ref=e649]: + - menuitem "IPv4 subnet calculator" [ref=e650]: + - img [ref=e652] [cursor=pointer]: + - img [ref=e653] + - link "IPv4 subnet calculator" [ref=e655] [cursor=pointer]: + - /url: /ipv4-subnet-calculator + - menuitem "IPv4 address converter" [ref=e656]: + - img [ref=e658] [cursor=pointer]: + - img [ref=e659] + - link "IPv4 address converter" [ref=e665] [cursor=pointer]: + - /url: /ipv4-address-converter + - menuitem "IPv4 range expander" [ref=e666]: + - img [ref=e668] [cursor=pointer]: + - img [ref=e669] + - link "IPv4 range expander" [ref=e671] [cursor=pointer]: + - /url: /ipv4-range-expander + - menuitem "MAC address lookup" [ref=e672]: + - img [ref=e674] [cursor=pointer]: + - img [ref=e675] + - link "MAC address lookup" [ref=e679] [cursor=pointer]: + - /url: /mac-address-lookup + - menuitem "MAC address generator" [ref=e680]: + - img [ref=e682] [cursor=pointer]: + - img [ref=e683] + - link "MAC address generator" [ref=e687] [cursor=pointer]: + - /url: /mac-address-generator + - menuitem "IPv6 ULA generator" [ref=e688]: + - img [ref=e690] [cursor=pointer]: + - img [ref=e691] + - link "IPv6 ULA generator" [ref=e696] [cursor=pointer]: + - /url: /ipv6-ula-generator + - menuitem "DNS Query" [ref=e697]: + - img [ref=e699] [cursor=pointer]: + - img [ref=e700] + - link "DNS Query" [ref=e706] [cursor=pointer]: + - /url: /dns-query + - generic [ref=e707]: + - generic [ref=e708] [cursor=pointer]: + - img [ref=e710] + - generic [ref=e712]: Math + - menu [ref=e716]: + - menuitem "Math evaluator" [ref=e717]: + - img [ref=e719] [cursor=pointer]: + - img [ref=e720] + - link "Math evaluator" [ref=e724] [cursor=pointer]: + - /url: /math-evaluator + - menuitem "ETA calculator" [ref=e725]: + - img [ref=e727] [cursor=pointer]: + - img [ref=e728] + - link "ETA calculator" [ref=e732] [cursor=pointer]: + - /url: /eta-calculator + - menuitem "Percentage calculator" [ref=e733]: + - img [ref=e735] [cursor=pointer]: + - img [ref=e736] + - link "Percentage calculator" [ref=e741] [cursor=pointer]: + - /url: /percentage-calculator + - generic [ref=e742]: + - generic [ref=e743] [cursor=pointer]: + - img [ref=e745] + - generic [ref=e747]: Measurement + - menu [ref=e751]: + - menuitem "Chronometer" [ref=e752]: + - img [ref=e754] [cursor=pointer]: + - img [ref=e755] + - link "Chronometer" [ref=e757] [cursor=pointer]: + - /url: /chronometer + - menuitem "Temperature converter" [ref=e758]: + - img [ref=e760] [cursor=pointer]: + - img [ref=e761] + - link "Temperature converter" [ref=e764] [cursor=pointer]: + - /url: /temperature-converter + - menuitem "Benchmark builder" [ref=e765]: + - img [ref=e767] [cursor=pointer]: + - img [ref=e768] + - link "Benchmark builder" [ref=e770] [cursor=pointer]: + - /url: /benchmark-builder + - menuitem "Byte unit converter" [ref=e771]: + - img [ref=e773] [cursor=pointer]: + - img [ref=e774] + - link "Byte unit converter" [ref=e781] [cursor=pointer]: + - /url: /byte-unit-converter + - generic [ref=e782]: + - generic [ref=e783] [cursor=pointer]: + - img [ref=e785] + - generic [ref=e787]: Text + - menu [ref=e791]: + - menuitem "Lorem ipsum generator" [ref=e792]: + - img [ref=e794] [cursor=pointer]: + - img [ref=e795] + - link "Lorem ipsum generator" [ref=e797] [cursor=pointer]: + - /url: /lorem-ipsum-generator + - menuitem "Text statistics" [ref=e798]: + - img [ref=e800] [cursor=pointer]: + - img [ref=e801] + - link "Text statistics" [ref=e805] [cursor=pointer]: + - /url: /text-statistics + - menuitem "Emoji picker" [ref=e806]: + - img [ref=e808] [cursor=pointer]: + - img [ref=e809] + - link "Emoji picker" [ref=e813] [cursor=pointer]: + - /url: /emoji-picker + - menuitem "String obfuscator" [ref=e814]: + - img [ref=e816] [cursor=pointer]: + - img [ref=e817] + - link "String obfuscator" [ref=e822] [cursor=pointer]: + - /url: /string-obfuscator + - menuitem "Text diff" [ref=e823]: + - img [ref=e825] [cursor=pointer]: + - img [ref=e826] + - link "Text diff" [ref=e830] [cursor=pointer]: + - /url: /text-diff + - menuitem "Numeronym generator" [ref=e831]: + - img [ref=e833] [cursor=pointer]: + - img [ref=e834]: + - generic "n7m" [ref=e835] + - link "Numeronym generator" [ref=e836] [cursor=pointer]: + - /url: /numeronym-generator + - menuitem "ASCII Art Text Generator" [ref=e837]: + - img [ref=e839] [cursor=pointer]: + - img [ref=e840] + - link "ASCII Art Text Generator" [ref=e843] [cursor=pointer]: + - /url: /ascii-text-drawer + - generic [ref=e844]: + - generic [ref=e845] [cursor=pointer]: + - img [ref=e847] + - generic [ref=e849]: Data + - menu [ref=e853]: + - menuitem "Phone parser and formatter" [ref=e854]: + - img [ref=e856] [cursor=pointer]: + - img [ref=e857] + - link "Phone parser and formatter" [ref=e859] [cursor=pointer]: + - /url: /phone-parser-and-formatter + - menuitem "IBAN validator and parser" [ref=e860]: + - img [ref=e862] [cursor=pointer]: + - img [ref=e863] + - link "IBAN validator and parser" [ref=e865] [cursor=pointer]: + - /url: /iban-validator-and-parser + - generic [ref=e866]: + - generic [ref=e867]: + - text: IT-Tools + - link "v2024.10.22-7ca5933" [ref=e868] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools/tree/v2024.10.22-7ca5933 + - generic [ref=e869]: + - text: © 2026 + - link "Corentin Thomasset" [ref=e870] [cursor=pointer]: + - /url: https://corentin.tech?utm_source=it-tools&utm_medium=footer + - generic [ref=e873]: + - generic [ref=e874]: + - button "Toggle menu" [ref=e875] [cursor=pointer]: + - img [ref=e876]: + - img [ref=e877] + - link "Home" [ref=e881] [cursor=pointer]: + - /url: / + - img [ref=e882]: + - img [ref=e883] + - link "UI Lib" [ref=e890] [cursor=pointer]: + - /url: /c-lib + - img [ref=e891] + - button "Search Cmd + K" [ref=e894] [cursor=pointer]: + - generic [ref=e895]: + - img [ref=e896] + - text: Search + - generic [ref=e898]: Cmd + K + - generic [ref=e901] [cursor=pointer]: + - generic [ref=e902]: English + - img [ref=e903] + - generic [ref=e905]: + - link "IT-Tools GitHub repository" [ref=e908] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools + - img [ref=e909]: + - img [ref=e910] + - link "IT Tools X account" [ref=e914] [cursor=pointer]: + - /url: https://x.com/ittoolsdottech + - img [ref=e915]: + - img [ref=e916] + - link "About" [ref=e921] [cursor=pointer]: + - /url: /about + - img [ref=e922]: + - img [ref=e923] + - button "Toggle dark/light mode" [ref=e928] [cursor=pointer]: + - img [ref=e929]: + - img [ref=e930] + - link "Buy me a coffee" [ref=e934] [cursor=pointer]: + - /url: https://www.buymeacoffee.com/cthmsst + - text: Buy me a coffee + - img [ref=e935]: + - img [ref=e936] + - generic [ref=e939]: + - generic [ref=e940]: + - heading "DNS Query" [level=1] [ref=e941] + - button [ref=e945] [cursor=pointer]: + - img [ref=e946] + - generic [ref=e949]: Query DNS records (A, AAAA, CNAME, MX, TXT, NS, SOA, ...) for any domain name online using Cloudflare DNS. + - generic [ref=e951]: + - generic [ref=e952]: + - generic [ref=e953]: Domain name + - generic [ref=e955]: + - textbox "Domain name" [ref=e956]: + - /placeholder: e.g. example.com + - text: example.com + - button [ref=e957] [cursor=pointer]: + - img [ref=e958] + - generic [ref=e960]: + - generic [ref=e961]: Record type + - generic [ref=e963] [cursor=pointer]: + - generic [ref=e964]: A + - img [ref=e965] + - button "Query DNS" [active] [ref=e968] [cursor=pointer] + - generic [ref=e969]: + - generic [ref=e970]: + - generic [ref=e971]: "Status:" + - generic [ref=e972]: NOERROR + - table [ref=e973]: + - rowgroup [ref=e974]: + - row "Name TTL Data" [ref=e975]: + - columnheader "Name" [ref=e976] + - columnheader "TTL" [ref=e977] + - columnheader "Data" [ref=e978] + - rowgroup [ref=e979]: + - row "example.com 130s 172.66.147.243" [ref=e980]: + - cell "example.com" [ref=e981] + - cell "130s" [ref=e982] + - cell "172.66.147.243" [ref=e983] + - row "example.com 130s 104.20.23.154" [ref=e984]: + - cell "example.com" [ref=e985] + - cell "130s" [ref=e986] + - cell "104.20.23.154" [ref=e987] + - button "Copy results" [ref=e989] [cursor=pointer] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-06-12T07-25-19-177Z.yml b/.playwright-mcp/page-2026-06-12T07-25-19-177Z.yml new file mode 100644 index 0000000000..ab899c10fa --- /dev/null +++ b/.playwright-mcp/page-2026-06-12T07-25-19-177Z.yml @@ -0,0 +1,596 @@ +- generic [ref=e5]: + - complementary [ref=e6]: + - link "IT - TOOLS Handy tools for developers" [ref=e7] [cursor=pointer]: + - /url: / + - img [ref=e8] + - generic [ref=e13]: + - generic [ref=e14]: IT - TOOLS + - generic [ref=e16]: Handy tools for developers + - generic [ref=e17]: + - generic [ref=e18]: + - generic [ref=e19] [cursor=pointer]: + - img [ref=e21] + - generic [ref=e23]: Crypto + - menu [ref=e27]: + - menuitem "Token generator" [ref=e28]: + - img [ref=e30] [cursor=pointer]: + - img [ref=e31] + - link "Token generator" [ref=e37] [cursor=pointer]: + - /url: /token-generator + - menuitem "Hash text" [ref=e38]: + - img [ref=e40] [cursor=pointer]: + - img [ref=e41] + - link "Hash text" [ref=e46] [cursor=pointer]: + - /url: /hash-text + - menuitem "Bcrypt" [ref=e47]: + - img [ref=e49] [cursor=pointer]: + - img [ref=e50] + - link "Bcrypt" [ref=e55] [cursor=pointer]: + - /url: /bcrypt + - menuitem "UUIDs generator" [ref=e56]: + - img [ref=e58] [cursor=pointer]: + - img [ref=e59] + - link "UUIDs generator" [ref=e66] [cursor=pointer]: + - /url: /uuid-generator + - menuitem "ULID generator" [ref=e67]: + - img [ref=e69] [cursor=pointer]: + - img [ref=e70] + - link "ULID generator" [ref=e76] [cursor=pointer]: + - /url: /ulid-generator + - menuitem "Encrypt / decrypt text" [ref=e77]: + - img [ref=e79] [cursor=pointer]: + - img [ref=e80] + - link "Encrypt / decrypt text" [ref=e85] [cursor=pointer]: + - /url: /encryption + - menuitem "BIP39 passphrase generator" [ref=e86]: + - img [ref=e88] [cursor=pointer]: + - img [ref=e89] + - link "BIP39 passphrase generator" [ref=e91] [cursor=pointer]: + - /url: /bip39-generator + - menuitem "Hmac generator" [ref=e92]: + - img [ref=e94] [cursor=pointer]: + - img [ref=e95] + - link "Hmac generator" [ref=e97] [cursor=pointer]: + - /url: /hmac-generator + - menuitem "RSA key pair generator" [ref=e98]: + - img [ref=e100] [cursor=pointer]: + - img [ref=e101] + - link "RSA key pair generator" [ref=e106] [cursor=pointer]: + - /url: /rsa-key-pair-generator + - menuitem "Password strength analyser" [ref=e107]: + - img [ref=e109] [cursor=pointer]: + - img [ref=e110] + - link "Password strength analyser" [ref=e112] [cursor=pointer]: + - /url: /password-strength-analyser + - menuitem "PDF signature checker" [ref=e113]: + - img [ref=e115] [cursor=pointer]: + - img [ref=e116] + - link "PDF signature checker" [ref=e118] [cursor=pointer]: + - /url: /pdf-signature-checker + - menuitem "SSL Certificate Parser" [ref=e119]: + - img [ref=e121] [cursor=pointer]: + - img [ref=e122] + - link "SSL Certificate Parser" [ref=e129] [cursor=pointer]: + - /url: /ssl-certificate-parser + - generic [ref=e130]: + - generic [ref=e131] [cursor=pointer]: + - img [ref=e133] + - generic [ref=e135]: Converter + - menu [ref=e139]: + - menuitem "Date-time converter" [ref=e140]: + - img [ref=e142] [cursor=pointer]: + - img [ref=e143] + - link "Date-time converter" [ref=e146] [cursor=pointer]: + - /url: /date-converter + - menuitem "Integer base converter" [ref=e147]: + - img [ref=e149] [cursor=pointer]: + - img [ref=e150] + - link "Integer base converter" [ref=e154] [cursor=pointer]: + - /url: /base-converter + - menuitem "Roman numeral converter" [ref=e155]: + - img [ref=e157] [cursor=pointer]: + - img [ref=e158] + - link "Roman numeral converter" [ref=e162] [cursor=pointer]: + - /url: /roman-numeral-converter + - menuitem "Base64 string encoder/decoder" [ref=e163]: + - img [ref=e165] [cursor=pointer]: + - img [ref=e166] + - link "Base64 string encoder/decoder" [ref=e171] [cursor=pointer]: + - /url: /base64-string-converter + - menuitem "Base64 file converter" [ref=e172]: + - img [ref=e174] [cursor=pointer]: + - img [ref=e175] + - link "Base64 file converter" [ref=e180] [cursor=pointer]: + - /url: /base64-file-converter + - menuitem "Color converter" [ref=e181]: + - img [ref=e183] [cursor=pointer]: + - img [ref=e184] + - link "Color converter" [ref=e190] [cursor=pointer]: + - /url: /color-converter + - menuitem "Case converter" [ref=e191]: + - img [ref=e193] [cursor=pointer]: + - img [ref=e194] + - link "Case converter" [ref=e198] [cursor=pointer]: + - /url: /case-converter + - menuitem "Text to NATO alphabet" [ref=e199]: + - img [ref=e201] [cursor=pointer]: + - img [ref=e202] + - link "Text to NATO alphabet" [ref=e207] [cursor=pointer]: + - /url: /text-to-nato-alphabet + - menuitem "Text to ASCII binary" [ref=e208]: + - img [ref=e210] [cursor=pointer]: + - img [ref=e211] + - link "Text to ASCII binary" [ref=e217] [cursor=pointer]: + - /url: /text-to-binary + - menuitem "Text to Unicode" [ref=e218]: + - img [ref=e220] [cursor=pointer]: + - img [ref=e221] + - link "Text to Unicode" [ref=e224] [cursor=pointer]: + - /url: /text-to-unicode + - menuitem "YAML to JSON converter" [ref=e225]: + - img [ref=e227] [cursor=pointer]: + - img [ref=e228] + - link "YAML to JSON converter" [ref=e230] [cursor=pointer]: + - /url: /yaml-to-json-converter + - menuitem "YAML to TOML" [ref=e231]: + - img [ref=e233] [cursor=pointer]: + - img [ref=e234] + - link "YAML to TOML" [ref=e236] [cursor=pointer]: + - /url: /yaml-to-toml + - menuitem "JSON to YAML converter" [ref=e237]: + - img [ref=e239] [cursor=pointer]: + - img [ref=e240] + - link "JSON to YAML converter" [ref=e244] [cursor=pointer]: + - /url: /json-to-yaml-converter + - menuitem "JSON to TOML" [ref=e245]: + - img [ref=e247] [cursor=pointer]: + - img [ref=e248] + - link "JSON to TOML" [ref=e252] [cursor=pointer]: + - /url: /json-to-toml + - menuitem "List converter" [ref=e253]: + - img [ref=e255] [cursor=pointer]: + - img [ref=e256] + - link "List converter" [ref=e258] [cursor=pointer]: + - /url: /list-converter + - menuitem "TOML to JSON" [ref=e259]: + - img [ref=e261] [cursor=pointer]: + - img [ref=e262] + - link "TOML to JSON" [ref=e264] [cursor=pointer]: + - /url: /toml-to-json + - menuitem "TOML to YAML" [ref=e265]: + - img [ref=e267] [cursor=pointer]: + - img [ref=e268] + - link "TOML to YAML" [ref=e270] [cursor=pointer]: + - /url: /toml-to-yaml + - menuitem "XML to JSON" [ref=e271]: + - img [ref=e273] [cursor=pointer]: + - img [ref=e274] + - link "XML to JSON" [ref=e278] [cursor=pointer]: + - /url: /xml-to-json + - menuitem "JSON to XML" [ref=e279]: + - img [ref=e281] [cursor=pointer]: + - img [ref=e282] + - link "JSON to XML" [ref=e286] [cursor=pointer]: + - /url: /json-to-xml + - menuitem "Markdown to HTML" [ref=e287]: + - img [ref=e289] [cursor=pointer]: + - img [ref=e290] + - link "Markdown to HTML" [ref=e295] [cursor=pointer]: + - /url: /markdown-to-html + - menuitem "HTML to Markdown" [ref=e296]: + - img [ref=e298] [cursor=pointer]: + - img [ref=e299] + - link "HTML to Markdown" [ref=e305] [cursor=pointer]: + - /url: /html-to-markdown + - generic [ref=e306]: + - generic [ref=e307] [cursor=pointer]: + - img [ref=e309] + - generic [ref=e311]: Web + - menu [ref=e315]: + - menuitem "Encode/decode URL-formatted strings" [ref=e316]: + - img [ref=e318] [cursor=pointer]: + - img [ref=e319] + - link "Encode/decode URL-formatted strings" [ref=e323] [cursor=pointer]: + - /url: /url-encoder + - menuitem "Escape HTML entities" [ref=e324]: + - img [ref=e326] [cursor=pointer]: + - img [ref=e327] + - link "Escape HTML entities" [ref=e332] [cursor=pointer]: + - /url: /html-entities + - menuitem "URL parser" [ref=e333]: + - img [ref=e335] [cursor=pointer]: + - img [ref=e336] + - link "URL parser" [ref=e340] [cursor=pointer]: + - /url: /url-parser + - menuitem "Device information" [ref=e341]: + - img [ref=e343] [cursor=pointer]: + - img [ref=e344] + - link "Device information" [ref=e347] [cursor=pointer]: + - /url: /device-information + - menuitem "Basic auth generator" [ref=e348]: + - img [ref=e350] [cursor=pointer]: + - img [ref=e351] + - link "Basic auth generator" [ref=e353] [cursor=pointer]: + - /url: /basic-auth-generator + - menuitem "Open graph meta generator" [ref=e354]: + - img [ref=e356] [cursor=pointer]: + - img [ref=e357] + - link "Open graph meta generator" [ref=e361] [cursor=pointer]: + - /url: /og-meta-generator + - menuitem "OTP code generator" [ref=e362]: + - img [ref=e364] [cursor=pointer]: + - img [ref=e365] + - link "OTP code generator" [ref=e368] [cursor=pointer]: + - /url: /otp-generator + - menuitem "MIME types" [ref=e369]: + - img [ref=e371] [cursor=pointer]: + - img [ref=e372] + - link "MIME types" [ref=e377] [cursor=pointer]: + - /url: /mime-types + - menuitem "JWT parser" [ref=e378]: + - img [ref=e380] [cursor=pointer]: + - img [ref=e381] + - link "JWT parser" [ref=e387] [cursor=pointer]: + - /url: /jwt-parser + - menuitem "Keycode info" [ref=e388]: + - img [ref=e390] [cursor=pointer]: + - img [ref=e391] + - link "Keycode info" [ref=e394] [cursor=pointer]: + - /url: /keycode-info + - menuitem "Slugify string" [ref=e395]: + - img [ref=e397] [cursor=pointer]: + - img [ref=e398] + - link "Slugify string" [ref=e400] [cursor=pointer]: + - /url: /slugify-string + - menuitem "HTML WYSIWYG editor" [ref=e401]: + - img [ref=e403] [cursor=pointer]: + - img [ref=e404] + - link "HTML WYSIWYG editor" [ref=e409] [cursor=pointer]: + - /url: /html-wysiwyg-editor + - menuitem "User-agent parser" [ref=e410]: + - img [ref=e412] [cursor=pointer]: + - img [ref=e413] + - link "User-agent parser" [ref=e416] [cursor=pointer]: + - /url: /user-agent-parser + - menuitem "HTTP status codes" [ref=e417]: + - img [ref=e419] [cursor=pointer]: + - img [ref=e420] + - link "HTTP status codes" [ref=e422] [cursor=pointer]: + - /url: /http-status-codes + - menuitem "JSON diff" [ref=e423]: + - img [ref=e425] [cursor=pointer]: + - img [ref=e426] + - link "JSON diff" [ref=e428] [cursor=pointer]: + - /url: /json-diff + - menuitem "Outlook Safelink decoder" [ref=e429]: + - img [ref=e431] [cursor=pointer]: + - img [ref=e432] + - link "Outlook Safelink decoder" [ref=e436] [cursor=pointer]: + - /url: /safelink-decoder + - generic [ref=e437]: + - generic [ref=e438] [cursor=pointer]: + - img [ref=e440] + - generic [ref=e442]: Images & Videos + - menu [ref=e446]: + - menuitem "QR Code generator" [ref=e447]: + - img [ref=e449] [cursor=pointer]: + - img [ref=e450] + - link "QR Code generator" [ref=e455] [cursor=pointer]: + - /url: /qrcode-generator + - menuitem "WiFi QR Code generator" [ref=e456]: + - img [ref=e458] [cursor=pointer]: + - img [ref=e459] + - link "WiFi QR Code generator" [ref=e464] [cursor=pointer]: + - /url: /wifi-qrcode-generator + - menuitem "SVG placeholder generator" [ref=e465]: + - img [ref=e467] [cursor=pointer]: + - img [ref=e468] + - link "SVG placeholder generator" [ref=e470] [cursor=pointer]: + - /url: /svg-placeholder-generator + - menuitem "Camera recorder" [ref=e471]: + - img [ref=e473] [cursor=pointer]: + - img [ref=e474] + - link "Camera recorder" [ref=e478] [cursor=pointer]: + - /url: /camera-recorder + - generic [ref=e479]: + - generic [ref=e480] [cursor=pointer]: + - img [ref=e482] + - generic [ref=e484]: Development + - menu [ref=e488]: + - menuitem "Git cheatsheet" [ref=e489]: + - img [ref=e491] [cursor=pointer]: + - img [ref=e492] + - link "Git cheatsheet" [ref=e500] [cursor=pointer]: + - /url: /git-memo + - menuitem "Random port generator" [ref=e501]: + - img [ref=e503] [cursor=pointer]: + - img [ref=e504] + - link "Random port generator" [ref=e508] [cursor=pointer]: + - /url: /random-port-generator + - menuitem "Crontab generator" [ref=e509]: + - img [ref=e511] [cursor=pointer]: + - img [ref=e512] + - link "Crontab generator" [ref=e518] [cursor=pointer]: + - /url: /crontab-generator + - menuitem "JSON prettify and format" [ref=e519]: + - img [ref=e521] [cursor=pointer]: + - img [ref=e522] + - link "JSON prettify and format" [ref=e526] [cursor=pointer]: + - /url: /json-prettify + - menuitem "JSON minify" [ref=e527]: + - img [ref=e529] [cursor=pointer]: + - img [ref=e530] + - link "JSON minify" [ref=e534] [cursor=pointer]: + - /url: /json-minify + - menuitem "JSON to CSV" [ref=e535]: + - img [ref=e537] [cursor=pointer]: + - img [ref=e538] + - link "JSON to CSV" [ref=e540] [cursor=pointer]: + - /url: /json-to-csv + - menuitem "SQL prettify and format" [ref=e541]: + - img [ref=e543] [cursor=pointer]: + - img [ref=e544] + - link "SQL prettify and format" [ref=e549] [cursor=pointer]: + - /url: /sql-prettify + - menuitem "Chmod calculator" [ref=e550]: + - img [ref=e552] [cursor=pointer]: + - img [ref=e553] + - link "Chmod calculator" [ref=e557] [cursor=pointer]: + - /url: /chmod-calculator + - menuitem "Docker run to Docker compose converter" [ref=e558]: + - img [ref=e560] [cursor=pointer]: + - img [ref=e561] + - link "Docker run to Docker compose converter" [ref=e571] [cursor=pointer]: + - /url: /docker-run-to-docker-compose-converter + - menuitem "XML formatter" [ref=e572]: + - img [ref=e574] [cursor=pointer]: + - img [ref=e575] + - link "XML formatter" [ref=e580] [cursor=pointer]: + - /url: /xml-formatter + - menuitem "YAML prettify and format" [ref=e581]: + - img [ref=e583] [cursor=pointer]: + - img [ref=e584] + - link "YAML prettify and format" [ref=e586] [cursor=pointer]: + - /url: /yaml-prettify + - menuitem "Email normalizer" [ref=e587]: + - img [ref=e589] [cursor=pointer]: + - img [ref=e590] + - link "Email normalizer" [ref=e594] [cursor=pointer]: + - /url: /email-normalizer + - menuitem "Regex Tester" [ref=e595]: + - img [ref=e597] [cursor=pointer]: + - img [ref=e598] + - link "Regex Tester" [ref=e603] [cursor=pointer]: + - /url: /regex-tester + - menuitem "Regex cheatsheet" [ref=e604]: + - img [ref=e606] [cursor=pointer]: + - img [ref=e607] + - link "Regex cheatsheet" [ref=e612] [cursor=pointer]: + - /url: /regex-memo + - menuitem "cURL to Code" [ref=e613]: + - img [ref=e615] [cursor=pointer]: + - img [ref=e616] + - link "cURL to Code" [ref=e620] [cursor=pointer]: + - /url: /curl-to-code + - menuitem "JSON to TypeScript/Go" [ref=e621]: + - img [ref=e623] [cursor=pointer]: + - img [ref=e624] + - link "JSON to TypeScript/Go" [ref=e629] [cursor=pointer]: + - /url: /json-to-types + - menuitem "CSS/JS Prettify & Minify" [ref=e630]: + - img [ref=e632] [cursor=pointer]: + - img [ref=e633] + - link "CSS/JS Prettify & Minify" [ref=e639] [cursor=pointer]: + - /url: /css-js-prettify-minify + - generic [ref=e640]: + - generic [ref=e641] [cursor=pointer]: + - img [ref=e643] + - generic [ref=e645]: Network + - menu [ref=e649]: + - menuitem "IPv4 subnet calculator" [ref=e650]: + - img [ref=e652] [cursor=pointer]: + - img [ref=e653] + - link "IPv4 subnet calculator" [ref=e655] [cursor=pointer]: + - /url: /ipv4-subnet-calculator + - menuitem "IPv4 address converter" [ref=e656]: + - img [ref=e658] [cursor=pointer]: + - img [ref=e659] + - link "IPv4 address converter" [ref=e665] [cursor=pointer]: + - /url: /ipv4-address-converter + - menuitem "IPv4 range expander" [ref=e666]: + - img [ref=e668] [cursor=pointer]: + - img [ref=e669] + - link "IPv4 range expander" [ref=e671] [cursor=pointer]: + - /url: /ipv4-range-expander + - menuitem "MAC address lookup" [ref=e672]: + - img [ref=e674] [cursor=pointer]: + - img [ref=e675] + - link "MAC address lookup" [ref=e679] [cursor=pointer]: + - /url: /mac-address-lookup + - menuitem "MAC address generator" [ref=e680]: + - img [ref=e682] [cursor=pointer]: + - img [ref=e683] + - link "MAC address generator" [ref=e687] [cursor=pointer]: + - /url: /mac-address-generator + - menuitem "IPv6 ULA generator" [ref=e688]: + - img [ref=e690] [cursor=pointer]: + - img [ref=e691] + - link "IPv6 ULA generator" [ref=e696] [cursor=pointer]: + - /url: /ipv6-ula-generator + - menuitem "DNS Query" [ref=e697]: + - img [ref=e699] [cursor=pointer]: + - img [ref=e700] + - link "DNS Query" [ref=e706] [cursor=pointer]: + - /url: /dns-query + - generic [ref=e707]: + - generic [ref=e708] [cursor=pointer]: + - img [ref=e710] + - generic [ref=e712]: Math + - menu [ref=e716]: + - menuitem "Math evaluator" [ref=e717]: + - img [ref=e719] [cursor=pointer]: + - img [ref=e720] + - link "Math evaluator" [ref=e724] [cursor=pointer]: + - /url: /math-evaluator + - menuitem "ETA calculator" [ref=e725]: + - img [ref=e727] [cursor=pointer]: + - img [ref=e728] + - link "ETA calculator" [ref=e732] [cursor=pointer]: + - /url: /eta-calculator + - menuitem "Percentage calculator" [ref=e733]: + - img [ref=e735] [cursor=pointer]: + - img [ref=e736] + - link "Percentage calculator" [ref=e741] [cursor=pointer]: + - /url: /percentage-calculator + - generic [ref=e742]: + - generic [ref=e743] [cursor=pointer]: + - img [ref=e745] + - generic [ref=e747]: Measurement + - menu [ref=e751]: + - menuitem "Chronometer" [ref=e752]: + - img [ref=e754] [cursor=pointer]: + - img [ref=e755] + - link "Chronometer" [ref=e757] [cursor=pointer]: + - /url: /chronometer + - menuitem "Temperature converter" [ref=e758]: + - img [ref=e760] [cursor=pointer]: + - img [ref=e761] + - link "Temperature converter" [ref=e764] [cursor=pointer]: + - /url: /temperature-converter + - menuitem "Benchmark builder" [ref=e765]: + - img [ref=e767] [cursor=pointer]: + - img [ref=e768] + - link "Benchmark builder" [ref=e770] [cursor=pointer]: + - /url: /benchmark-builder + - menuitem "Byte unit converter" [ref=e771]: + - img [ref=e773] [cursor=pointer]: + - img [ref=e774] + - link "Byte unit converter" [ref=e781] [cursor=pointer]: + - /url: /byte-unit-converter + - generic [ref=e782]: + - generic [ref=e783] [cursor=pointer]: + - img [ref=e785] + - generic [ref=e787]: Text + - menu [ref=e791]: + - menuitem "Lorem ipsum generator" [ref=e792]: + - img [ref=e794] [cursor=pointer]: + - img [ref=e795] + - link "Lorem ipsum generator" [ref=e797] [cursor=pointer]: + - /url: /lorem-ipsum-generator + - menuitem "Text statistics" [ref=e798]: + - img [ref=e800] [cursor=pointer]: + - img [ref=e801] + - link "Text statistics" [ref=e805] [cursor=pointer]: + - /url: /text-statistics + - menuitem "Emoji picker" [ref=e806]: + - img [ref=e808] [cursor=pointer]: + - img [ref=e809] + - link "Emoji picker" [ref=e813] [cursor=pointer]: + - /url: /emoji-picker + - menuitem "String obfuscator" [ref=e814]: + - img [ref=e816] [cursor=pointer]: + - img [ref=e817] + - link "String obfuscator" [ref=e822] [cursor=pointer]: + - /url: /string-obfuscator + - menuitem "Text diff" [ref=e823]: + - img [ref=e825] [cursor=pointer]: + - img [ref=e826] + - link "Text diff" [ref=e830] [cursor=pointer]: + - /url: /text-diff + - menuitem "Numeronym generator" [ref=e831]: + - img [ref=e833] [cursor=pointer]: + - img [ref=e834]: + - generic "n7m" [ref=e835] + - link "Numeronym generator" [ref=e836] [cursor=pointer]: + - /url: /numeronym-generator + - menuitem "ASCII Art Text Generator" [ref=e837]: + - img [ref=e839] [cursor=pointer]: + - img [ref=e840] + - link "ASCII Art Text Generator" [ref=e843] [cursor=pointer]: + - /url: /ascii-text-drawer + - generic [ref=e844]: + - generic [ref=e845] [cursor=pointer]: + - img [ref=e847] + - generic [ref=e849]: Data + - menu [ref=e853]: + - menuitem "Phone parser and formatter" [ref=e854]: + - img [ref=e856] [cursor=pointer]: + - img [ref=e857] + - link "Phone parser and formatter" [ref=e859] [cursor=pointer]: + - /url: /phone-parser-and-formatter + - menuitem "IBAN validator and parser" [ref=e860]: + - img [ref=e862] [cursor=pointer]: + - img [ref=e863] + - link "IBAN validator and parser" [ref=e865] [cursor=pointer]: + - /url: /iban-validator-and-parser + - generic [ref=e866]: + - generic [ref=e867]: + - text: IT-Tools + - link "v2024.10.22-7ca5933" [ref=e868] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools/tree/v2024.10.22-7ca5933 + - generic [ref=e869]: + - text: © 2026 + - link "Corentin Thomasset" [ref=e870] [cursor=pointer]: + - /url: https://corentin.tech?utm_source=it-tools&utm_medium=footer + - generic [ref=e873]: + - generic [ref=e874]: + - button "Toggle menu" [ref=e875] [cursor=pointer]: + - img [ref=e876]: + - img [ref=e877] + - link "Home" [ref=e881] [cursor=pointer]: + - /url: / + - img [ref=e882]: + - img [ref=e883] + - link "UI Lib" [ref=e890] [cursor=pointer]: + - /url: /c-lib + - img [ref=e891] + - button "Search Cmd + K" [ref=e894] [cursor=pointer]: + - generic [ref=e895]: + - img [ref=e896] + - text: Search + - generic [ref=e898]: Cmd + K + - generic [ref=e901] [cursor=pointer]: + - generic [ref=e902]: English + - img [ref=e903] + - generic [ref=e905]: + - link "IT-Tools GitHub repository" [ref=e908] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools + - img [ref=e909]: + - img [ref=e910] + - link "IT Tools X account" [ref=e914] [cursor=pointer]: + - /url: https://x.com/ittoolsdottech + - img [ref=e915]: + - img [ref=e916] + - link "About" [ref=e921] [cursor=pointer]: + - /url: /about + - img [ref=e922]: + - img [ref=e923] + - button "Toggle dark/light mode" [ref=e928] [cursor=pointer]: + - img [ref=e929]: + - img [ref=e930] + - link "Buy me a coffee" [ref=e934] [cursor=pointer]: + - /url: https://www.buymeacoffee.com/cthmsst + - text: Buy me a coffee + - img [ref=e935]: + - img [ref=e936] + - generic [ref=e939]: + - generic [ref=e940]: + - heading "DNS Query" [level=1] [ref=e941] + - button [ref=e945] [cursor=pointer]: + - img [ref=e946] + - generic [ref=e949]: Query DNS records (A, AAAA, CNAME, MX, TXT, NS, SOA, ...) for any domain name online using Cloudflare DNS. + - generic [ref=e951]: + - generic [ref=e952]: + - generic [ref=e953]: Domain name + - generic [ref=e955]: + - textbox "Domain name" [ref=e956]: + - /placeholder: e.g. example.com + - text: example.com + - button [ref=e957] [cursor=pointer]: + - img [ref=e958] + - generic [ref=e960]: + - generic [ref=e961]: Record type + - generic [ref=e963] [cursor=pointer]: + - generic [ref=e964]: A + - img [ref=e965] + - button "Query DNS" [ref=e968] [cursor=pointer] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-06-12T07-29-28-690Z.yml b/.playwright-mcp/page-2026-06-12T07-29-28-690Z.yml new file mode 100644 index 0000000000..c7d31a12bd --- /dev/null +++ b/.playwright-mcp/page-2026-06-12T07-29-28-690Z.yml @@ -0,0 +1,616 @@ +- generic [ref=e5]: + - complementary [ref=e6]: + - link "IT - TOOLS Handy tools for developers" [ref=e7] [cursor=pointer]: + - /url: / + - img [ref=e8] + - generic [ref=e13]: + - generic [ref=e14]: IT - TOOLS + - generic [ref=e16]: Handy tools for developers + - generic [ref=e17]: + - generic [ref=e18]: + - generic [ref=e19] [cursor=pointer]: + - img [ref=e21] + - generic [ref=e23]: Crypto + - menu [ref=e27]: + - menuitem "Token generator" [ref=e28]: + - img [ref=e30] [cursor=pointer]: + - img [ref=e31] + - link "Token generator" [ref=e37] [cursor=pointer]: + - /url: /token-generator + - menuitem "Hash text" [ref=e38]: + - img [ref=e40] [cursor=pointer]: + - img [ref=e41] + - link "Hash text" [ref=e46] [cursor=pointer]: + - /url: /hash-text + - menuitem "Bcrypt" [ref=e47]: + - img [ref=e49] [cursor=pointer]: + - img [ref=e50] + - link "Bcrypt" [ref=e55] [cursor=pointer]: + - /url: /bcrypt + - menuitem "UUIDs generator" [ref=e56]: + - img [ref=e58] [cursor=pointer]: + - img [ref=e59] + - link "UUIDs generator" [ref=e66] [cursor=pointer]: + - /url: /uuid-generator + - menuitem "ULID generator" [ref=e67]: + - img [ref=e69] [cursor=pointer]: + - img [ref=e70] + - link "ULID generator" [ref=e76] [cursor=pointer]: + - /url: /ulid-generator + - menuitem "Encrypt / decrypt text" [ref=e77]: + - img [ref=e79] [cursor=pointer]: + - img [ref=e80] + - link "Encrypt / decrypt text" [ref=e85] [cursor=pointer]: + - /url: /encryption + - menuitem "BIP39 passphrase generator" [ref=e86]: + - img [ref=e88] [cursor=pointer]: + - img [ref=e89] + - link "BIP39 passphrase generator" [ref=e91] [cursor=pointer]: + - /url: /bip39-generator + - menuitem "Hmac generator" [ref=e92]: + - img [ref=e94] [cursor=pointer]: + - img [ref=e95] + - link "Hmac generator" [ref=e97] [cursor=pointer]: + - /url: /hmac-generator + - menuitem "RSA key pair generator" [ref=e98]: + - img [ref=e100] [cursor=pointer]: + - img [ref=e101] + - link "RSA key pair generator" [ref=e106] [cursor=pointer]: + - /url: /rsa-key-pair-generator + - menuitem "Password strength analyser" [ref=e107]: + - img [ref=e109] [cursor=pointer]: + - img [ref=e110] + - link "Password strength analyser" [ref=e112] [cursor=pointer]: + - /url: /password-strength-analyser + - menuitem "PDF signature checker" [ref=e113]: + - img [ref=e115] [cursor=pointer]: + - img [ref=e116] + - link "PDF signature checker" [ref=e118] [cursor=pointer]: + - /url: /pdf-signature-checker + - menuitem "SSL Certificate Parser" [ref=e119]: + - img [ref=e121] [cursor=pointer]: + - img [ref=e122] + - link "SSL Certificate Parser" [ref=e129] [cursor=pointer]: + - /url: /ssl-certificate-parser + - generic [ref=e130]: + - generic [ref=e131] [cursor=pointer]: + - img [ref=e133] + - generic [ref=e135]: Converter + - menu [ref=e139]: + - menuitem "Date-time converter" [ref=e140]: + - img [ref=e142] [cursor=pointer]: + - img [ref=e143] + - link "Date-time converter" [ref=e146] [cursor=pointer]: + - /url: /date-converter + - menuitem "Integer base converter" [ref=e147]: + - img [ref=e149] [cursor=pointer]: + - img [ref=e150] + - link "Integer base converter" [ref=e154] [cursor=pointer]: + - /url: /base-converter + - menuitem "Roman numeral converter" [ref=e155]: + - img [ref=e157] [cursor=pointer]: + - img [ref=e158] + - link "Roman numeral converter" [ref=e162] [cursor=pointer]: + - /url: /roman-numeral-converter + - menuitem "Base64 string encoder/decoder" [ref=e163]: + - img [ref=e165] [cursor=pointer]: + - img [ref=e166] + - link "Base64 string encoder/decoder" [ref=e171] [cursor=pointer]: + - /url: /base64-string-converter + - menuitem "Base64 file converter" [ref=e172]: + - img [ref=e174] [cursor=pointer]: + - img [ref=e175] + - link "Base64 file converter" [ref=e180] [cursor=pointer]: + - /url: /base64-file-converter + - menuitem "Color converter" [ref=e181]: + - img [ref=e183] [cursor=pointer]: + - img [ref=e184] + - link "Color converter" [ref=e190] [cursor=pointer]: + - /url: /color-converter + - menuitem "Case converter" [ref=e191]: + - img [ref=e193] [cursor=pointer]: + - img [ref=e194] + - link "Case converter" [ref=e198] [cursor=pointer]: + - /url: /case-converter + - menuitem "Text to NATO alphabet" [ref=e199]: + - img [ref=e201] [cursor=pointer]: + - img [ref=e202] + - link "Text to NATO alphabet" [ref=e207] [cursor=pointer]: + - /url: /text-to-nato-alphabet + - menuitem "Text to ASCII binary" [ref=e208]: + - img [ref=e210] [cursor=pointer]: + - img [ref=e211] + - link "Text to ASCII binary" [ref=e217] [cursor=pointer]: + - /url: /text-to-binary + - menuitem "Text to Unicode" [ref=e218]: + - img [ref=e220] [cursor=pointer]: + - img [ref=e221] + - link "Text to Unicode" [ref=e224] [cursor=pointer]: + - /url: /text-to-unicode + - menuitem "YAML to JSON converter" [ref=e225]: + - img [ref=e227] [cursor=pointer]: + - img [ref=e228] + - link "YAML to JSON converter" [ref=e230] [cursor=pointer]: + - /url: /yaml-to-json-converter + - menuitem "YAML to TOML" [ref=e231]: + - img [ref=e233] [cursor=pointer]: + - img [ref=e234] + - link "YAML to TOML" [ref=e236] [cursor=pointer]: + - /url: /yaml-to-toml + - menuitem "JSON to YAML converter" [ref=e237]: + - img [ref=e239] [cursor=pointer]: + - img [ref=e240] + - link "JSON to YAML converter" [ref=e244] [cursor=pointer]: + - /url: /json-to-yaml-converter + - menuitem "JSON to TOML" [ref=e245]: + - img [ref=e247] [cursor=pointer]: + - img [ref=e248] + - link "JSON to TOML" [ref=e252] [cursor=pointer]: + - /url: /json-to-toml + - menuitem "List converter" [ref=e253]: + - img [ref=e255] [cursor=pointer]: + - img [ref=e256] + - link "List converter" [ref=e258] [cursor=pointer]: + - /url: /list-converter + - menuitem "TOML to JSON" [ref=e259]: + - img [ref=e261] [cursor=pointer]: + - img [ref=e262] + - link "TOML to JSON" [ref=e264] [cursor=pointer]: + - /url: /toml-to-json + - menuitem "TOML to YAML" [ref=e265]: + - img [ref=e267] [cursor=pointer]: + - img [ref=e268] + - link "TOML to YAML" [ref=e270] [cursor=pointer]: + - /url: /toml-to-yaml + - menuitem "XML to JSON" [ref=e271]: + - img [ref=e273] [cursor=pointer]: + - img [ref=e274] + - link "XML to JSON" [ref=e278] [cursor=pointer]: + - /url: /xml-to-json + - menuitem "JSON to XML" [ref=e279]: + - img [ref=e281] [cursor=pointer]: + - img [ref=e282] + - link "JSON to XML" [ref=e286] [cursor=pointer]: + - /url: /json-to-xml + - menuitem "Markdown to HTML" [ref=e287]: + - img [ref=e289] [cursor=pointer]: + - img [ref=e290] + - link "Markdown to HTML" [ref=e295] [cursor=pointer]: + - /url: /markdown-to-html + - menuitem "HTML to Markdown" [ref=e296]: + - img [ref=e298] [cursor=pointer]: + - img [ref=e299] + - link "HTML to Markdown" [ref=e305] [cursor=pointer]: + - /url: /html-to-markdown + - generic [ref=e306]: + - generic [ref=e307] [cursor=pointer]: + - img [ref=e309] + - generic [ref=e311]: Web + - menu [ref=e315]: + - menuitem "Encode/decode URL-formatted strings" [ref=e316]: + - img [ref=e318] [cursor=pointer]: + - img [ref=e319] + - link "Encode/decode URL-formatted strings" [ref=e323] [cursor=pointer]: + - /url: /url-encoder + - menuitem "Escape HTML entities" [ref=e324]: + - img [ref=e326] [cursor=pointer]: + - img [ref=e327] + - link "Escape HTML entities" [ref=e332] [cursor=pointer]: + - /url: /html-entities + - menuitem "URL parser" [ref=e333]: + - img [ref=e335] [cursor=pointer]: + - img [ref=e336] + - link "URL parser" [ref=e340] [cursor=pointer]: + - /url: /url-parser + - menuitem "Device information" [ref=e341]: + - img [ref=e343] [cursor=pointer]: + - img [ref=e344] + - link "Device information" [ref=e347] [cursor=pointer]: + - /url: /device-information + - menuitem "Basic auth generator" [ref=e348]: + - img [ref=e350] [cursor=pointer]: + - img [ref=e351] + - link "Basic auth generator" [ref=e353] [cursor=pointer]: + - /url: /basic-auth-generator + - menuitem "Open graph meta generator" [ref=e354]: + - img [ref=e356] [cursor=pointer]: + - img [ref=e357] + - link "Open graph meta generator" [ref=e361] [cursor=pointer]: + - /url: /og-meta-generator + - menuitem "OTP code generator" [ref=e362]: + - img [ref=e364] [cursor=pointer]: + - img [ref=e365] + - link "OTP code generator" [ref=e368] [cursor=pointer]: + - /url: /otp-generator + - menuitem "MIME types" [ref=e369]: + - img [ref=e371] [cursor=pointer]: + - img [ref=e372] + - link "MIME types" [ref=e377] [cursor=pointer]: + - /url: /mime-types + - menuitem "JWT parser" [ref=e378]: + - img [ref=e380] [cursor=pointer]: + - img [ref=e381] + - link "JWT parser" [ref=e387] [cursor=pointer]: + - /url: /jwt-parser + - menuitem "Keycode info" [ref=e388]: + - img [ref=e390] [cursor=pointer]: + - img [ref=e391] + - link "Keycode info" [ref=e394] [cursor=pointer]: + - /url: /keycode-info + - menuitem "Slugify string" [ref=e395]: + - img [ref=e397] [cursor=pointer]: + - img [ref=e398] + - link "Slugify string" [ref=e400] [cursor=pointer]: + - /url: /slugify-string + - menuitem "HTML WYSIWYG editor" [ref=e401]: + - img [ref=e403] [cursor=pointer]: + - img [ref=e404] + - link "HTML WYSIWYG editor" [ref=e409] [cursor=pointer]: + - /url: /html-wysiwyg-editor + - menuitem "User-agent parser" [ref=e410]: + - img [ref=e412] [cursor=pointer]: + - img [ref=e413] + - link "User-agent parser" [ref=e416] [cursor=pointer]: + - /url: /user-agent-parser + - menuitem "HTTP status codes" [ref=e417]: + - img [ref=e419] [cursor=pointer]: + - img [ref=e420] + - link "HTTP status codes" [ref=e422] [cursor=pointer]: + - /url: /http-status-codes + - menuitem "JSON diff" [ref=e423]: + - img [ref=e425] [cursor=pointer]: + - img [ref=e426] + - link "JSON diff" [ref=e428] [cursor=pointer]: + - /url: /json-diff + - menuitem "Outlook Safelink decoder" [ref=e429]: + - img [ref=e431] [cursor=pointer]: + - img [ref=e432] + - link "Outlook Safelink decoder" [ref=e436] [cursor=pointer]: + - /url: /safelink-decoder + - generic [ref=e437]: + - generic [ref=e438] [cursor=pointer]: + - img [ref=e440] + - generic [ref=e442]: Images & Videos + - menu [ref=e446]: + - menuitem "QR Code generator" [ref=e447]: + - img [ref=e449] [cursor=pointer]: + - img [ref=e450] + - link "QR Code generator" [ref=e455] [cursor=pointer]: + - /url: /qrcode-generator + - menuitem "WiFi QR Code generator" [ref=e456]: + - img [ref=e458] [cursor=pointer]: + - img [ref=e459] + - link "WiFi QR Code generator" [ref=e464] [cursor=pointer]: + - /url: /wifi-qrcode-generator + - menuitem "SVG placeholder generator" [ref=e465]: + - img [ref=e467] [cursor=pointer]: + - img [ref=e468] + - link "SVG placeholder generator" [ref=e470] [cursor=pointer]: + - /url: /svg-placeholder-generator + - menuitem "Camera recorder" [ref=e471]: + - img [ref=e473] [cursor=pointer]: + - img [ref=e474] + - link "Camera recorder" [ref=e478] [cursor=pointer]: + - /url: /camera-recorder + - generic [ref=e479]: + - generic [ref=e480] [cursor=pointer]: + - img [ref=e482] + - generic [ref=e484]: Development + - menu [ref=e488]: + - menuitem "Git cheatsheet" [ref=e489]: + - img [ref=e491] [cursor=pointer]: + - img [ref=e492] + - link "Git cheatsheet" [ref=e500] [cursor=pointer]: + - /url: /git-memo + - menuitem "Random port generator" [ref=e501]: + - img [ref=e503] [cursor=pointer]: + - img [ref=e504] + - link "Random port generator" [ref=e508] [cursor=pointer]: + - /url: /random-port-generator + - menuitem "Crontab generator" [ref=e509]: + - img [ref=e511] [cursor=pointer]: + - img [ref=e512] + - link "Crontab generator" [ref=e518] [cursor=pointer]: + - /url: /crontab-generator + - menuitem "JSON prettify and format" [ref=e519]: + - img [ref=e521] [cursor=pointer]: + - img [ref=e522] + - link "JSON prettify and format" [ref=e526] [cursor=pointer]: + - /url: /json-prettify + - menuitem "JSON minify" [ref=e527]: + - img [ref=e529] [cursor=pointer]: + - img [ref=e530] + - link "JSON minify" [ref=e534] [cursor=pointer]: + - /url: /json-minify + - menuitem "JSON to CSV" [ref=e535]: + - img [ref=e537] [cursor=pointer]: + - img [ref=e538] + - link "JSON to CSV" [ref=e540] [cursor=pointer]: + - /url: /json-to-csv + - menuitem "SQL prettify and format" [ref=e541]: + - img [ref=e543] [cursor=pointer]: + - img [ref=e544] + - link "SQL prettify and format" [ref=e549] [cursor=pointer]: + - /url: /sql-prettify + - menuitem "Chmod calculator" [ref=e550]: + - img [ref=e552] [cursor=pointer]: + - img [ref=e553] + - link "Chmod calculator" [ref=e557] [cursor=pointer]: + - /url: /chmod-calculator + - menuitem "Docker run to Docker compose converter" [ref=e558]: + - img [ref=e560] [cursor=pointer]: + - img [ref=e561] + - link "Docker run to Docker compose converter" [ref=e571] [cursor=pointer]: + - /url: /docker-run-to-docker-compose-converter + - menuitem "XML formatter" [ref=e572]: + - img [ref=e574] [cursor=pointer]: + - img [ref=e575] + - link "XML formatter" [ref=e580] [cursor=pointer]: + - /url: /xml-formatter + - menuitem "YAML prettify and format" [ref=e581]: + - img [ref=e583] [cursor=pointer]: + - img [ref=e584] + - link "YAML prettify and format" [ref=e586] [cursor=pointer]: + - /url: /yaml-prettify + - menuitem "Email normalizer" [ref=e587]: + - img [ref=e589] [cursor=pointer]: + - img [ref=e590] + - link "Email normalizer" [ref=e594] [cursor=pointer]: + - /url: /email-normalizer + - menuitem "Regex Tester" [ref=e595]: + - img [ref=e597] [cursor=pointer]: + - img [ref=e598] + - link "Regex Tester" [ref=e603] [cursor=pointer]: + - /url: /regex-tester + - menuitem "Regex cheatsheet" [ref=e604]: + - img [ref=e606] [cursor=pointer]: + - img [ref=e607] + - link "Regex cheatsheet" [ref=e612] [cursor=pointer]: + - /url: /regex-memo + - menuitem "cURL to Code" [ref=e613]: + - img [ref=e615] [cursor=pointer]: + - img [ref=e616] + - link "cURL to Code" [ref=e620] [cursor=pointer]: + - /url: /curl-to-code + - menuitem "JSON to TypeScript/Go" [ref=e621]: + - img [ref=e623] [cursor=pointer]: + - img [ref=e624] + - link "JSON to TypeScript/Go" [ref=e629] [cursor=pointer]: + - /url: /json-to-types + - menuitem "CSS/JS Prettify & Minify" [ref=e630]: + - img [ref=e632] [cursor=pointer]: + - img [ref=e633] + - link "CSS/JS Prettify & Minify" [ref=e639] [cursor=pointer]: + - /url: /css-js-prettify-minify + - generic [ref=e640]: + - generic [ref=e641] [cursor=pointer]: + - img [ref=e643] + - generic [ref=e645]: Network + - menu [ref=e649]: + - menuitem "IPv4 subnet calculator" [ref=e650]: + - img [ref=e652] [cursor=pointer]: + - img [ref=e653] + - link "IPv4 subnet calculator" [ref=e655] [cursor=pointer]: + - /url: /ipv4-subnet-calculator + - menuitem "IPv4 address converter" [ref=e656]: + - img [ref=e658] [cursor=pointer]: + - img [ref=e659] + - link "IPv4 address converter" [ref=e665] [cursor=pointer]: + - /url: /ipv4-address-converter + - menuitem "IPv4 range expander" [ref=e666]: + - img [ref=e668] [cursor=pointer]: + - img [ref=e669] + - link "IPv4 range expander" [ref=e671] [cursor=pointer]: + - /url: /ipv4-range-expander + - menuitem "MAC address lookup" [ref=e672]: + - img [ref=e674] [cursor=pointer]: + - img [ref=e675] + - link "MAC address lookup" [ref=e679] [cursor=pointer]: + - /url: /mac-address-lookup + - menuitem "MAC address generator" [ref=e680]: + - img [ref=e682] [cursor=pointer]: + - img [ref=e683] + - link "MAC address generator" [ref=e687] [cursor=pointer]: + - /url: /mac-address-generator + - menuitem "IPv6 ULA generator" [ref=e688]: + - img [ref=e690] [cursor=pointer]: + - img [ref=e691] + - link "IPv6 ULA generator" [ref=e696] [cursor=pointer]: + - /url: /ipv6-ula-generator + - menuitem "DNS Query" [ref=e697]: + - img [ref=e699] [cursor=pointer]: + - img [ref=e700] + - link "DNS Query" [ref=e706] [cursor=pointer]: + - /url: /dns-query + - generic [ref=e707]: + - generic [ref=e708] [cursor=pointer]: + - img [ref=e710] + - generic [ref=e712]: Math + - menu [ref=e716]: + - menuitem "Math evaluator" [ref=e717]: + - img [ref=e719] [cursor=pointer]: + - img [ref=e720] + - link "Math evaluator" [ref=e724] [cursor=pointer]: + - /url: /math-evaluator + - menuitem "ETA calculator" [ref=e725]: + - img [ref=e727] [cursor=pointer]: + - img [ref=e728] + - link "ETA calculator" [ref=e732] [cursor=pointer]: + - /url: /eta-calculator + - menuitem "Percentage calculator" [ref=e733]: + - img [ref=e735] [cursor=pointer]: + - img [ref=e736] + - link "Percentage calculator" [ref=e741] [cursor=pointer]: + - /url: /percentage-calculator + - generic [ref=e742]: + - generic [ref=e743] [cursor=pointer]: + - img [ref=e745] + - generic [ref=e747]: Measurement + - menu [ref=e751]: + - menuitem "Chronometer" [ref=e752]: + - img [ref=e754] [cursor=pointer]: + - img [ref=e755] + - link "Chronometer" [ref=e757] [cursor=pointer]: + - /url: /chronometer + - menuitem "Temperature converter" [ref=e758]: + - img [ref=e760] [cursor=pointer]: + - img [ref=e761] + - link "Temperature converter" [ref=e764] [cursor=pointer]: + - /url: /temperature-converter + - menuitem "Benchmark builder" [ref=e765]: + - img [ref=e767] [cursor=pointer]: + - img [ref=e768] + - link "Benchmark builder" [ref=e770] [cursor=pointer]: + - /url: /benchmark-builder + - menuitem "Byte unit converter" [ref=e771]: + - img [ref=e773] [cursor=pointer]: + - img [ref=e774] + - link "Byte unit converter" [ref=e781] [cursor=pointer]: + - /url: /byte-unit-converter + - generic [ref=e782]: + - generic [ref=e783] [cursor=pointer]: + - img [ref=e785] + - generic [ref=e787]: Text + - menu [ref=e791]: + - menuitem "Lorem ipsum generator" [ref=e792]: + - img [ref=e794] [cursor=pointer]: + - img [ref=e795] + - link "Lorem ipsum generator" [ref=e797] [cursor=pointer]: + - /url: /lorem-ipsum-generator + - menuitem "Text statistics" [ref=e798]: + - img [ref=e800] [cursor=pointer]: + - img [ref=e801] + - link "Text statistics" [ref=e805] [cursor=pointer]: + - /url: /text-statistics + - menuitem "Emoji picker" [ref=e806]: + - img [ref=e808] [cursor=pointer]: + - img [ref=e809] + - link "Emoji picker" [ref=e813] [cursor=pointer]: + - /url: /emoji-picker + - menuitem "String obfuscator" [ref=e814]: + - img [ref=e816] [cursor=pointer]: + - img [ref=e817] + - link "String obfuscator" [ref=e822] [cursor=pointer]: + - /url: /string-obfuscator + - menuitem "Text diff" [ref=e823]: + - img [ref=e825] [cursor=pointer]: + - img [ref=e826] + - link "Text diff" [ref=e830] [cursor=pointer]: + - /url: /text-diff + - menuitem "Numeronym generator" [ref=e831]: + - img [ref=e833] [cursor=pointer]: + - img [ref=e834]: + - generic "n7m" [ref=e835] + - link "Numeronym generator" [ref=e836] [cursor=pointer]: + - /url: /numeronym-generator + - menuitem "ASCII Art Text Generator" [ref=e837]: + - img [ref=e839] [cursor=pointer]: + - img [ref=e840] + - link "ASCII Art Text Generator" [ref=e843] [cursor=pointer]: + - /url: /ascii-text-drawer + - generic [ref=e844]: + - generic [ref=e845] [cursor=pointer]: + - img [ref=e847] + - generic [ref=e849]: Data + - menu [ref=e853]: + - menuitem "Phone parser and formatter" [ref=e854]: + - img [ref=e856] [cursor=pointer]: + - img [ref=e857] + - link "Phone parser and formatter" [ref=e859] [cursor=pointer]: + - /url: /phone-parser-and-formatter + - menuitem "IBAN validator and parser" [ref=e860]: + - img [ref=e862] [cursor=pointer]: + - img [ref=e863] + - link "IBAN validator and parser" [ref=e865] [cursor=pointer]: + - /url: /iban-validator-and-parser + - generic [ref=e866]: + - generic [ref=e867]: + - text: IT-Tools + - link "v2024.10.22-7ca5933" [ref=e868] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools/tree/v2024.10.22-7ca5933 + - generic [ref=e869]: + - text: © 2026 + - link "Corentin Thomasset" [ref=e870] [cursor=pointer]: + - /url: https://corentin.tech?utm_source=it-tools&utm_medium=footer + - generic [ref=e873]: + - generic [ref=e874]: + - button "Toggle menu" [ref=e875] [cursor=pointer]: + - img [ref=e876]: + - img [ref=e877] + - link "Home" [ref=e881] [cursor=pointer]: + - /url: / + - img [ref=e882]: + - img [ref=e883] + - link "UI Lib" [ref=e890] [cursor=pointer]: + - /url: /c-lib + - img [ref=e891] + - button "Search Cmd + K" [ref=e894] [cursor=pointer]: + - generic [ref=e895]: + - img [ref=e896] + - text: Search + - generic [ref=e898]: Cmd + K + - generic [ref=e901] [cursor=pointer]: + - generic [ref=e902]: English + - img [ref=e903] + - generic [ref=e905]: + - link "IT-Tools GitHub repository" [ref=e908] [cursor=pointer]: + - /url: https://github.com/CorentinTh/it-tools + - img [ref=e909]: + - img [ref=e910] + - link "IT Tools X account" [ref=e914] [cursor=pointer]: + - /url: https://x.com/ittoolsdottech + - img [ref=e915]: + - img [ref=e916] + - link "About" [ref=e921] [cursor=pointer]: + - /url: /about + - img [ref=e922]: + - img [ref=e923] + - button "Toggle dark/light mode" [ref=e928] [cursor=pointer]: + - img [ref=e929]: + - img [ref=e930] + - link "Buy me a coffee" [ref=e934] [cursor=pointer]: + - /url: https://www.buymeacoffee.com/cthmsst + - text: Buy me a coffee + - img [ref=e935]: + - img [ref=e936] + - generic [ref=e939]: + - generic [ref=e940]: + - heading "DNS Query" [level=1] [ref=e941] + - button [ref=e945] [cursor=pointer]: + - img [ref=e946] + - generic [ref=e949]: Query DNS records (A, AAAA, CNAME, MX, TXT, NS, SOA, ...) for any domain name online using Cloudflare DNS. + - generic [ref=e951]: + - generic [ref=e952]: + - generic [ref=e953]: Domain name + - generic [ref=e955]: + - textbox "Domain name" [ref=e956]: + - /placeholder: e.g. example.com + - text: example.com + - button [ref=e957] [cursor=pointer]: + - img [ref=e958] + - generic [ref=e960]: + - generic [ref=e961]: Record type + - generic [ref=e963] [cursor=pointer]: + - generic [ref=e964]: A + - img [ref=e965] + - button "Query DNS" [ref=e968] [cursor=pointer] + - generic [ref=e969]: + - generic [ref=e970]: + - generic [ref=e971]: "Status:" + - generic [ref=e972]: NOERROR + - table [ref=e973]: + - rowgroup [ref=e974]: + - row "Name TTL Data" [ref=e975]: + - columnheader "Name" [ref=e976] + - columnheader "TTL" [ref=e977] + - columnheader "Data" [ref=e978] + - rowgroup [ref=e979]: + - row "example.com 123s 104.20.23.154" [ref=e980]: + - cell "example.com" [ref=e981] + - cell "123s" [ref=e982] + - cell "104.20.23.154" [ref=e983] + - row "example.com 123s 172.66.147.243" [ref=e984]: + - cell "example.com" [ref=e985] + - cell "123s" [ref=e986] + - cell "172.66.147.243" [ref=e987] + - button "Copy results" [ref=e989] [cursor=pointer] \ No newline at end of file diff --git a/auto-imports.d.ts b/auto-imports.d.ts index 186963f1d9..d9c125c61a 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -36,6 +36,7 @@ declare global { const h: typeof import('vue')['h'] const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] const inject: typeof import('vue')['inject'] + const injectLocal: typeof import('@vueuse/core')['injectLocal'] const isDefined: typeof import('@vueuse/core')['isDefined'] const isProxy: typeof import('vue')['isProxy'] const isReactive: typeof import('vue')['isReactive'] @@ -63,8 +64,10 @@ declare global { const onStartTyping: typeof import('@vueuse/core')['onStartTyping'] const onUnmounted: typeof import('vue')['onUnmounted'] const onUpdated: typeof import('vue')['onUpdated'] + const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] const provide: typeof import('vue')['provide'] + const provideLocal: typeof import('@vueuse/core')['provideLocal'] const reactify: typeof import('@vueuse/core')['reactify'] const reactifyObject: typeof import('@vueuse/core')['reactifyObject'] const reactive: typeof import('vue')['reactive'] @@ -128,6 +131,7 @@ declare global { const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation'] const useCached: typeof import('@vueuse/core')['useCached'] const useClipboard: typeof import('@vueuse/core')['useClipboard'] + const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems'] const useCloned: typeof import('@vueuse/core')['useCloned'] const useColorMode: typeof import('@vueuse/core')['useColorMode'] const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog'] @@ -171,6 +175,7 @@ declare global { const useGamepad: typeof import('@vueuse/core')['useGamepad'] const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] const useI18n: typeof import('vue-i18n')['useI18n'] + const useId: typeof import('vue')['useId'] const useIdle: typeof import('@vueuse/core')['useIdle'] const useImage: typeof import('@vueuse/core')['useImage'] const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll'] @@ -189,6 +194,7 @@ declare global { const useMemoize: typeof import('@vueuse/core')['useMemoize'] const useMemory: typeof import('@vueuse/core')['useMemory'] const useMessage: typeof import('naive-ui')['useMessage'] + const useModel: typeof import('vue')['useModel'] const useMounted: typeof import('@vueuse/core')['useMounted'] const useMouse: typeof import('@vueuse/core')['useMouse'] const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] @@ -237,6 +243,7 @@ declare global { const useStyleTag: typeof import('@vueuse/core')['useStyleTag'] const useSupported: typeof import('@vueuse/core')['useSupported'] const useSwipe: typeof import('@vueuse/core')['useSwipe'] + const useTemplateRef: typeof import('vue')['useTemplateRef'] const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] const useTextDirection: typeof import('@vueuse/core')['useTextDirection'] const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] diff --git a/components.d.ts b/components.d.ts index 3e65c3cc52..5da666971c 100644 --- a/components.d.ts +++ b/components.d.ts @@ -20,6 +20,7 @@ declare module '@vue/runtime-core' { Bcrypt: typeof import('./src/tools/bcrypt/bcrypt.vue')['default'] BenchmarkBuilder: typeof import('./src/tools/benchmark-builder/benchmark-builder.vue')['default'] Bip39Generator: typeof import('./src/tools/bip39-generator/bip39-generator.vue')['default'] + ByteUnitConverter: typeof import('./src/tools/byte-unit-converter/byte-unit-converter.vue')['default'] CAlert: typeof import('./src/ui/c-alert/c-alert.vue')['default'] 'CAlert.demo': typeof import('./src/ui/c-alert/c-alert.demo.vue')['default'] CameraRecorder: typeof import('./src/tools/camera-recorder/camera-recorder.vue')['default'] @@ -58,17 +59,21 @@ declare module '@vue/runtime-core' { CrontabGenerator: typeof import('./src/tools/crontab-generator/crontab-generator.vue')['default'] CSelect: typeof import('./src/ui/c-select/c-select.vue')['default'] 'CSelect.demo': typeof import('./src/ui/c-select/c-select.demo.vue')['default'] + CssJsPrettifyMinify: typeof import('./src/tools/css-js-prettify-minify/css-js-prettify-minify.vue')['default'] CTable: typeof import('./src/ui/c-table/c-table.vue')['default'] 'CTable.demo': typeof import('./src/ui/c-table/c-table.demo.vue')['default'] CTextCopyable: typeof import('./src/ui/c-text-copyable/c-text-copyable.vue')['default'] 'CTextCopyable.demo': typeof import('./src/ui/c-text-copyable/c-text-copyable.demo.vue')['default'] CTooltip: typeof import('./src/ui/c-tooltip/c-tooltip.vue')['default'] 'CTooltip.demo': typeof import('./src/ui/c-tooltip/c-tooltip.demo.vue')['default'] + CurlToCode: typeof import('./src/tools/curl-to-code/curl-to-code.vue')['default'] + DateCalculator: typeof import('./src/tools/date-calculator/date-calculator.vue')['default'] DateTimeConverter: typeof import('./src/tools/date-time-converter/date-time-converter.vue')['default'] 'DemoHome.page': typeof import('./src/ui/demo/demo-home.page.vue')['default'] DemoWrapper: typeof import('./src/ui/demo/demo-wrapper.vue')['default'] DeviceInformation: typeof import('./src/tools/device-information/device-information.vue')['default'] DiffViewer: typeof import('./src/tools/json-diff/diff-viewer/diff-viewer.vue')['default'] + DnsQuery: typeof import('./src/tools/dns-query/dns-query.vue')['default'] DockerRunToDockerComposeConverter: typeof import('./src/tools/docker-run-to-docker-compose-converter/docker-run-to-docker-compose-converter.vue')['default'] DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default'] Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default'] @@ -86,21 +91,33 @@ declare module '@vue/runtime-core' { HmacGenerator: typeof import('./src/tools/hmac-generator/hmac-generator.vue')['default'] 'Home.page': typeof import('./src/pages/Home.page.vue')['default'] HtmlEntities: typeof import('./src/tools/html-entities/html-entities.vue')['default'] + HtmlToMarkdown: typeof import('./src/tools/html-to-markdown/html-to-markdown.vue')['default'] HtmlWysiwygEditor: typeof import('./src/tools/html-wysiwyg-editor/html-wysiwyg-editor.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'] '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'] + 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'] IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default'] IconMdiClose: typeof import('~icons/mdi/close')['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'] IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['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'] IconMdiTranslate: typeof import('~icons/mdi/translate')['default'] IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default'] + IconMdiVideo: typeof import('~icons/mdi/video')['default'] InputCopyable: typeof import('./src/components/InputCopyable.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'] @@ -111,6 +128,7 @@ declare module '@vue/runtime-core' { JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default'] JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default'] JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default'] + JsonToTypes: typeof import('./src/tools/json-to-types/json-to-types.vue')['default'] JsonToXml: typeof import('./src/tools/json-to-xml/json-to-xml.vue')['default'] JsonToYaml: typeof import('./src/tools/json-to-yaml-converter/json-to-yaml.vue')['default'] JsonViewer: typeof import('./src/tools/json-viewer/json-viewer.vue')['default'] @@ -129,20 +147,48 @@ declare module '@vue/runtime-core' { MenuLayout: typeof import('./src/components/MenuLayout.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'] + NAlert: typeof import('naive-ui')['NAlert'] NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] + NButton: typeof import('naive-ui')['NButton'] NCheckbox: typeof import('naive-ui')['NCheckbox'] + NCode: typeof import('naive-ui')['NCode'] + NCollapse: typeof import('naive-ui')['NCollapse'] + NCollapseItem: typeof import('naive-ui')['NCollapseItem'] NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] + NColorPicker: typeof import('naive-ui')['NColorPicker'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] + NDatePicker: typeof import('naive-ui')['NDatePicker'] NDivider: typeof import('naive-ui')['NDivider'] + NDynamicInput: typeof import('naive-ui')['NDynamicInput'] NEllipsis: typeof import('naive-ui')['NEllipsis'] + NForm: typeof import('naive-ui')['NForm'] + NFormItem: typeof import('naive-ui')['NFormItem'] + NGi: typeof import('naive-ui')['NGi'] + NGrid: typeof import('naive-ui')['NGrid'] NH1: typeof import('naive-ui')['NH1'] + NH2: typeof import('naive-ui')['NH2'] NH3: typeof import('naive-ui')['NH3'] + NH4: typeof import('naive-ui')['NH4'] 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'] NLayout: typeof import('naive-ui')['NLayout'] NLayoutSider: typeof import('naive-ui')['NLayoutSider'] + NLi: typeof import('naive-ui')['NLi'] NMenu: typeof import('naive-ui')['NMenu'] + NP: typeof import('naive-ui')['NP'] + NProgress: typeof import('naive-ui')['NProgress'] + NScrollbar: typeof import('naive-ui')['NScrollbar'] + NSlider: typeof import('naive-ui')['NSlider'] NSpace: typeof import('naive-ui')['NSpace'] + 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'] + NUl: typeof import('naive-ui')['NUl'] 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'] PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] @@ -164,6 +210,7 @@ declare module '@vue/runtime-core' { SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default'] SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default'] SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default'] + SslCertificateParser: typeof import('./src/tools/ssl-certificate-parser/ssl-certificate-parser.vue')['default'] StringObfuscator: typeof import('./src/tools/string-obfuscator/string-obfuscator.vue')['default'] SvgPlaceholderGenerator: typeof import('./src/tools/svg-placeholder-generator/svg-placeholder-generator.vue')['default'] TemperatureConverter: typeof import('./src/tools/temperature-converter/temperature-converter.vue')['default'] diff --git a/locales/en.yml b/locales/en.yml index d03d80d3f6..befdf93785 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -101,6 +101,10 @@ tools: title: SVG placeholder generator description: Generate svg images to use as a placeholder in your applications. + dns-query: + title: DNS Query + description: Query DNS records (A, AAAA, CNAME, MX, TXT, NS, SOA, ...) for any domain name online using Cloudflare DNS. + json-to-csv: title: JSON to CSV description: Convert JSON to CSV with automatic header detection. @@ -293,6 +297,25 @@ tools: title: JWT parser description: Parse and decode your JSON Web Token (jwt) and display its content. + date-calculator: + title: Date calculator + description: Add or subtract days from a date, or calculate the number of days between two dates. + offset: + sectionTitle: Date after / before N days + baseDate: Start date + days: Days offset + daysHint: Use a negative number to go backwards + resultLabel: Result date + diff: + sectionTitle: Days between two dates + startDate: Start date + targetDate: Target date + resultLabel: Difference + dayUnit: days + directionAfter: Target date is after the start date + directionBefore: Target date is before the start date + directionSame: Same date + date-converter: title: Date-time converter description: Convert date and time into the various different formats @@ -392,3 +415,61 @@ tools: text-to-binary: title: Text to ASCII binary description: Convert text to its ASCII binary representation and vice-versa. + + html-to-markdown: + title: HTML to Markdown + description: Convert HTML to Markdown with this online converter. + + byte-unit-converter: + title: Byte unit converter + description: Convert between data size units (bytes, KB, MB, GB, TB) in both decimal (SI) and binary (IEC) systems. + + json-to-types: + title: JSON to TypeScript/Go + description: Generate TypeScript interfaces or Go structs from a JSON sample. + + css-js-prettify-minify: + title: CSS/JS Prettify & Minify + description: Prettify or minify your CSS and JavaScript code online. + + curl-to-code: + title: cURL to Code + description: Convert cURL commands to code in various programming languages. + + ssl-certificate-parser: + title: SSL Certificate Parser + description: Parse and decode PEM certificates to view expiry date, domain, issuer and other details. + inputLabel: PEM certificate + inputPlaceholder: 'Paste your PEM certificate here (-----BEGIN CERTIFICATE-----...)' + invalidPem: Invalid PEM certificate + validity: Validity + status: Status + valid: Valid + expired: Expired + expiredAgo: '(expired {days} days ago)' + daysRemaining: '({days} days remaining)' + validFrom: Valid From + validTo: Valid To + subject: Subject + san: Subject Alternative Names (SAN) + issuer: Issuer + details: Details + version: Version + serialNumber: Serial Number + signatureAlgorithm: Signature Algorithm + publicKey: Public Key + fingerprint: Public Key Fingerprint (SHA-256) + keyUsage: Key Usage + basicConstraints: Basic Constraints + help: + title: How to get a PEM certificate? + section1Title: 1. Export from a website + section1Desc: 'This outputs content from -----BEGIN CERTIFICATE----- to -----END CERTIFICATE-----, which is the PEM certificate.' + section2Title: 2. Export from browser + section2Step1: 'Chrome/Edge: Click the lock icon in the address bar → Connection is secure → Certificate is valid → Details → Export' + section2Step2: Choose Base-64 encoded (.pem/.crt) format when exporting + section3Title: 3. From server files + section3Nginx: 'Nginx: Check the file pointed to by ssl_certificate (usually .pem or .crt)' + section3Apache: 'Apache: Check SSLCertificateFile' + section3Paths: 'Common paths: /etc/ssl/certs/, /etc/letsencrypt/live//fullchain.pem' + section4Title: 4. PEM format example diff --git a/locales/zh.yml b/locales/zh.yml index 97968eb5ef..65d24c170e 100644 --- a/locales/zh.yml +++ b/locales/zh.yml @@ -100,6 +100,10 @@ tools: title: SVG 占位符生成器 description: 生成 svg 图像以用作应用程序中的占位符。 + dns-query: + title: DNS 查询 + description: 在线查询任意域名的 DNS 记录(A、AAAA、CNAME、MX、TXT、NS、SOA 等),使用 Cloudflare DNS 解析。 + json-to-csv: title: JSON 转 CSV description: 使用自动标头检测将JSON转换为CSV。 @@ -144,8 +148,8 @@ tools: description: Git是一种去中心化的版本管理软件。使用此备忘单,您可以快速访问最常见的git命令. slugify-string: - title: 打乱字符串 - description: 确保字符串 url、文件名和 id 安全。 + title: 字符串 Slug 化 + description: "将任意字符串转换为 URL、文件名和 HTML id 安全的格式(slug)。\n转换规则:空格/换行转为连字符、大写转小写、去除重音符号、删除特殊字符。" encryption: title: 加密/解密文本 @@ -289,6 +293,25 @@ tools: title: JWT 解析器 description: 解析和解码JSON Web Token(jwt)并显示其内容。 + date-calculator: + title: 日期计算器 + description: 推算几天前/后的日期,或计算两个日期之间相差的天数。 + offset: + sectionTitle: 推算几天前 / 后的日期 + baseDate: 起始日期 + days: 偏移天数 + daysHint: 输入负数则往前推算 + resultLabel: 结果日期 + diff: + sectionTitle: 计算两个日期相差 + startDate: 开始日期 + targetDate: 目标日期 + resultLabel: 相差 + dayUnit: 天 + directionAfter: 目标日期比起始日期晚 + directionBefore: 目标日期比起始日期早 + directionSame: 两个日期为同一天 + date-converter: title: 日期时间转换器 description: 将日期和时间转换为各种不同的格式 @@ -388,3 +411,61 @@ tools: text-to-binary: title: 文本到 ASCII 二进制 description: 将文本转换为其 ASCII 二进制表示形式,反之亦然。 + + html-to-markdown: + title: HTML 转 Markdown + description: 使用此在线转换器将 HTML 转换为 Markdown。 + + byte-unit-converter: + title: 字节单位转换器 + description: 在十进制(SI)和二进制(IEC)系统中转换数据大小单位(字节、KB、MB、GB、TB)。 + + json-to-types: + title: JSON 转 TypeScript/Go + description: 从 JSON 样本生成 TypeScript 接口或 Go 结构体。 + + css-js-prettify-minify: + title: CSS/JS 格式化与压缩 + description: 在线格式化或压缩您的 CSS 和 JavaScript 代码。 + + curl-to-code: + title: cURL 转代码 + description: 将 cURL 命令转换为多种编程语言的代码。 + + ssl-certificate-parser: + title: SSL 证书解析器 + description: 解析 PEM 证书,查看过期时间、域名、颁发者等详细信息。 + inputLabel: PEM 证书 + inputPlaceholder: '在此粘贴 PEM 证书(-----BEGIN CERTIFICATE-----...)' + invalidPem: 无效的 PEM 证书 + validity: 有效期 + status: 状态 + valid: 有效 + expired: 已过期 + expiredAgo: '(已过期 {days} 天)' + daysRemaining: '(剩余 {days} 天)' + validFrom: 生效时间 + validTo: 过期时间 + subject: 主体信息 + san: 主体备用名称 (SAN) + issuer: 颁发者 + details: 详细信息 + version: 版本 + serialNumber: 序列号 + signatureAlgorithm: 签名算法 + publicKey: 公钥 + fingerprint: 公钥指纹 (SHA-256) + keyUsage: 密钥用途 + basicConstraints: 基本约束 + help: + title: 如何获取 PEM 证书? + section1Title: 1. 从网站导出 + section1Desc: '这会输出从 -----BEGIN CERTIFICATE----- 到 -----END CERTIFICATE----- 的内容,这就是 PEM 证书。' + section2Title: 2. 从浏览器导出 + section2Step1: Chrome/Edge:点击地址栏锁图标 → 连接是安全的 → 证书有效 → 详细信息 → 导出 + section2Step2: 导出时选择 Base-64 编码(.pem/.crt)格式 + section3Title: 3. 从服务器文件获取 + section3Nginx: Nginx:查看 ssl_certificate 配置项指向的文件(通常是 .pem 或 .crt) + section3Apache: Apache:查看 SSLCertificateFile 配置项 + section3Paths: 常见路径:/etc/ssl/certs/、/etc/letsencrypt/live/<域名>/fullchain.pem + section4Title: 4. PEM 格式示例 diff --git a/package.json b/package.json index 5738b6325a..57f9d2c34e 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,9 @@ "cron-validator": "^1.3.1", "cronstrue": "^2.26.0", "crypto-js": "^4.1.1", + "curlconverter": "^4.12.0", "date-fns": "^2.29.3", + "date-fns-tz": "^2.0.1", "dompurify": "^3.0.6", "email-normalizer": "^1.0.0", "emojilib": "^3.0.10", @@ -71,6 +73,7 @@ "iarna-toml-esm": "^3.0.5", "ibantools": "^4.3.3", "js-base64": "^3.7.6", + "js-beautify": "^1.15.4", "json5": "^2.2.3", "jwt-decode": "^3.1.2", "libphonenumber-js": "^1.10.28", @@ -90,6 +93,7 @@ "qrcode": "^1.5.1", "randexp": "^0.5.3", "sql-formatter": "^13.0.0", + "turndown": "^7.2.4", "ua-parser-js": "^1.0.35", "ulid": "^2.3.0", "unicode-emoji-json": "^0.4.0", @@ -115,6 +119,7 @@ "@types/bcryptjs": "^2.4.2", "@types/crypto-js": "^4.1.1", "@types/dompurify": "^3.0.5", + "@types/js-beautify": "^1.14.3", "@types/jsdom": "^21.0.0", "@types/lodash": "^4.14.192", "@types/mime-types": "^2.1.1", @@ -122,6 +127,7 @@ "@types/node": "^18.15.11", "@types/node-forge": "^1.3.2", "@types/qrcode": "^1.5.0", + "@types/turndown": "^5.0.6", "@types/ua-parser-js": "^0.7.36", "@types/uuid": "^9.0.0", "@unocss/eslint-config": "^0.57.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d11389323..78b12137f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -49,7 +49,7 @@ importers: version: 10.3.0(vue@3.3.4) '@vueuse/head': specifier: ^1.0.0 - version: 1.0.0(typescript@5.2.2)(vue@3.3.4) + version: 1.0.0(vue@3.3.4) '@vueuse/router': specifier: ^10.0.0 version: 10.0.0(vue-router@4.1.6(vue@3.3.4))(vue@3.3.4) @@ -77,9 +77,15 @@ importers: crypto-js: specifier: ^4.1.1 version: 4.1.1 + curlconverter: + specifier: ^4.12.0 + version: 4.12.0 date-fns: specifier: ^2.29.3 version: 2.29.3 + date-fns-tz: + specifier: ^2.0.1 + version: 2.0.1(date-fns@2.29.3) dompurify: specifier: ^3.0.6 version: 3.0.6 @@ -110,6 +116,9 @@ importers: js-base64: specifier: ^3.7.6 version: 3.7.7 + js-beautify: + specifier: ^1.15.4 + version: 1.15.4 json5: specifier: ^2.2.3 version: 2.2.3 @@ -167,6 +176,9 @@ importers: sql-formatter: specifier: ^13.0.0 version: 13.0.0 + turndown: + specifier: ^7.2.4 + version: 7.2.4 ua-parser-js: specifier: ^1.0.35 version: 1.0.35 @@ -237,6 +249,9 @@ importers: '@types/dompurify': specifier: ^3.0.5 version: 3.0.5 + '@types/js-beautify': + specifier: ^1.14.3 + version: 1.14.3 '@types/jsdom': specifier: ^21.0.0 version: 21.1.0 @@ -258,6 +273,9 @@ importers: '@types/qrcode': specifier: ^1.5.0 version: 1.5.0 + '@types/turndown': + specifier: ^5.0.6 + version: 5.0.6 '@types/ua-parser-js': specifier: ^0.7.36 version: 0.7.36 @@ -1523,6 +1541,10 @@ packages: vue-i18n-bridge: optional: true + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@it-tools/bip39@0.0.4': resolution: {integrity: sha512-0PWO7VKi6VALiFcm8z2WgxzSZ5wAko0OctBZ0I5+jjtSIXm3t1d54yrrHfgFOZDTyMpCXi638oLpzqexcfRtbA==} @@ -1610,6 +1632,9 @@ packages: '@mdit-vue/types@0.12.0': resolution: {integrity: sha512-mrC4y8n88BYvgcgzq9bvTlDgFyi2zuvzmPilRvRc3Uz1iIvq8mDhxJ0rHKFUNzPEScpDvJdIujqiDrulMqiudA==} + '@mixmark-io/domino@2.2.0': + resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1622,6 +1647,13 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@one-ini/wasm@0.1.1': + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@pkgr/utils@2.3.1': resolution: {integrity: sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -1913,6 +1945,9 @@ packages: '@types/fs-extra@11.0.1': resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==} + '@types/js-beautify@1.14.3': + resolution: {integrity: sha512-FMbQHz+qd9DoGvgLHxeqqVPaNRffpIu5ZjozwV8hf9JAGpIOzuAf4wGbRSo8LNITHqGjmmVjaMggTT5P4v4IHg==} + '@types/jsdom@21.1.0': resolution: {integrity: sha512-leWreJOdnuIxq9Y70tBVm/bvTuh31DSlF/r4l7Cfi4uhVQqLHD0Q4v301GMisEMwwbMgF7ZKxuZ+Jbd4NcdmRw==} @@ -2000,6 +2035,9 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/turndown@5.0.6': + resolution: {integrity: sha512-ru00MoyeeouE5BX4gRL+6m/BsDfbRayOskWqUvh7CLGW+UXxHQItqALa38kKnOiZPqJrtzJUgAC2+F0rL1S4Pg==} + '@types/ua-parser-js@0.7.36': resolution: {integrity: sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==} @@ -2303,9 +2341,6 @@ packages: '@vue/compiler-core@3.3.7': resolution: {integrity: sha512-pACdY6YnTNVLXsB86YD8OF9ihwpolzhhtdLVHhBL6do/ykr6kKXNYABRtNMGrsQXpEXXyAdwvWWkuTbs4MFtPQ==} - '@vue/compiler-core@3.5.13': - resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} - '@vue/compiler-dom@3.2.47': resolution: {integrity: sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==} @@ -2315,18 +2350,12 @@ packages: '@vue/compiler-dom@3.3.7': resolution: {integrity: sha512-0LwkyJjnUPssXv/d1vNJ0PKfBlDoQs7n81CbO6Q0zdL7H1EzqYRrTVXDqdBVqro0aJjo/FOa1qBAPVI4PGSHBw==} - '@vue/compiler-dom@3.5.13': - resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} - '@vue/compiler-sfc@3.2.47': resolution: {integrity: sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==} '@vue/compiler-sfc@3.3.4': resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} - '@vue/compiler-sfc@3.5.13': - resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} - '@vue/compiler-ssr@3.2.47': resolution: {integrity: sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==} @@ -2336,9 +2365,6 @@ packages: '@vue/compiler-ssr@3.3.7': resolution: {integrity: sha512-TxOfNVVeH3zgBc82kcUv+emNHo+vKnlRrkv8YvQU5+Y5LJGJwSNzcmLUoxD/dNzv0bhQ/F0s+InlgV0NrApJZg==} - '@vue/compiler-ssr@3.5.13': - resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} - '@vue/devtools-api@6.5.0': resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} @@ -2359,21 +2385,12 @@ packages: '@vue/reactivity@3.3.4': resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} - '@vue/reactivity@3.5.13': - resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} - '@vue/runtime-core@3.3.4': resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} - '@vue/runtime-core@3.5.13': - resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} - '@vue/runtime-dom@3.3.4': resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} - '@vue/runtime-dom@3.5.13': - resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} - '@vue/server-renderer@3.3.4': resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} peerDependencies: @@ -2384,11 +2401,6 @@ packages: peerDependencies: vue: 3.3.7 - '@vue/server-renderer@3.5.13': - resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} - peerDependencies: - vue: 3.5.13 - '@vue/shared@3.2.47': resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==} @@ -2398,9 +2410,6 @@ packages: '@vue/shared@3.3.7': resolution: {integrity: sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg==} - '@vue/shared@3.5.13': - resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} - '@vue/test-utils@2.3.2': resolution: {integrity: sha512-hJnVaYhbrIm0yBS0+e1Y0Sj85cMyAi+PAbK4JHqMRUZ6S622Goa+G7QzkRSyvCteG8wop7tipuEbHoZo26wsSA==} peerDependencies: @@ -2434,8 +2443,10 @@ packages: '@vueuse/shared@10.3.0': resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} - '@vueuse/shared@12.0.0': - resolution: {integrity: sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==} + '@vueuse/shared@14.3.0': + resolution: {integrity: sha512-bZpge9eSXwa4ToSiqJ7j6KRwhAsneMFoSz3LMWKQDkqimm3D/tbFlrklrs/IOqC8tEcYmXQZJ6N0UrjhBirVCg==} + peerDependencies: + vue: ^3.5.0 '@zhead/schema@1.0.0-beta.13': resolution: {integrity: sha512-P1A1vRGFBhITco8Iw4/hvnDYoE/SoVrd71dW1pBFdXJb3vP+pBtoOuhbEKy0ROJGOyzQuqvFibcwzyLlWMqNiQ==} @@ -2446,6 +2457,10 @@ packages: abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -2493,6 +2508,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -2505,6 +2524,10 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -2595,6 +2618,9 @@ packages: brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.1.1: + resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==} + braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -2848,6 +2874,10 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + crypto-js@4.1.1: resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==} @@ -2896,8 +2926,9 @@ packages: csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + curlconverter@4.12.0: + resolution: {integrity: sha512-NcwPKJgu9DkCH4gQsnjnXuUtPrhLhoNwvIYTTS5rRrsCC/X2flUswtgmeCyV9ePGszXzFReXk5y/CdBxrsAQ8Q==} + hasBin: true dash-get@1.0.2: resolution: {integrity: sha512-4FbVrHDwfOASx7uQVxeiCTo7ggSdYZbqs8lH+WU6ViypPlDbe9y6IP5VVUDQBv9DcnyaiPT5XT0UWHgJ64zLeQ==} @@ -2922,10 +2953,10 @@ packages: resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} engines: {node: '>= 0.4'} - date-fns-tz@2.0.0: - resolution: {integrity: sha512-OAtcLdB9vxSXTWHdT8b398ARImVwQMyjfYGkKD2zaGpHseG2UPHbHjXELReErZFxWdSLph3c2zOaaTyHfOhERQ==} + date-fns-tz@2.0.1: + resolution: {integrity: sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA==} peerDependencies: - date-fns: '>=2.0.0' + date-fns: 2.x date-fns@2.29.3: resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} @@ -3082,10 +3113,18 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + editorconfig@0.15.3: resolution: {integrity: sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==} hasBin: true + editorconfig@1.0.7: + resolution: {integrity: sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw==} + engines: {node: '>=14'} + hasBin: true + ejs@3.1.10: resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} engines: {node: '>=0.10.0'} @@ -3114,6 +3153,9 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + emojilib@3.0.10: resolution: {integrity: sha512-VQtCRroFykPTJaoEBEGFg5tI+rEluabjuaVDDbSftDtiRJ5GuqRG/LGV1mmDzkJP4bh5rzuEBOafMN68/YXQcQ==} @@ -3246,6 +3288,7 @@ packages: eslint-plugin-i@2.28.0-2: resolution: {integrity: sha512-z48kG4qmE4TmiLcxbmvxMT5ycwvPkXaWW0XpU1L768uZaTbiDbxsHMEdV24JHlOR1xDsPpKW39BfP/pRdYIwFA==} engines: {node: '>=12'} + deprecated: Please migrate to the brand new `eslint-plugin-import-x` instead peerDependencies: eslint: ^7.2.0 || ^8 @@ -3467,6 +3510,10 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -3564,12 +3611,18 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -3649,10 +3702,6 @@ packages: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} - hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} - engines: {node: '>= 0.4'} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -3817,9 +3866,6 @@ packages: is-core-module@2.13.0: resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - is-core-module@2.16.0: resolution: {integrity: sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==} engines: {node: '>= 0.4'} @@ -3984,6 +4030,9 @@ packages: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jake@10.8.7: resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==} engines: {node: '>=10'} @@ -4017,6 +4066,14 @@ packages: engines: {node: '>=10'} hasBin: true + js-beautify@1.15.4: + resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} + engines: {node: '>=14'} + hasBin: true + + js-cookie@3.0.8: + resolution: {integrity: sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw==} + js-sha256@0.9.0: resolution: {integrity: sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==} @@ -4170,6 +4227,9 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + lossless-json@4.3.0: + resolution: {integrity: sha512-ToxOC+SsduRmdSuoLZLYAr5zy1Qu7l5XhmPWM3zefCZ5IcrzW/h108qbJUKfOlDlhvhjUK84+8PSVX0kxnit0g==} + loupe@2.3.6: resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} @@ -4182,6 +4242,9 @@ packages: lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} @@ -4309,9 +4372,17 @@ packages: resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + mlly@1.4.0: resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==} @@ -4377,6 +4448,10 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + node-addon-api@8.8.0: + resolution: {integrity: sha512-c5Ko1fZJIJmzhFIkhRN76WTq+fC6tWnGy9CXA0fA+XygsWZmEwG8vmbkNqxMyoaa0Tin4djul49NzdVcJJcjeA==} + engines: {node: ^18 || ^20 || >= 21} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -4392,6 +4467,10 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + node-releases@2.0.12: resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} @@ -4406,6 +4485,11 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} hasBin: true + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -4495,6 +4579,9 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@0.2.7: resolution: {integrity: sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==} @@ -4549,6 +4636,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -4868,10 +4959,6 @@ packages: resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} hasBin: true - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - resolve@1.22.9: resolution: {integrity: sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==} hasBin: true @@ -5029,6 +5116,10 @@ packages: signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + sirv@2.0.4: resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} engines: {node: '>= 10'} @@ -5071,6 +5162,7 @@ packages: source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} @@ -5116,6 +5208,10 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string.prototype.matchall@4.0.11: resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} engines: {node: '>= 0.4'} @@ -5143,6 +5239,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + strip-bom-string@1.0.0: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} @@ -5272,6 +5372,17 @@ packages: resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} engines: {node: '>=14'} + tree-sitter-bash@0.23.3: + resolution: {integrity: sha512-36cg/GQ2YmIbeiBeqeuh4fBJ6i4kgVouDaqTxqih5ysPag+zHufyIaxMOFeM8CeplwAK/Luj1o5XHqgdAfoCZg==} + peerDependencies: + tree-sitter: ^0.21.1 + peerDependenciesMeta: + tree-sitter: + optional: true + + tree-sitter@0.21.1: + resolution: {integrity: sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==} + treemate@0.3.11: resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==} @@ -5298,6 +5409,10 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + turndown@7.2.4: + resolution: {integrity: sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==} + engines: {node: '>=18', npm: '>=9'} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -5701,14 +5816,6 @@ packages: vue@3.3.4: resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==} - vue@3.5.13: - resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - vuedraggable@4.1.0: resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==} peerDependencies: @@ -5733,6 +5840,9 @@ packages: resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} engines: {node: '>= 8'} + web-tree-sitter@0.24.7: + resolution: {integrity: sha512-CdC/TqVFbXqR+C51v38hv6wOPatKEUGxa39scAeFSm98wIhZxAYonhRQPSMmfZ2w7JDI0zQDdzdmgtNk06/krQ==} + webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} @@ -5859,6 +5969,14 @@ packages: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -6117,7 +6235,7 @@ snapshots: '@babel/traverse': 7.23.2 '@babel/types': 7.23.0 convert-source-map: 2.0.0 - debug: 4.3.4 + debug: 4.4.0 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -7000,7 +7118,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.22.10 '@babel/types': 7.22.10 - debug: 4.3.4 + debug: 4.4.0 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -7015,7 +7133,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.22.5 '@babel/parser': 7.22.5 '@babel/types': 7.22.5 - debug: 4.3.4 + debug: 4.4.0 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -7030,7 +7148,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.23.0 '@babel/types': 7.23.0 - debug: 4.3.4 + debug: 4.4.0 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -7228,7 +7346,7 @@ snapshots: '@eslint/eslintrc@2.1.2': dependencies: ajv: 6.12.6 - debug: 4.3.4 + debug: 4.4.0 espree: 9.6.1 globals: 13.20.0 ignore: 5.2.4 @@ -7244,7 +7362,7 @@ snapshots: '@humanwhocodes/config-array@0.11.10': dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 + debug: 4.4.0 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -7330,6 +7448,15 @@ snapshots: - rollup - supports-color + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + '@it-tools/bip39@0.0.4': dependencies: js-sha256: 0.9.0 @@ -7401,7 +7528,7 @@ snapshots: '@linaria/logger@4.0.0': dependencies: - debug: 4.3.4 + debug: 4.4.0 picocolors: 1.0.0 transitivePeerDependencies: - supports-color @@ -7441,6 +7568,8 @@ snapshots: '@mdit-vue/types@0.12.0': {} + '@mixmark-io/domino@2.2.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -7453,6 +7582,11 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 + '@one-ini/wasm@0.1.1': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + '@pkgr/utils@2.3.1': dependencies: cross-spawn: 7.0.3 @@ -7782,6 +7916,8 @@ snapshots: '@types/jsonfile': 6.1.1 '@types/node': 18.15.11 + '@types/js-beautify@1.14.3': {} + '@types/jsdom@21.1.0': dependencies: '@types/node': 18.15.11 @@ -7860,6 +7996,8 @@ snapshots: '@types/trusted-types@2.0.7': {} + '@types/turndown@5.0.6': {} + '@types/ua-parser-js@0.7.36': {} '@types/unist@2.0.6': {} @@ -7922,7 +8060,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 6.4.1(typescript@5.2.2) '@typescript-eslint/utils': 6.4.1(eslint@8.47.0)(typescript@5.2.2) - debug: 4.3.4 + debug: 4.4.0 eslint: 8.47.0 ts-api-utils: 1.0.1(typescript@5.2.2) optionalDependencies: @@ -7940,10 +8078,10 @@ snapshots: dependencies: '@typescript-eslint/types': 5.60.0 '@typescript-eslint/visitor-keys': 5.60.0 - debug: 4.3.4 + debug: 4.4.0 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.5.4 + semver: 7.6.3 tsutils: 3.21.0(typescript@5.2.2) optionalDependencies: typescript: 5.2.2 @@ -7954,10 +8092,10 @@ snapshots: dependencies: '@typescript-eslint/types': 6.4.1 '@typescript-eslint/visitor-keys': 6.4.1 - debug: 4.3.4 + debug: 4.4.0 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.5.4 + semver: 7.6.3 ts-api-utils: 1.0.1(typescript@5.2.2) optionalDependencies: typescript: 5.2.2 @@ -7968,10 +8106,10 @@ snapshots: dependencies: '@typescript-eslint/types': 6.9.1 '@typescript-eslint/visitor-keys': 6.9.1 - debug: 4.3.4 + debug: 4.4.0 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.5.4 + semver: 7.6.3 ts-api-utils: 1.0.1(typescript@5.2.2) optionalDependencies: typescript: 5.2.2 @@ -7988,7 +8126,7 @@ snapshots: '@typescript-eslint/typescript-estree': 5.60.0(typescript@5.2.2) eslint: 8.47.0 eslint-scope: 5.1.1 - semver: 7.5.4 + semver: 7.6.3 transitivePeerDependencies: - supports-color - typescript @@ -8002,7 +8140,7 @@ snapshots: '@typescript-eslint/types': 6.4.1 '@typescript-eslint/typescript-estree': 6.4.1(typescript@5.2.2) eslint: 8.47.0 - semver: 7.5.4 + semver: 7.6.3 transitivePeerDependencies: - supports-color - typescript @@ -8016,7 +8154,7 @@ snapshots: '@typescript-eslint/types': 6.9.1 '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.2.2) eslint: 8.47.0 - semver: 7.5.4 + semver: 7.6.3 transitivePeerDependencies: - supports-color - typescript @@ -8049,15 +8187,13 @@ snapshots: dependencies: '@unhead/schema': 0.5.1 - '@unhead/vue@0.5.1(typescript@5.2.2)(vue@3.3.4)': + '@unhead/vue@0.5.1(vue@3.3.4)': dependencies: '@unhead/dom': 0.5.1 '@unhead/schema': 0.5.1 - '@vueuse/shared': 12.0.0(typescript@5.2.2) + '@vueuse/shared': 14.3.0(vue@3.3.4) unhead: 0.5.1 vue: 3.3.4 - transitivePeerDependencies: - - typescript '@unocss/astro@0.65.1(rollup@2.79.2)(vite@4.4.9(@types/node@18.15.11)(less@4.1.3)(terser@5.37.0))(vue@3.3.4)': dependencies: @@ -8341,14 +8477,6 @@ snapshots: source-map-js: 1.0.2 optional: true - '@vue/compiler-core@3.5.13': - dependencies: - '@babel/parser': 7.26.3 - '@vue/shared': 3.5.13 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - '@vue/compiler-dom@3.2.47': dependencies: '@vue/compiler-core': 3.2.47 @@ -8365,11 +8493,6 @@ snapshots: '@vue/shared': 3.3.7 optional: true - '@vue/compiler-dom@3.5.13': - dependencies: - '@vue/compiler-core': 3.5.13 - '@vue/shared': 3.5.13 - '@vue/compiler-sfc@3.2.47': dependencies: '@babel/parser': 7.21.4 @@ -8396,18 +8519,6 @@ snapshots: postcss: 8.4.28 source-map-js: 1.0.2 - '@vue/compiler-sfc@3.5.13': - dependencies: - '@babel/parser': 7.26.3 - '@vue/compiler-core': 3.5.13 - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 - estree-walker: 2.0.2 - magic-string: 0.30.15 - postcss: 8.4.49 - source-map-js: 1.2.1 - '@vue/compiler-ssr@3.2.47': dependencies: '@vue/compiler-dom': 3.2.47 @@ -8424,11 +8535,6 @@ snapshots: '@vue/shared': 3.3.7 optional: true - '@vue/compiler-ssr@3.5.13': - dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/shared': 3.5.13 - '@vue/devtools-api@6.5.0': {} '@vue/language-core@1.8.1(typescript@5.2.2)': @@ -8438,7 +8544,7 @@ snapshots: '@vue/compiler-dom': 3.3.4 '@vue/reactivity': 3.3.4 '@vue/shared': 3.3.4 - minimatch: 9.0.1 + minimatch: 9.0.9 muggle-string: 0.3.1 vue-template-compiler: 2.7.14 optionalDependencies: @@ -8464,33 +8570,17 @@ snapshots: dependencies: '@vue/shared': 3.3.4 - '@vue/reactivity@3.5.13': - dependencies: - '@vue/shared': 3.5.13 - '@vue/runtime-core@3.3.4': dependencies: '@vue/reactivity': 3.3.4 '@vue/shared': 3.3.4 - '@vue/runtime-core@3.5.13': - dependencies: - '@vue/reactivity': 3.5.13 - '@vue/shared': 3.5.13 - '@vue/runtime-dom@3.3.4': dependencies: '@vue/runtime-core': 3.3.4 '@vue/shared': 3.3.4 csstype: 3.1.2 - '@vue/runtime-dom@3.5.13': - dependencies: - '@vue/reactivity': 3.5.13 - '@vue/runtime-core': 3.5.13 - '@vue/shared': 3.5.13 - csstype: 3.1.3 - '@vue/server-renderer@3.3.4(vue@3.3.4)': dependencies: '@vue/compiler-ssr': 3.3.4 @@ -8504,12 +8594,6 @@ snapshots: vue: 3.3.4 optional: true - '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.2.2))': - dependencies: - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 - vue: 3.5.13(typescript@5.2.2) - '@vue/shared@3.2.47': {} '@vue/shared@3.3.4': {} @@ -8517,8 +8601,6 @@ snapshots: '@vue/shared@3.3.7': optional: true - '@vue/shared@3.5.13': {} - '@vue/test-utils@2.3.2(vue@3.3.4)': dependencies: js-beautify: 1.14.6 @@ -8546,14 +8628,12 @@ snapshots: - '@vue/composition-api' - vue - '@vueuse/head@1.0.0(typescript@5.2.2)(vue@3.3.4)': + '@vueuse/head@1.0.0(vue@3.3.4)': dependencies: '@unhead/schema': 0.5.1 '@unhead/ssr': 0.5.1 - '@unhead/vue': 0.5.1(typescript@5.2.2)(vue@3.3.4) + '@unhead/vue': 0.5.1(vue@3.3.4) vue: 3.3.4 - transitivePeerDependencies: - - typescript '@vueuse/metadata@10.3.0': {} @@ -8580,11 +8660,9 @@ snapshots: - '@vue/composition-api' - vue - '@vueuse/shared@12.0.0(typescript@5.2.2)': + '@vueuse/shared@14.3.0(vue@3.3.4)': dependencies: - vue: 3.5.13(typescript@5.2.2) - transitivePeerDependencies: - - typescript + vue: 3.3.4 '@zhead/schema@1.0.0-beta.13': {} @@ -8592,6 +8670,8 @@ snapshots: abbrev@1.1.1: {} + abbrev@2.0.0: {} + acorn-jsx@5.3.2(acorn@8.10.0): dependencies: acorn: 8.10.0 @@ -8608,7 +8688,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.4 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -8630,6 +8710,8 @@ snapshots: ansi-regex@5.0.1: {} + ansi-regex@6.2.2: {} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -8640,6 +8722,8 @@ snapshots: ansi-styles@5.2.0: {} + ansi-styles@6.2.3: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -8740,6 +8824,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@2.1.1: + dependencies: + balanced-match: 1.0.2 + braces@3.0.2: dependencies: fill-range: 7.0.1 @@ -8780,7 +8868,7 @@ snapshots: builtins@5.0.1: dependencies: - semver: 7.5.4 + semver: 7.6.3 bundle-require@5.0.0(esbuild@0.23.1): dependencies: @@ -9036,6 +9124,12 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + crypto-js@4.1.1: {} crypto-random-string@2.0.0: {} @@ -9084,7 +9178,14 @@ snapshots: csstype@3.1.2: {} - csstype@3.1.3: {} + curlconverter@4.12.0: + dependencies: + jsesc: 3.1.0 + lossless-json: 4.3.0 + tree-sitter: 0.21.1 + tree-sitter-bash: 0.23.3(tree-sitter@0.21.1) + web-tree-sitter: 0.24.7 + yamljs: 0.3.0 dash-get@1.0.2: {} @@ -9114,7 +9215,11 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - date-fns-tz@2.0.0(date-fns@2.30.0): + date-fns-tz@2.0.1(date-fns@2.29.3): + dependencies: + date-fns: 2.29.3 + + date-fns-tz@2.0.1(date-fns@2.30.0): dependencies: date-fns: 2.30.0 @@ -9243,6 +9348,8 @@ snapshots: duplexer@0.1.2: {} + eastasianwidth@0.2.0: {} + editorconfig@0.15.3: dependencies: commander: 2.20.3 @@ -9250,6 +9357,13 @@ snapshots: semver: 5.7.2 sigmund: 1.0.1 + editorconfig@1.0.7: + dependencies: + '@one-ini/wasm': 0.1.1 + commander: 10.0.0 + minimatch: 9.0.9 + semver: 7.6.3 + ejs@3.1.10: dependencies: jake: 10.9.2 @@ -9272,6 +9386,8 @@ snapshots: emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + emojilib@3.0.10: {} encode-utf8@1.0.3: {} @@ -9547,7 +9663,7 @@ snapshots: esquery: 1.5.0 indent-string: 4.0.0 is-builtin-module: 3.2.1 - jsesc: 3.0.2 + jsesc: 3.1.0 lodash: 4.17.21 pluralize: 8.0.0 read-pkg-up: 7.0.1 @@ -9778,6 +9894,11 @@ snapshots: dependencies: is-callable: 1.2.7 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + form-data@4.0.0: dependencies: asynckit: 0.4.0 @@ -9879,6 +10000,15 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -9971,10 +10101,6 @@ snapshots: dependencies: function-bind: 1.1.2 - hasown@2.0.0: - dependencies: - function-bind: 1.1.2 - hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -10016,14 +10142,14 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.4.0 transitivePeerDependencies: - supports-color https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -10160,10 +10286,6 @@ snapshots: dependencies: has: 1.0.3 - is-core-module@2.13.1: - dependencies: - hasown: 2.0.0 - is-core-module@2.16.0: dependencies: hasown: 2.0.2 @@ -10299,6 +10421,12 @@ snapshots: isobject@3.0.1: {} + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jake@10.8.7: dependencies: async: 3.2.4 @@ -10330,6 +10458,16 @@ snapshots: glob: 8.1.0 nopt: 6.0.0 + js-beautify@1.15.4: + dependencies: + config-chain: 1.1.13 + editorconfig: 1.0.7 + glob: 10.4.5 + js-cookie: 3.0.8 + nopt: 7.2.1 + + js-cookie@3.0.8: {} + js-sha256@0.9.0: {} js-tokens@4.0.0: {} @@ -10485,6 +10623,8 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + lossless-json@4.3.0: {} + loupe@2.3.6: dependencies: get-func-name: 2.0.0 @@ -10499,6 +10639,8 @@ snapshots: dependencies: tslib: 2.5.0 + lru-cache@10.4.3: {} + lru-cache@4.1.5: dependencies: pseudomap: 1.0.2 @@ -10632,14 +10774,20 @@ snapshots: minimatch@5.1.6: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.1.1 minimatch@9.0.1: dependencies: brace-expansion: 2.0.1 + minimatch@9.0.9: + dependencies: + brace-expansion: 2.1.1 + minimist@1.2.8: {} + minipass@7.1.3: {} + mlly@1.4.0: dependencies: acorn: 8.11.2 @@ -10683,7 +10831,7 @@ snapshots: async-validator: 4.2.5 css-render: 0.15.12 date-fns: 2.30.0 - date-fns-tz: 2.0.0(date-fns@2.30.0) + date-fns-tz: 2.0.1(date-fns@2.30.0) evtd: 0.2.4 highlight.js: 11.9.0 lodash: 4.17.21 @@ -10728,6 +10876,8 @@ snapshots: lower-case: 2.0.2 tslib: 2.5.0 + node-addon-api@8.8.0: {} + node-domexception@1.0.0: {} node-fetch-native@1.6.4: {} @@ -10740,6 +10890,8 @@ snapshots: node-forge@1.3.1: {} + node-gyp-build@4.8.4: {} + node-releases@2.0.12: {} node-releases@2.0.13: {} @@ -10750,10 +10902,14 @@ snapshots: dependencies: abbrev: 1.1.1 + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.8 + resolve: 1.22.9 semver: 5.7.2 validate-npm-package-license: 3.0.4 @@ -10855,6 +11011,8 @@ snapshots: p-try@2.2.0: {} + package-json-from-dist@1.0.1: {} + package-manager-detector@0.2.7: {} param-case@2.1.1: @@ -10919,6 +11077,11 @@ snapshots: path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + path-type@4.0.0: {} pathe@1.1.1: {} @@ -11261,19 +11424,13 @@ snapshots: resolve@1.22.2: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.16.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 resolve@1.22.4: dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - resolve@1.22.8: - dependencies: - is-core-module: 2.13.1 + is-core-module: 2.16.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -11441,6 +11598,8 @@ snapshots: signal-exit@3.0.7: {} + signal-exit@4.1.0: {} + sirv@2.0.4: dependencies: '@polka/url': 1.0.0-next.28 @@ -11527,6 +11686,12 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + string.prototype.matchall@4.0.11: dependencies: call-bind: 1.0.8 @@ -11579,6 +11744,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + strip-bom-string@1.0.0: {} strip-comments@2.0.1: {} @@ -11702,6 +11871,18 @@ snapshots: dependencies: punycode: 2.3.0 + tree-sitter-bash@0.23.3(tree-sitter@0.21.1): + dependencies: + node-addon-api: 8.8.0 + node-gyp-build: 4.8.4 + optionalDependencies: + tree-sitter: 0.21.1 + + tree-sitter@0.21.1: + dependencies: + node-addon-api: 8.8.0 + node-gyp-build: 4.8.4 + treemate@0.3.11: {} ts-api-utils@1.0.1(typescript@5.2.2): @@ -11724,6 +11905,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + turndown@7.2.4: + dependencies: + '@mixmark-io/domino': 2.2.0 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -12018,7 +12203,7 @@ snapshots: vite-node@0.34.0(@types/node@18.15.11)(less@4.1.3)(terser@5.37.0): dependencies: cac: 6.7.14 - debug: 4.3.4 + debug: 4.4.0 mlly: 1.4.0 pathe: 1.1.1 picocolors: 1.0.0 @@ -12125,14 +12310,14 @@ snapshots: vue-eslint-parser@9.3.1(eslint@8.47.0): dependencies: - debug: 4.3.4 + debug: 4.4.0 eslint: 8.47.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 esquery: 1.5.0 lodash: 4.17.21 - semver: 7.5.4 + semver: 7.6.3 transitivePeerDependencies: - supports-color @@ -12180,16 +12365,6 @@ snapshots: '@vue/server-renderer': 3.3.4(vue@3.3.4) '@vue/shared': 3.3.4 - vue@3.5.13(typescript@5.2.2): - dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-sfc': 3.5.13 - '@vue/runtime-dom': 3.5.13 - '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.2.2)) - '@vue/shared': 3.5.13 - optionalDependencies: - typescript: 5.2.2 - vuedraggable@4.1.0(vue@3.3.4): dependencies: sortablejs: 1.14.0 @@ -12218,6 +12393,8 @@ snapshots: web-streams-polyfill@3.2.1: {} + web-tree-sitter@0.24.7: {} + webidl-conversions@4.0.2: {} webidl-conversions@7.0.0: {} @@ -12425,6 +12602,18 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + wrappy@1.0.2: {} ws@8.13.0: {} diff --git a/public/tree-sitter-bash.wasm b/public/tree-sitter-bash.wasm new file mode 100755 index 0000000000..e6f8540ef5 Binary files /dev/null and b/public/tree-sitter-bash.wasm differ diff --git a/public/tree-sitter.wasm b/public/tree-sitter.wasm new file mode 100755 index 0000000000..8f6156796b Binary files /dev/null and b/public/tree-sitter.wasm differ diff --git a/src/components/TextareaCopyable.vue b/src/components/TextareaCopyable.vue index 9585177d17..c8e7ca6bb1 100644 --- a/src/components/TextareaCopyable.vue +++ b/src/components/TextareaCopyable.vue @@ -8,6 +8,11 @@ import xmlHljs from 'highlight.js/lib/languages/xml'; import yamlHljs from 'highlight.js/lib/languages/yaml'; import iniHljs from 'highlight.js/lib/languages/ini'; import markdownHljs from 'highlight.js/lib/languages/markdown'; +import typescriptHljs from 'highlight.js/lib/languages/typescript'; +import javascriptHljs from 'highlight.js/lib/languages/javascript'; +import pythonHljs from 'highlight.js/lib/languages/python'; +import goHljs from 'highlight.js/lib/languages/go'; +import cssHljs from 'highlight.js/lib/languages/css'; import { useCopy } from '@/composable/copy'; const props = withDefaults( @@ -32,6 +37,11 @@ hljs.registerLanguage('xml', xmlHljs); hljs.registerLanguage('yaml', yamlHljs); hljs.registerLanguage('toml', iniHljs); hljs.registerLanguage('markdown', markdownHljs); +hljs.registerLanguage('typescript', typescriptHljs); +hljs.registerLanguage('javascript', javascriptHljs); +hljs.registerLanguage('python', pythonHljs); +hljs.registerLanguage('go', goHljs); +hljs.registerLanguage('css', cssHljs); const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(props); const { height } = followHeightOf.value ? useElementSize(followHeightOf) : { height: ref(null) }; diff --git a/src/layouts/tool.layout.vue b/src/layouts/tool.layout.vue index ad34c4a0dd..101c83f9b8 100644 --- a/src/layouts/tool.layout.vue +++ b/src/layouts/tool.layout.vue @@ -102,6 +102,7 @@ const toolDescription = computed(() => t(`tools.${i18nKey.value}.descrip margin: 0; opacity: 0.7; + white-space: pre-line; } } } diff --git a/src/main.ts b/src/main.ts index 19d28bf2ee..8105ca4c30 100644 --- a/src/main.ts +++ b/src/main.ts @@ -16,6 +16,26 @@ import { i18nPlugin } from './plugins/i18n.plugin'; registerSW(); +// Reload the page the moment a newly installed service worker takes control. +// vite-plugin-pwa's autoUpdate relies on the Workbox `activated(isUpdate)` event, but +// with `skipWaiting` the new SW can install→activate so fast that Workbox-window never +// attaches its lifecycle listeners and `activated` is missed — leaving users stuck on +// stale content until a hard refresh. `controllerchange` is fired directly by the +// browser when the new SW calls `clients.claim()`, so it fires reliably regardless of +// that race. We only reload on an actual handover (controller already existed), not on +// the very first install. +if ('serviceWorker' in navigator) { + const hadController = navigator.serviceWorker.controller !== null; + let refreshing = false; + navigator.serviceWorker.addEventListener('controllerchange', () => { + if (!hadController || refreshing) { + return; + } + refreshing = true; + globalThis.location.reload(); + }); +} + const app = createApp(App); app.use(createPinia()); diff --git a/src/tools/byte-unit-converter/byte-unit-converter.vue b/src/tools/byte-unit-converter/byte-unit-converter.vue new file mode 100644 index 0000000000..8fef510d51 --- /dev/null +++ b/src/tools/byte-unit-converter/byte-unit-converter.vue @@ -0,0 +1,82 @@ + + + diff --git a/src/tools/byte-unit-converter/index.ts b/src/tools/byte-unit-converter/index.ts new file mode 100644 index 0000000000..e6663efa23 --- /dev/null +++ b/src/tools/byte-unit-converter/index.ts @@ -0,0 +1,13 @@ +import { Binary } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: translate('tools.byte-unit-converter.title'), + path: '/byte-unit-converter', + description: translate('tools.byte-unit-converter.description'), + keywords: ['byte', 'data', 'unit', 'converter', 'KB', 'MB', 'GB', 'TB', 'PB', 'kibibyte', 'mebibyte', 'gibibyte', 'size'], + component: () => import('./byte-unit-converter.vue'), + icon: Binary, + createdAt: new Date('2026-06-04'), +}); diff --git a/src/tools/css-js-prettify-minify/css-js-prettify-minify.vue b/src/tools/css-js-prettify-minify/css-js-prettify-minify.vue new file mode 100644 index 0000000000..53569f51e2 --- /dev/null +++ b/src/tools/css-js-prettify-minify/css-js-prettify-minify.vue @@ -0,0 +1,111 @@ + + + diff --git a/src/tools/css-js-prettify-minify/index.ts b/src/tools/css-js-prettify-minify/index.ts new file mode 100644 index 0000000000..be1e37030f --- /dev/null +++ b/src/tools/css-js-prettify-minify/index.ts @@ -0,0 +1,13 @@ +import { Code } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: translate('tools.css-js-prettify-minify.title'), + path: '/css-js-prettify-minify', + description: translate('tools.css-js-prettify-minify.description'), + keywords: ['css', 'javascript', 'js', 'prettify', 'minify', 'beautify', 'format', 'uglify', 'compress', 'formatter'], + component: () => import('./css-js-prettify-minify.vue'), + icon: Code, + createdAt: new Date('2026-06-04'), +}); diff --git a/src/tools/curl-to-code/curl-to-code.vue b/src/tools/curl-to-code/curl-to-code.vue new file mode 100644 index 0000000000..2ad0a664cd --- /dev/null +++ b/src/tools/curl-to-code/curl-to-code.vue @@ -0,0 +1,68 @@ + + + diff --git a/src/tools/curl-to-code/index.ts b/src/tools/curl-to-code/index.ts new file mode 100644 index 0000000000..e237b36d2c --- /dev/null +++ b/src/tools/curl-to-code/index.ts @@ -0,0 +1,13 @@ +import { Terminal } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: translate('tools.curl-to-code.title'), + path: '/curl-to-code', + description: translate('tools.curl-to-code.description'), + keywords: ['curl', 'code', 'converter', 'python', 'javascript', 'go', 'fetch', 'requests', 'http', 'api'], + component: () => import('./curl-to-code.vue'), + icon: Terminal, + createdAt: new Date('2026-06-04'), +}); diff --git a/src/tools/date-calculator/date-calculator.vue b/src/tools/date-calculator/date-calculator.vue new file mode 100644 index 0000000000..621b2c4de4 --- /dev/null +++ b/src/tools/date-calculator/date-calculator.vue @@ -0,0 +1,141 @@ + + + + + diff --git a/src/tools/date-calculator/index.ts b/src/tools/date-calculator/index.ts new file mode 100644 index 0000000000..2ab05e53cc --- /dev/null +++ b/src/tools/date-calculator/index.ts @@ -0,0 +1,13 @@ +import { Calculator } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: translate('tools.date-calculator.title'), + path: '/date-calculator', + description: translate('tools.date-calculator.description'), + keywords: ['date', 'difference', 'days', 'calculator', 'add', 'subtract', 'duration', 'between', 'offset'], + component: () => import('./date-calculator.vue'), + icon: Calculator, + createdAt: new Date('2026-06-15'), +}); diff --git a/src/tools/dns-query/dns-query.service.ts b/src/tools/dns-query/dns-query.service.ts new file mode 100644 index 0000000000..d22213881b --- /dev/null +++ b/src/tools/dns-query/dns-query.service.ts @@ -0,0 +1,166 @@ +export const defaultRecordTypes = ['A', 'AAAA', 'CNAME', 'MX', 'TXT', 'NS', 'SOA'] as const; + +export const allRecordTypes = ['A', 'AAAA', 'CNAME', 'MX', 'TXT', 'NS', 'SOA', 'SRV', 'CAA', 'PTR'] as const; + +export type DnsRecordType = typeof allRecordTypes[number]; + +const dnsTypeNumberToName: Record = { + 1: 'A', + 2: 'NS', + 5: 'CNAME', + 6: 'SOA', + 12: 'PTR', + 15: 'MX', + 16: 'TXT', + 28: 'AAAA', + 33: 'SRV', + 257: 'CAA', +}; + +export function getTypeName(typeNumber: number): string { + return dnsTypeNumberToName[typeNumber] ?? `TYPE${typeNumber}`; +} + +export interface DnsAnswer { + name: string + type: number + TTL: number + data: string +} + +export interface DnsResponse { + Status: number + TC: boolean + RD: boolean + RA: boolean + AD: boolean + CD: boolean + Question: { name: string; type: number }[] + Answer?: DnsAnswer[] + Authority?: DnsAnswer[] +} + +export async function queryDns({ domain, type }: { domain: string; type: string }): Promise { + const url = `https://cloudflare-dns.com/dns-query?name=${encodeURIComponent(domain)}&type=${encodeURIComponent(type)}`; + + const response = await fetch(url, { + headers: { Accept: 'application/dns-json' }, + }); + + if (!response.ok) { + throw new Error(`DNS query failed: ${response.status} ${response.statusText}`); + } + + return response.json(); +} + +export async function queryAllDns(domain: string, types: readonly string[]): Promise { + const results = await Promise.allSettled( + types.map(type => queryDns({ domain, type })), + ); + + const seen = new Set(); + const answers: DnsAnswer[] = []; + for (const result of results) { + if (result.status === 'fulfilled' && result.value.Answer) { + for (const answer of result.value.Answer) { + const key = `${answer.type}|${answer.name}|${answer.data}`; + if (!seen.has(key)) { + seen.add(key); + answers.push(answer); + } + } + } + } + + return answers; +} + +export function formatDnsRecords(answers: DnsAnswer[]): string { + if (answers.length === 0) { + return 'No records found'; + } + + const lines = answers.map((answer) => { + const typeName = getTypeName(answer.type); + return `${typeName}\t${answer.name}\t${answer.TTL}s\t${answer.data}`; + }); + + return lines.join('\n'); +} + +export interface WhoisInfo { + domainName: string + registrar: string + registrationDate: string + expirationDate: string + updatedDate: string + status: string[] + nameServers: string[] + dnssec: string + registrantCountry: string + registrantProvince: string +} + +export async function queryWhois(domain: string): Promise { + try { + const response = await fetch(`https://rdap.org/domain/${encodeURIComponent(domain)}`); + if (!response.ok) { + return null; + } + const data = await response.json(); + return parseRdapResponse(data, domain); + } + catch { + return null; + } +} + +function parseRdapResponse(data: any, domain: string): WhoisInfo { + const events = data.events ?? []; + const findEvent = (action: string) => { + const ev = events.find((e: any) => e.eventAction === action); + return ev?.eventDate ? formatDate(ev.eventDate) : ''; + }; + + const registrarEntity = (data.entities ?? []).find((e: any) => e.roles?.includes('registrar')); + const registrar = registrarEntity?.vcardArray?.[1] + ?.find((v: any) => v[0] === 'fn')?.[3] ?? ''; + + const registrantEntity = (data.entities ?? []).find((e: any) => e.roles?.includes('registrant')); + const registrantVcard = registrantEntity?.vcardArray?.[1] ?? []; + const adr = registrantVcard.find((v: any) => v[0] === 'adr'); + const registrantCountry = adr?.[1]?.cc ?? ''; + const registrantProvince = adr?.[3]?.[4] ?? ''; + + const nameServers = (data.nameservers ?? []) + .map((ns: any) => (ns.ldhName ?? '').replace(/\.$/, '')) + .filter(Boolean); + + const status = (data.status ?? []).map((s: string) => s.replaceAll(' ', '')); + + const dnssec = data.secureDNS?.delegationSigned ? 'signed' : 'unsigned'; + + return { + domainName: data.ldhName ?? domain, + registrar, + registrationDate: findEvent('registration'), + expirationDate: findEvent('expiration'), + updatedDate: findEvent('last changed'), + status, + nameServers, + dnssec, + registrantCountry, + registrantProvince, + }; +} + +function formatDate(isoDate: string): string { + try { + const d = new Date(isoDate); + return `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, '0')}-${String(d.getUTCDate()).padStart(2, '0')}`; + } + catch { + return isoDate; + } +} diff --git a/src/tools/dns-query/dns-query.vue b/src/tools/dns-query/dns-query.vue new file mode 100644 index 0000000000..9082754383 --- /dev/null +++ b/src/tools/dns-query/dns-query.vue @@ -0,0 +1,216 @@ + + + diff --git a/src/tools/dns-query/index.ts b/src/tools/dns-query/index.ts new file mode 100644 index 0000000000..51e068bda2 --- /dev/null +++ b/src/tools/dns-query/index.ts @@ -0,0 +1,13 @@ +import { World } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: translate('tools.dns-query.title'), + path: '/dns-query', + description: translate('tools.dns-query.description'), + keywords: ['dns', 'query', 'lookup', 'resolve', 'domain', 'A', 'AAAA', 'CNAME', 'MX', 'TXT', 'NS', 'SOA', 'network', 'devops'], + component: () => import('./dns-query.vue'), + icon: World, + createdAt: new Date('2026-06-12'), +}); diff --git a/src/tools/html-to-markdown/html-to-markdown.vue b/src/tools/html-to-markdown/html-to-markdown.vue new file mode 100644 index 0000000000..ea64944a32 --- /dev/null +++ b/src/tools/html-to-markdown/html-to-markdown.vue @@ -0,0 +1,28 @@ + + + diff --git a/src/tools/html-to-markdown/index.ts b/src/tools/html-to-markdown/index.ts new file mode 100644 index 0000000000..4fa2ac2407 --- /dev/null +++ b/src/tools/html-to-markdown/index.ts @@ -0,0 +1,13 @@ +import { Markdown } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: translate('tools.html-to-markdown.title'), + path: '/html-to-markdown', + description: translate('tools.html-to-markdown.description'), + keywords: ['html', 'markdown', 'converter', 'turndown', 'markup'], + component: () => import('./html-to-markdown.vue'), + icon: Markdown, + createdAt: new Date('2026-06-04'), +}); diff --git a/src/tools/index.ts b/src/tools/index.ts index 388cfaf494..3414b67556 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,7 +1,13 @@ 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 byteUnitConverter } from './byte-unit-converter'; +import { tool as cssJsPrettifyMinify } from './css-js-prettify-minify'; +import { tool as curlToCode } from './curl-to-code'; +import { tool as dnsQuery } from './dns-query'; import { tool as emailNormalizer } from './email-normalizer'; +import { tool as htmlToMarkdown } from './html-to-markdown'; +import { tool as jsonToTypes } from './json-to-types'; import { tool as asciiTextDrawer } from './ascii-text-drawer'; @@ -43,6 +49,7 @@ import { tool as ipv4SubnetCalculator } from './ipv4-subnet-calculator'; import { tool as dockerRunToDockerComposeConverter } from './docker-run-to-docker-compose-converter'; import { tool as htmlWysiwygEditor } from './html-wysiwyg-editor'; import { tool as rsaKeyPairGenerator } from './rsa-key-pair-generator'; +import { tool as sslCertificateParser } from './ssl-certificate-parser'; import { tool as textToNatoAlphabet } from './text-to-nato-alphabet'; import { tool as slugifyString } from './slugify-string'; import { tool as keycodeInfo } from './keycode-info'; @@ -54,6 +61,7 @@ import { tool as chmodCalculator } from './chmod-calculator'; import { tool as chronometer } from './chronometer'; import { tool as colorConverter } from './color-converter'; import { tool as crontabGenerator } from './crontab-generator'; +import { tool as dateCalculator } from './date-calculator'; import { tool as dateTimeConverter } from './date-time-converter'; import { tool as deviceInformation } from './device-information'; import { tool as cypher } from './encryption'; @@ -93,9 +101,34 @@ export const toolsByCategory: ToolCategory[] = [ name: 'Crypto', components: [tokenGenerator, hashText, bcrypt, uuidGenerator, ulidGenerator, cypher, bip39, hmacGenerator, rsaKeyPairGenerator, passwordStrengthAnalyser, pdfSignatureChecker], }, + { + name: 'Web', + components: [ + dnsQuery, + sslCertificateParser, + urlEncoder, + htmlEntities, + urlParser, + deviceInformation, + basicAuthGenerator, + metaTagGenerator, + otpCodeGeneratorAndValidator, + mimeTypes, + jwtParser, + keycodeInfo, + slugifyString, + htmlWysiwygEditor, + userAgentParser, + httpStatusCodes, + jsonDiff, + safelinkDecoder, + ], + }, { name: 'Converter', components: [ + byteUnitConverter, + dateCalculator, dateTimeConverter, baseConverter, romanNumeralConverter, @@ -118,34 +151,13 @@ export const toolsByCategory: ToolCategory[] = [ markdownToHtml, ], }, - { - name: 'Web', - components: [ - urlEncoder, - htmlEntities, - urlParser, - deviceInformation, - basicAuthGenerator, - metaTagGenerator, - otpCodeGeneratorAndValidator, - mimeTypes, - jwtParser, - keycodeInfo, - slugifyString, - htmlWysiwygEditor, - userAgentParser, - httpStatusCodes, - jsonDiff, - safelinkDecoder, - ], - }, - { - name: 'Images and videos', - components: [qrCodeGenerator, wifiQrCodeGenerator, svgPlaceholderGenerator, cameraRecorder], - }, { name: 'Development', components: [ + cssJsPrettifyMinify, + htmlToMarkdown, + jsonToTypes, + curlToCode, gitMemo, randomPortGenerator, crontabGenerator, @@ -162,6 +174,10 @@ export const toolsByCategory: ToolCategory[] = [ regexMemo, ], }, + { + name: 'Images and videos', + components: [qrCodeGenerator, wifiQrCodeGenerator, svgPlaceholderGenerator, cameraRecorder], + }, { name: 'Network', components: [ipv4SubnetCalculator, ipv4AddressConverter, ipv4RangeExpander, macAddressLookup, macAddressGenerator, ipv6UlaGenerator], diff --git a/src/tools/json-to-types/index.ts b/src/tools/json-to-types/index.ts new file mode 100644 index 0000000000..6e698f155c --- /dev/null +++ b/src/tools/json-to-types/index.ts @@ -0,0 +1,13 @@ +import { Braces } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: translate('tools.json-to-types.title'), + path: '/json-to-types', + description: translate('tools.json-to-types.description'), + keywords: ['json', 'typescript', 'go', 'struct', 'interface', 'type', 'convert', 'generate', 'definition'], + component: () => import('./json-to-types.vue'), + icon: Braces, + createdAt: new Date('2026-06-04'), +}); diff --git a/src/tools/json-to-types/json-to-types.service.ts b/src/tools/json-to-types/json-to-types.service.ts new file mode 100644 index 0000000000..49e6beb572 --- /dev/null +++ b/src/tools/json-to-types/json-to-types.service.ts @@ -0,0 +1,115 @@ +function capitalize(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +function toPascalCase(str: string): string { + return str + .replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : '')) + .replace(/^./, s => s.toUpperCase()); +} + +function inferTsType(value: unknown, name: string, interfaces: Map): string { + if (value === null) { + return 'null'; + } + + switch (typeof value) { + case 'string': + return 'string'; + case 'number': + return 'number'; + case 'boolean': + return 'boolean'; + default: + break; + } + + if (Array.isArray(value)) { + if (value.length === 0) { + return 'unknown[]'; + } + const elementTypes = new Set(value.map(item => inferTsType(item, `${name}Item`, interfaces))); + const uniqueTypes = [...elementTypes]; + if (uniqueTypes.length === 1) { + return `${uniqueTypes[0]}[]`; + } + return `(${uniqueTypes.join(' | ')})[]`; + } + + if (typeof value === 'object') { + const interfaceName = capitalize(toPascalCase(name)); + const entries = Object.entries(value as Record); + const fields = entries.map(([key, val]) => { + const type = inferTsType(val, key, interfaces); + const safeKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `'${key}'`; + return ` ${safeKey}: ${type};`; + }); + interfaces.set(interfaceName, `interface ${interfaceName} {\n${fields.join('\n')}\n}`); + return interfaceName; + } + + return 'unknown'; +} + +export function jsonToTypeScript(json: unknown, rootName: string = 'RootType'): string { + const interfaces = new Map(); + inferTsType(json, rootName, interfaces); + + if (interfaces.size === 0) { + const simpleType = inferTsType(json, rootName, interfaces); + return `type ${toPascalCase(rootName)} = ${simpleType};`; + } + + return [...interfaces.values()].reverse().join('\n\n'); +} + +function inferGoType(value: unknown, name: string, structs: Map): string { + if (value === null) { + return 'interface{}'; + } + + switch (typeof value) { + case 'string': + return 'string'; + case 'number': + return Number.isInteger(value) ? 'int64' : 'float64'; + case 'boolean': + return 'bool'; + default: + break; + } + + if (Array.isArray(value)) { + if (value.length === 0) { + return '[]interface{}'; + } + const elementType = inferGoType(value[0], `${name}Item`, structs); + return `[]${elementType}`; + } + + if (typeof value === 'object') { + const structName = toPascalCase(name); + const entries = Object.entries(value as Record); + const fields = entries.map(([key, val]) => { + const goType = inferGoType(val, key, structs); + const fieldName = toPascalCase(key); + return `\t${fieldName} ${goType} \`json:"${key}"\``; + }); + structs.set(structName, `type ${structName} struct {\n${fields.join('\n')}\n}`); + return structName; + } + + return 'interface{}'; +} + +export function jsonToGoStruct(json: unknown, rootName: string = 'RootType'): string { + const structs = new Map(); + inferGoType(json, rootName, structs); + + if (structs.size === 0) { + const simpleType = inferGoType(json, rootName, structs); + return `type ${toPascalCase(rootName)} ${simpleType}`; + } + + return [...structs.values()].reverse().join('\n\n'); +} diff --git a/src/tools/json-to-types/json-to-types.vue b/src/tools/json-to-types/json-to-types.vue new file mode 100644 index 0000000000..e19711177c --- /dev/null +++ b/src/tools/json-to-types/json-to-types.vue @@ -0,0 +1,64 @@ + + + diff --git a/src/tools/ssl-certificate-parser/index.ts b/src/tools/ssl-certificate-parser/index.ts new file mode 100644 index 0000000000..3464b500d7 --- /dev/null +++ b/src/tools/ssl-certificate-parser/index.ts @@ -0,0 +1,13 @@ +import { FileCertificate } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: translate('tools.ssl-certificate-parser.title'), + path: '/ssl-certificate-parser', + description: translate('tools.ssl-certificate-parser.description'), + keywords: ['ssl', 'certificate', 'x509', 'pem', 'cert', 'tls', 'https', 'expiry', 'issuer', 'subject', 'domain'], + component: () => import('./ssl-certificate-parser.vue'), + icon: FileCertificate, + createdAt: new Date('2026-06-05'), +}); diff --git a/src/tools/ssl-certificate-parser/ssl-certificate-parser.service.ts b/src/tools/ssl-certificate-parser/ssl-certificate-parser.service.ts new file mode 100644 index 0000000000..f4aabaa01f --- /dev/null +++ b/src/tools/ssl-certificate-parser/ssl-certificate-parser.service.ts @@ -0,0 +1,108 @@ +import forge from 'node-forge'; + +const { pki } = forge; + +export interface CertificateInfo { + subject: { key: string; value: string }[] + issuer: { key: string; value: string }[] + serialNumber: string + validFrom: string + validTo: string + isExpired: boolean + daysUntilExpiry: number + version: number + signatureAlgorithm: string + thumbprint: string + subjectAltNames: string[] + keyUsage: string[] + basicConstraints: string + publicKeyAlgorithm: string + publicKeySize: string +} + +const fieldLabels: Record = { + commonName: 'Common Name (CN)', + organizationName: 'Organization (O)', + organizationalUnitName: 'Organizational Unit (OU)', + countryName: 'Country (C)', + stateOrProvinceName: 'State/Province (ST)', + localityName: 'Locality (L)', + emailAddress: 'Email', +}; + +function formatDN(attrs: pki.CertificateField[]) { + return attrs.map((attr) => { + const label = (attr.name && fieldLabels[attr.name]) || attr.shortName || attr.name || attr.type || 'Unknown'; + return { key: label, value: String(attr.value) }; + }); +} + +function getSubjectAltNames(cert: pki.Certificate): string[] { + const ext = cert.getExtension('subjectAltName') as { altNames?: { type: number; value: string }[] } | null; + if (!ext?.altNames) { + return []; + } + return ext.altNames.map(an => an.value); +} + +function getKeyUsage(cert: pki.Certificate): string[] { + const ext = cert.getExtension('keyUsage') as Record | null; + if (!ext) { + return []; + } + const usages = [ + 'digitalSignature', 'nonRepudiation', 'keyEncipherment', 'dataEncipherment', + 'keyAgreement', 'keyCertSign', 'cRLSign', 'encipherOnly', 'decipherOnly', + ]; + return usages.filter(u => ext[u]); +} + +function getBasicConstraints(cert: pki.Certificate): string { + const ext = cert.getExtension('basicConstraints') as { cA?: boolean; pathLenConstraint?: number } | null; + if (!ext) { + return 'Not present'; + } + const ca = ext.cA ? 'CA: TRUE' : 'CA: FALSE'; + const pathLen = ext.pathLenConstraint !== undefined ? `, Path Length: ${ext.pathLenConstraint}` : ''; + return `${ca}${pathLen}`; +} + +export function parseCertificate(pem: string): CertificateInfo { + const cert = pki.certificateFromPem(pem); + + const now = new Date(); + const validTo = cert.validity.notAfter; + const isExpired = now > validTo; + const daysUntilExpiry = Math.floor((validTo.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)); + + const md = pki.getPublicKeyFingerprint(cert.publicKey, { + md: forge.md.sha256.create(), + encoding: 'hex', + delimiter: ':', + }); + + const pubKey = cert.publicKey as pki.rsa.PublicKey; + let publicKeyAlgorithm = 'RSA'; + let publicKeySize = ''; + if ('n' in pubKey && pubKey.n) { + publicKeySize = `${pubKey.n.bitLength()} bits`; + } + + return { + subject: formatDN(cert.subject.attributes), + issuer: formatDN(cert.issuer.attributes), + serialNumber: cert.serialNumber, + validFrom: cert.validity.notBefore.toISOString(), + validTo: cert.validity.notAfter.toISOString(), + isExpired, + daysUntilExpiry, + version: cert.version + 1, + signatureAlgorithm: (pki as any).oids[cert.siginfo.algorithmOid] || cert.siginfo.algorithmOid, + thumbprint: String(md), + subjectAltNames: getSubjectAltNames(cert), + keyUsage: getKeyUsage(cert), + basicConstraints: getBasicConstraints(cert), + publicKeyAlgorithm, + publicKeySize, + }; +} diff --git a/src/tools/ssl-certificate-parser/ssl-certificate-parser.vue b/src/tools/ssl-certificate-parser/ssl-certificate-parser.vue new file mode 100644 index 0000000000..6b89d4c16a --- /dev/null +++ b/src/tools/ssl-certificate-parser/ssl-certificate-parser.vue @@ -0,0 +1,222 @@ + + + diff --git a/src/tools/tools.store.ts b/src/tools/tools.store.ts index fb12450dfe..32c7308b30 100644 --- a/src/tools/tools.store.ts +++ b/src/tools/tools.store.ts @@ -42,7 +42,9 @@ export const useToolStore = defineStore('tools', () => { tools, favoriteTools, toolsByCategory, - newTools: computed(() => tools.value.filter(({ isNew }) => isNew)), + newTools: computed(() => tools.value + .filter(({ isNew }) => isNew) + .sort((a, b) => (b.createdAt?.getTime() ?? 0) - (a.createdAt?.getTime() ?? 0))), addToolToFavorites({ tool }: { tool: MaybeRef }) { const toolPath = get(tool).path; diff --git a/vite.config.ts b/vite.config.ts index 42a2cb29f7..eaf7736a73 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -56,6 +56,10 @@ export default defineConfig({ VitePWA({ registerType: 'autoUpdate', strategies: 'generateSW', + workbox: { + skipWaiting: true, + clientsClaim: true, + }, manifest: { name: 'IT Tools', description: 'Aggregated set of useful tools for developers.', @@ -102,6 +106,7 @@ export default defineConfig({ resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), + '@vueuse/shared': fileURLToPath(new URL('./node_modules/@vueuse/shared/index.mjs', import.meta.url)), }, }, define: { @@ -110,6 +115,11 @@ export default defineConfig({ test: { exclude: [...configDefaults.exclude, '**/*.e2e.spec.ts'], }, + optimizeDeps: { + esbuildOptions: { + target: 'esnext', + }, + }, build: { target: 'esnext', }, diff --git a/worker.js b/worker.js new file mode 100644 index 0000000000..910f22e914 --- /dev/null +++ b/worker.js @@ -0,0 +1,5 @@ +export default { + async fetch(request, env) { + return env.ASSETS.fetch(request); + }, +}; diff --git a/wrangler.toml b/wrangler.toml new file mode 100644 index 0000000000..9a60ae9ae4 --- /dev/null +++ b/wrangler.toml @@ -0,0 +1,14 @@ +name = "it-tools" +main = "worker.js" +compatibility_date = "2024-09-23" +compatibility_flags = ["nodejs_compat"] + +[assets] +directory = "./dist" +binding = "ASSETS" +html_handling = "auto-trailing-slash" +not_found_handling = "single-page-application" + +[[routes]] +pattern = "it-tools.88586688.xyz" +custom_domain = true