diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..13e044a
--- /dev/null
+++ b/.env.example
@@ -0,0 +1 @@
+LOCIZE_API_KEY=
diff --git a/.gitignore b/.gitignore
index f691227..e9d8978 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,5 @@ yarn-error.log*
dist.zip
.aider*
.qodo
+
+error.txt
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 3f79c3d..9948720 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,18 +4,22 @@
-
+
-
-
-
-
+
+
+
+
+
+
+
+
@@ -23,7 +27,7 @@
-
+
@@ -204,6 +208,27 @@
"number": 176
},
"lastSeen": 1752158748013
+ },
+ {
+ "id": {
+ "id": "PR_kwDOMJIfts6eqzP7",
+ "number": 190
+ },
+ "lastSeen": 1752404173008
+ },
+ {
+ "id": {
+ "id": "PR_kwDOMJIfts6et6vx",
+ "number": 192
+ },
+ "lastSeen": 1752585709582
+ },
+ {
+ "id": {
+ "id": "PR_kwDOMJIfts6d36mi",
+ "number": 168
+ },
+ "lastSeen": 1752805763664
}
]
}]]>
@@ -244,6 +269,9 @@
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
"Docker.Dockerfile build.executor": "Run",
"Docker.Dockerfile.executor": "Run",
+ "Node.js.add-i18n-to-meta.js.executor": "Run",
+ "Node.js.locize-upload.js.executor": "Run",
+ "Node.js.update-i18n-from-meta.js.executor": "Run",
"Playwright.Create transparent PNG.should make png color transparent.executor": "Run",
"Playwright.JoinText Component.executor": "Run",
"Playwright.JoinText Component.should merge text pieces with specified join character.executor": "Run",
@@ -252,6 +280,7 @@
"RunOnceActivity.git.unshallow": "true",
"Vitest.compute function (1).executor": "Run",
"Vitest.compute function.executor": "Run",
+ "Vitest.generatePassword.executor": "Run",
"Vitest.mergeText.executor": "Run",
"Vitest.mergeText.should merge lines and preserve blank lines when deleteBlankLines is false.executor": "Run",
"Vitest.mergeText.should merge lines, preserve blank lines and trailing spaces when both deleteBlankLines and deleteTrailingSpaces are false.executor": "Run",
@@ -265,7 +294,7 @@
"git-widget-placeholder": "main",
"ignore.virus.scanning.warn.message": "true",
"kotlin-language-version-configured": "true",
- "last_opened_file_path": "C:/Users/Ibrahima/IdeaProjects/omni-tools/public",
+ "last_opened_file_path": "C:/Users/Ibrahima/IdeaProjects/omni-tools",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
@@ -273,6 +302,10 @@
"nodejs_package_manager_path": "npm",
"npm.build.executor": "Run",
"npm.dev.executor": "Run",
+ "npm.i18n:extract.executor": "Run",
+ "npm.i18n:pull.executor": "Run",
+ "npm.i18n:push.executor": "Run",
+ "npm.i18n:sync.executor": "Run",
"npm.lint.executor": "Run",
"npm.prebuild.executor": "Run",
"npm.script:create:tool.executor": "Run",
@@ -299,58 +332,31 @@
+
+
-
-
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -367,33 +373,58 @@
-
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
-
-
-
+
-
-
-
-
+
+
+
+
@@ -504,222 +535,9 @@
-
-
-
- 1743022260639
-
-
-
- 1743022260639
-
-
-
- 1743051792459
-
-
-
- 1743051792459
-
-
-
- 1743052111988
-
-
-
- 1743052111988
-
-
-
- 1743106796406
-
-
-
- 1743106796406
-
-
-
- 1743349732644
-
-
-
- 1743349732644
-
-
-
- 1743355099396
-
-
-
- 1743355099396
-
-
-
- 1743355166425
-
-
-
- 1743355166426
-
-
-
- 1743385388051
-
-
-
- 1743385388051
-
-
-
- 1743385467178
-
-
-
- 1743385467178
-
-
-
- 1743385898871
-
-
-
- 1743385898871
-
-
-
- 1743459110471
-
-
-
- 1743459110471
-
-
-
- 1743459205311
-
-
-
- 1743459205311
-
-
-
- 1743470832619
-
-
-
- 1743470832619
-
-
-
- 1743644598841
-
-
-
- 1743644598841
-
-
-
- 1743644703041
-
-
-
- 1743644703042
-
-
-
- 1743644942488
-
-
-
- 1743644942488
-
-
-
- 1743645074051
-
-
-
- 1743645074051
-
-
-
- 1743647707334
-
-
-
- 1743647707334
-
-
-
- 1743691399769
-
-
-
- 1743691399769
-
-
-
- 1743691471368
-
-
-
- 1743691471368
-
-
-
- 1743705749057
-
-
-
- 1743705749057
-
-
-
- 1743710133267
-
-
-
- 1743710133267
-
-
-
- 1743710669869
-
-
-
- 1743710669869
-
-
-
- 1743811980098
-
-
-
- 1743811980098
-
-
-
- 1745688369521
-
-
-
- 1745688369521
-
-
-
- 1745688866294
-
-
-
- 1745688866294
-
-
-
- 1747172914927
-
-
-
- 1747172914927
+
+
+
@@ -897,7 +715,223 @@
1752158119802
-
+
+
+ 1752402313190
+
+
+
+ 1752402313191
+
+
+
+ 1752408068771
+
+
+
+ 1752408068771
+
+
+
+ 1752412149075
+
+
+
+ 1752412149075
+
+
+
+ 1752422405814
+
+
+
+ 1752422405814
+
+
+
+ 1752423460080
+
+
+
+ 1752423460080
+
+
+
+ 1752493634215
+
+
+
+ 1752493634215
+
+
+
+ 1752497705915
+
+
+
+ 1752497705915
+
+
+
+ 1752501110885
+
+
+
+ 1752501110885
+
+
+
+ 1752503206380
+
+
+
+ 1752503206380
+
+
+
+ 1752503720380
+
+
+
+ 1752503720380
+
+
+
+ 1752503770543
+
+
+
+ 1752503770543
+
+
+
+ 1752505593881
+
+
+
+ 1752505593881
+
+
+
+ 1752512678963
+
+
+
+ 1752512678963
+
+
+
+ 1752514466233
+
+
+
+ 1752514466233
+
+
+
+ 1752515675314
+
+
+
+ 1752515675314
+
+
+
+ 1752585351036
+
+
+
+ 1752585351036
+
+
+
+ 1752585829343
+
+
+
+ 1752585829343
+
+
+
+ 1752586932190
+
+
+
+ 1752586932190
+
+
+
+ 1752591387066
+
+
+
+ 1752591387066
+
+
+
+ 1752596436284
+
+
+
+ 1752596436284
+
+
+
+ 1752600606853
+
+
+
+ 1752600606853
+
+
+
+ 1752601115085
+
+
+
+ 1752601115085
+
+
+
+ 1752601506346
+
+
+
+ 1752601506346
+
+
+
+ 1752601987121
+
+
+
+ 1752601987121
+
+
+
+ 1752604958929
+
+
+
+ 1752604958929
+
+
+
+ 1752605940802
+
+
+
+ 1752605940802
+
+
+
+ 1752805853344
+
+
+
+ 1752805853344
+
+
@@ -944,32 +978,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
false
diff --git a/@types/i18n.d.ts b/@types/i18n.d.ts
new file mode 100644
index 0000000..efd6ca1
--- /dev/null
+++ b/@types/i18n.d.ts
@@ -0,0 +1,9 @@
+// types/i18next.d.ts
+import 'i18next';
+import { resources } from '../src/i18n';
+
+declare module 'i18next' {
+ interface CustomTypeOptions {
+ resources: (typeof resources)['en'];
+ }
+}
diff --git a/README.md b/README.md
index 9d6e367..ed6f0b9 100644
--- a/README.md
+++ b/README.md
@@ -30,21 +30,21 @@ Here is the [demo](https://omnitools.app) website.
All files are processed entirely on the client side: nothing ever leaves your device.
Plus, the Docker image is super lightweight at just 28MB, making it fast to deploy and easy to self-host.
-
+
## Table of Contents
- [Features](#features)
- [Self-host](#self-hostrun)
- [Contribute](#contribute)
-- [License](#license)
- [Contact](#contact)
+- [License](#license)
## Features
We strive to offer a variety of tools, including:
-## **Image/Video/Audio Tools**
+### **Image/Video/Audio Tools**
- Image Resizer
- Image Converter
@@ -53,33 +53,33 @@ We strive to offer a variety of tools, including:
- Video Reverser
- And more...
-## **PDF Tools**
+### **PDF Tools**
- PDF Splitter
- PDF Merger
- PDF Editor
- And more...
-## **Text/List Tools**
+### **Text/List Tools**
- Case Converters
- List Shuffler
- Text Formatters
- And more...
-## **Date and Time Tools**
+### **Date and Time Tools**
- Date Calculators
- Time Zone Converters
- And more...
-## **Math Tools**
+### **Math Tools**
- Generate Prime Numbers
- Calculate voltage, current, or resistance
- And more...
-## **Data Tools**
+### **Data Tools**
- JSON Tools
- CSV Tools
@@ -148,20 +148,34 @@ npm run test
npm run test:e2e
```
+### i18n (Translations)
+The translation files are [here](public/locales). Only edit these if you are a developer. For non developers, use [Locize](https://www.locize.app/register?invitation=YOIH0Dyz3KHh3uQFCGYe9v1QOUoq8W5ySgmlwjX9cSypeJmt8F40brDtVbXb71fK).
+
## ๐ค Looking to contribute?
We welcome contributions! You can help by:
-- โ
Reporting bugs
-- โ
Suggesting new features in GitHub issues or [here](https://tally.so/r/nrkkx2)
-- โ
Improving documentation
-- โ
Submitting pull requests
+- Reporting bugs
+- Suggesting new features in GitHub issues or [here](https://tally.so/r/nrkkx2)
+- Translating in [Locize project](https://www.locize.app/register?invitation=YOIH0Dyz3KHh3uQFCGYe9v1QOUoq8W5ySgmlwjX9cSypeJmt8F40brDtVbXb71fK).
+- Improving documentation
+- Submitting pull requests
+
You can also join our [Discord server](https://discord.gg/SDbbn3hT4b)
+## ๐งก Sponsors
+
-### Contributors
+Thanks to [Locize](https://www.locize.com) for sponsoring OmniTools and supporting localization efforts.
+They make translation management simple and developer-friendly.
+
+## Contributors
diff --git a/img.png b/docs-images/img.png
similarity index 100%
rename from img.png
rename to docs-images/img.png
diff --git a/docs-images/locizeSponsor.svg b/docs-images/locizeSponsor.svg
new file mode 100644
index 0000000..1139aa2
--- /dev/null
+++ b/docs-images/locizeSponsor.svg
@@ -0,0 +1,187 @@
+
+
+
+ Custom Preset 2 Copy
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 5b698c2..835edf1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,6 +15,7 @@
"@ffmpeg/util": "^0.12.2",
"@imgly/background-removal": "^1.6.0",
"@jimp/types": "^1.6.0",
+ "@monaco-editor/react": "^4.7.0",
"@mui/icons-material": "^5.15.20",
"@mui/material": "^5.15.20",
"@playwright/test": "^1.45.0",
@@ -24,6 +25,7 @@
"@types/lodash": "^4.17.5",
"@types/morsee": "^1.0.2",
"@types/omggif": "^1.0.5",
+ "@types/react-i18next": "^7.8.3",
"browser-image-compression": "^2.0.2",
"buffer": "^6.0.3",
"color": "^4.2.3",
@@ -32,10 +34,13 @@
"dayjs": "^1.11.13",
"fast-xml-parser": "^5.2.5",
"formik": "^2.4.6",
+ "i18next": "^25.3.2",
+ "i18next-http-backend": "^3.0.2",
"jimp": "^0.22.12",
"js-quantities": "^1.8.0",
"jszip": "^3.10.1",
"lint-staged": "^15.4.3",
+ "locize": "^4.0.14",
"lodash": "^4.17.21",
"mime": "^4.0.6",
"morsee": "^1.0.9",
@@ -51,6 +56,7 @@
"react-dom": "^18.3.1",
"react-filerobot-image-editor": "^4.9.1",
"react-helmet": "^6.1.0",
+ "react-i18next": "^15.6.0",
"react-image-crop": "^11.0.7",
"react-konva": "^18.2.10",
"react-router-dom": "^6.23.1",
@@ -85,6 +91,8 @@
"eslint-plugin-tailwindcss": "^3.17.0",
"happy-dom": "^12.10.3",
"husky": "^9.0.11",
+ "i18next-locize-backend": "^7.0.4",
+ "locize-cli": "^10.1.1",
"postcss": "^8.4.38",
"prettier": "3.1.1",
"start-server-and-test": "^2.0.4",
@@ -302,12 +310,10 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz",
- "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==",
- "dependencies": {
- "regenerator-runtime": "^0.14.0"
- },
+ "version": "7.27.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
+ "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@@ -1419,20 +1425,22 @@
}
},
"node_modules/@floating-ui/core": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.2.tgz",
- "integrity": "sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==",
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz",
+ "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==",
+ "license": "MIT",
"dependencies": {
- "@floating-ui/utils": "^0.2.0"
+ "@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/dom": {
- "version": "1.6.5",
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz",
- "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==",
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz",
+ "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==",
+ "license": "MIT",
"dependencies": {
- "@floating-ui/core": "^1.0.0",
- "@floating-ui/utils": "^0.2.0"
+ "@floating-ui/core": "^1.7.2",
+ "@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/react-dom": {
@@ -1448,9 +1456,21 @@
}
},
"node_modules/@floating-ui/utils": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz",
- "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw=="
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
+ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
+ "license": "MIT"
+ },
+ "node_modules/@fluent/syntax": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/@fluent/syntax/-/syntax-0.19.0.tgz",
+ "integrity": "sha512-5D2qVpZrgpjtqU4eNOcWGp1gnUCgjfM+vKGE2y03kKN6z5EBhtx0qdRFbg8QuNNj8wXNoX93KJoYb+NqoxswmQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=14.0.0",
+ "npm": ">=7.0.0"
+ }
},
"node_modules/@hapi/hoek": {
"version": "9.3.0",
@@ -2078,6 +2098,36 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@js.properties/properties": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/@js.properties/properties/-/properties-0.5.4.tgz",
+ "integrity": "sha512-4M/Mb2CxzuI1CtQhVFs6OC9ceuGPAP6SOWnpLcrdB1TcUHroXbsYDVJNOm32koRMfuCoRACbojcm4dPPcQxu0w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@monaco-editor/loader": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.5.0.tgz",
+ "integrity": "sha512-hKoGSM+7aAc7eRTRjpqAZucPmoNOC4UUbknb/VNoTkEIkCPhqV8LfbsgM1webRM7S/z21eHEx9Fkwx8Z/C/+Xw==",
+ "license": "MIT",
+ "dependencies": {
+ "state-local": "^1.0.6"
+ }
+ },
+ "node_modules/@monaco-editor/react": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz",
+ "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==",
+ "license": "MIT",
+ "dependencies": {
+ "@monaco-editor/loader": "^1.5.0"
+ },
+ "peerDependencies": {
+ "monaco-editor": ">= 0.25.0 < 1",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/@mui/base": {
"version": "5.0.0-beta.40",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz",
@@ -3395,6 +3445,12 @@
"hoist-non-react-statics": "^3.3.0"
}
},
+ "node_modules/@types/i18next": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/@types/i18next/-/i18next-12.1.0.tgz",
+ "integrity": "sha512-qLyqTkp3ZKHsSoX8CNVYcTyTkxlm0aRCUpaUVetgkSlSpiNCdWryOgaYwgbO04tJIfLgBXPcy0tJ3Nl/RagllA==",
+ "license": "MIT"
+ },
"node_modules/@types/js-quantities": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/@types/js-quantities/-/js-quantities-1.6.6.tgz",
@@ -3484,6 +3540,16 @@
"@types/react": "*"
}
},
+ "node_modules/@types/react-i18next": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@types/react-i18next/-/react-i18next-7.8.3.tgz",
+ "integrity": "sha512-VPopxbHXz/1Sjl+ljXQQchf6FHXaYLaH0a6TH6KnGOQGD4LzNbUVlofK26S30OIYfYibm8r/sAb2KeTst+AwTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/i18next": "*",
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/react-reconciler": {
"version": "0.28.9",
"resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz",
@@ -3936,6 +4002,16 @@
"node": ">=0.4.0"
}
},
+ "node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -3952,6 +4028,17 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/android-string-resource": {
+ "version": "2.3.10",
+ "resolved": "https://registry.npmjs.org/android-string-resource/-/android-string-resource-2.3.10.tgz",
+ "integrity": "sha512-Ldzy2znjm+BVWVHbzyhmdiznVdIum/EM2CMtSPjnoVr1/MljZTVPB08giSpm1WIo00fK/sL/kcnvr0+d9wVUzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "rdotjson": "1.1.1",
+ "xml-js": "1.6.11"
+ }
+ },
"node_modules/ansi-escapes": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz",
@@ -4191,6 +4278,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/arrify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/assertion-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
@@ -4200,6 +4297,13 @@
"node": "*"
}
},
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -4348,6 +4452,13 @@
"integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==",
"license": "MIT"
},
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@@ -4450,6 +4561,16 @@
"node": ">=8"
}
},
+ "node_modules/cacheable-lookup": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz",
+ "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.6.0"
+ }
+ },
"node_modules/call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
@@ -4577,6 +4698,46 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/cheerio": {
+ "version": "1.0.0-rc.12",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
+ "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "htmlparser2": "^8.0.1",
+ "parse5": "^7.0.0",
+ "parse5-htmlparser2-tree-adapter": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
"node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
@@ -4802,6 +4963,16 @@
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
"license": "MIT"
},
+ "node_modules/colors": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -4845,6 +5016,16 @@
"integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==",
"dev": true
},
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/conventional-changelog-angular": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
@@ -4936,10 +5117,21 @@
"cronstrue": "bin/cli.js"
}
},
+ "node_modules/cross-fetch": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz",
+ "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-fetch": "^2.7.0"
+ }
+ },
"node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -4959,6 +5151,23 @@
"node": ">=4"
}
},
+ "node_modules/css-select": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
+ "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
"node_modules/css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
@@ -4971,6 +5180,19 @@
"postcss-value-parser": "^4.0.2"
}
},
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
"node_modules/css.escape": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
@@ -4994,6 +5216,13 @@
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
+ "node_modules/csvjson": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/csvjson/-/csvjson-5.1.0.tgz",
+ "integrity": "sha512-OqALQHA0k2rEGluOWikwFq5qtkRUDyoWP2u0UJy8uFjFx5FPMjPzx7D2Hn2KjBLpc8jkGrT9HDNgTUfopDlqVg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/dargs": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
@@ -5203,6 +5432,16 @@
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
"dev": true
},
+ "node_modules/diff": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
+ "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
"node_modules/diff-sequences": {
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
@@ -5263,11 +5502,70 @@
"csstype": "^3.0.2"
}
},
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
"node_modules/dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
"node_modules/dot-prop": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
@@ -5280,6 +5578,19 @@
"node": ">=8"
}
},
+ "node_modules/dotenv": {
+ "version": "16.5.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
+ "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
"node_modules/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@@ -5304,6 +5615,16 @@
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true
},
+ "node_modules/encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -6108,6 +6429,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
"node_modules/flat-cache": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
@@ -6135,6 +6466,16 @@
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
"dev": true
},
+ "node_modules/fluent_conv": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/fluent_conv/-/fluent_conv-3.3.0.tgz",
+ "integrity": "sha512-OsTQyVWo1WYmEnnH7m3MRlk5NQq/+jXOLzv0WOk8GGn99LdQV1kNp3IOR6HYb+fwDqYebLPLAThS2pFEaDbyHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fluent/syntax": "0.19.0"
+ }
+ },
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
@@ -6368,6 +6709,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/gettext-converter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/gettext-converter/-/gettext-converter-1.3.0.tgz",
+ "integrity": "sha512-vXjx4vRBjw6rd3Zg73IMyNLZuPjs8/lE9gJZs270YJJI0t5vlCpdsyX5E0TmSd+KcRWzwPbwjwd6bnNpF72sFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arrify": "^2.0.1",
+ "content-type": "1.0.5",
+ "encoding": "0.1.13"
+ }
+ },
"node_modules/gifwrap": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz",
@@ -6684,6 +7037,49 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/html-parse-stringify": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
+ "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
+ "license": "MIT",
+ "dependencies": {
+ "void-elements": "3.1.0"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
+ "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "entities": "^4.4.0"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/human-signals": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
@@ -6707,11 +7103,79 @@
"url": "https://github.com/sponsors/typicode"
}
},
+ "node_modules/i18next": {
+ "version": "25.3.2",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.3.2.tgz",
+ "integrity": "sha512-JSnbZDxRVbphc5jiptxr3o2zocy5dEqpVm9qCGdJwRNO+9saUJS0/u4LnM/13C23fUEWxAylPqKU/NpMV/IjqA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://locize.com"
+ },
+ {
+ "type": "individual",
+ "url": "https://locize.com/i18next.html"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.27.6"
+ },
+ "peerDependencies": {
+ "typescript": "^5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/i18next-http-backend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-3.0.2.tgz",
+ "integrity": "sha512-PdlvPnvIp4E1sYi46Ik4tBYh/v/NbYfFFgTjkwFl0is8A18s7/bx9aXqsrOax9WUbeNS6mD2oix7Z0yGGf6m5g==",
+ "license": "MIT",
+ "dependencies": {
+ "cross-fetch": "4.0.0"
+ }
+ },
+ "node_modules/i18next-http-backend/node_modules/cross-fetch": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
+ "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==",
+ "license": "MIT",
+ "dependencies": {
+ "node-fetch": "^2.6.12"
+ }
+ },
+ "node_modules/i18next-locize-backend": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/i18next-locize-backend/-/i18next-locize-backend-7.0.4.tgz",
+ "integrity": "sha512-saRyIQAX0k+YA6XzirU6cyudWDj1W7bGDz/Szq+8OIs3JJnNuMZCADuNgCwmo+dQm9P69bbALymV+9t9ffywBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-fetch": "4.1.0"
+ }
+ },
+ "node_modules/i18next-subliminal": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/i18next-subliminal/-/i18next-subliminal-1.0.1.tgz",
+ "integrity": "sha512-h3m1oQ8lTaTNNgqmvBXAzFSGoJ0uobUcFW6TJMaWV4QDQ0+YGIih3ZcCX1XouGzK8yyFX13lP+2zAT/k7u4oiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.27.0"
+ }
+ },
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "dev": true,
+ "devOptional": true,
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
@@ -7594,6 +8058,16 @@
"license": "MIT",
"peer": true
},
+ "node_modules/laravelphp": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/laravelphp/-/laravelphp-2.0.4.tgz",
+ "integrity": "sha512-rx5X+Yds6MmIxGS+VVQBWhylPYxkOYmKXrWqQHc2rj2ewsoWMZS7OaTXk9UE8y95XV+D5CqLjaEj+IJgRmrIaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "php-parser": "3.1.5"
+ }
+ },
"node_modules/lazy-ass": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz",
@@ -7876,6 +8350,146 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/locize": {
+ "version": "4.0.14",
+ "resolved": "https://registry.npmjs.org/locize/-/locize-4.0.14.tgz",
+ "integrity": "sha512-4AnM9Hoxm7tgE+LhkdX1cDp+PLnraSruNc/3O/AAFfbmqmqaGdf9TyLwgHd0C9ug6GPRS0RIzXH6wdg5tHMWWw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.23.6",
+ "@floating-ui/dom": "^1.6.13",
+ "i18next-subliminal": "^1.0.1"
+ }
+ },
+ "node_modules/locize-cli": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/locize-cli/-/locize-cli-10.1.1.tgz",
+ "integrity": "sha512-X0qzyKvlMPsu65jSFAaTLGobVFvLvd2wuPqPiJqROruneIc2ddEIRA6jspuRBpi9EGxDCERnmkM5nkGK/SjV8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@js.properties/properties": "0.5.4",
+ "android-string-resource": "2.3.10",
+ "async": "3.2.6",
+ "cacheable-lookup": "6.1.0",
+ "colors": "1.4.0",
+ "commander": "9.5.0",
+ "csvjson": "5.1.0",
+ "diff": "7.0.0",
+ "dotenv": "16.5.0",
+ "flat": "5.0.2",
+ "fluent_conv": "3.3.0",
+ "gettext-converter": "1.3.0",
+ "https-proxy-agent": "7.0.6",
+ "ini": "4.1.3",
+ "laravelphp": "2.0.4",
+ "locize-xcstrings": "2.0.0",
+ "lodash.clonedeep": "4.5.0",
+ "mkdirp": "3.0.1",
+ "node-fetch": "2.7.0",
+ "resx": "2.0.4",
+ "rimraf": "4.4.1",
+ "strings-file": "0.0.5",
+ "tmexchange": "2.0.5",
+ "xliff": "6.2.2",
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
+ "yaml": "2.8.0"
+ },
+ "bin": {
+ "locize": "bin/locize"
+ }
+ },
+ "node_modules/locize-cli/node_modules/commander": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
+ "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || >=14"
+ }
+ },
+ "node_modules/locize-cli/node_modules/glob": {
+ "version": "9.3.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
+ "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "minimatch": "^8.0.2",
+ "minipass": "^4.2.4",
+ "path-scurry": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/locize-cli/node_modules/ini": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz",
+ "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/locize-cli/node_modules/minimatch": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
+ "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/locize-cli/node_modules/minipass": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
+ "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/locize-cli/node_modules/rimraf": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz",
+ "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^9.2.0"
+ },
+ "bin": {
+ "rimraf": "dist/cjs/src/bin.js"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/locize-xcstrings": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locize-xcstrings/-/locize-xcstrings-2.0.0.tgz",
+ "integrity": "sha512-Gef3IrMDSB5ZuRbym9ktr7KXCTFjIvs1T2TEnaew5ed7BBwt3od0/sj8C7X9iGpRebHxG1kyF6hR6aK8iBPkLg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@@ -7892,6 +8506,13 @@
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
"dev": true
},
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
@@ -8277,6 +8898,22 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/mkdirp": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
+ "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "dist/cjs/src/bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/mlly": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz",
@@ -8289,6 +8926,13 @@
"ufo": "^1.5.3"
}
},
+ "node_modules/monaco-editor": {
+ "version": "0.52.2",
+ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz",
+ "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/morsee": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/morsee/-/morsee-1.0.9.tgz",
@@ -8457,6 +9101,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -8592,6 +9249,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/obop": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/obop/-/obop-0.2.3.tgz",
+ "integrity": "sha512-xmaHk+pwv4T6QKoq553KeJlkZUV6WBVGU/dO7rppA7YFIvGf+xB1OQAkw8mcORtxtSHpiK5JiTQ+d7Bme/Y7Wg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/omggif": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz",
@@ -8771,6 +9435,46 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+ "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domhandler": "^5.0.3",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5/node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -8897,6 +9601,13 @@
"integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."
},
+ "node_modules/php-parser": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/php-parser/-/php-parser-3.1.5.tgz",
+ "integrity": "sha512-jEY2DcbgCm5aclzBdfW86GM6VEIWcSlhTBSHN1qhJguVePlYe28GhwS0yoeLYXpM2K8y6wzLwrbq814n2PHSoQ==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -9282,6 +9993,16 @@
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"license": "MIT"
},
+ "node_modules/process.argv": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/process.argv/-/process.argv-0.6.1.tgz",
+ "integrity": "sha512-WQOWF/VB0pTJu7c3ko0y5w6HWDQf6Wm3ppvKDI7ET4OSYBDOvcliBRM1HFIHHkJPNa/1bYTzmUinjF8492oaBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "obop": "^0.2.2"
+ }
+ },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@@ -9579,6 +10300,34 @@
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
"license": "MIT"
},
+ "node_modules/rdotjson": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/rdotjson/-/rdotjson-1.1.1.tgz",
+ "integrity": "sha512-L6wBhp64fAr/FPhjfkuf9Lx6dAbfkznROcBMj55tVamw6ddTvhcgoqu89a3lUJCaALJkZe/mTcQoNM0P09RpQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cheerio": "1.0.0-rc.12",
+ "is-stream": "^2.0.0",
+ "process.argv": "^0.6.1"
+ },
+ "bin": {
+ "rdotjson": "rdotjson.cli.js"
+ }
+ },
+ "node_modules/rdotjson/node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
@@ -9682,6 +10431,32 @@
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
},
+ "node_modules/react-i18next": {
+ "version": "15.6.0",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.6.0.tgz",
+ "integrity": "sha512-W135dB0rDfiFmbMipC17nOhGdttO5mzH8BivY+2ybsQBbXvxWIwl3cmeH3T9d+YPBSJu/ouyJKFJTtkK7rJofw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.27.6",
+ "html-parse-stringify": "^3.0.1"
+ },
+ "peerDependencies": {
+ "i18next": ">= 23.2.3",
+ "react": ">= 16.8.0",
+ "typescript": "^5"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-image-crop": {
"version": "11.0.7",
"resolved": "https://registry.npmjs.org/react-image-crop/-/react-image-crop-11.0.7.tgz",
@@ -9880,11 +10655,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/regenerator-runtime": {
- "version": "0.14.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
- },
"node_modules/regexp.prototype.flags": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
@@ -9982,6 +10752,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/resx": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/resx/-/resx-2.0.4.tgz",
+ "integrity": "sha512-b3IW7ge0nxbWOhbUGO/WULL4NG5ctrpey+UgDIwRq5K4Bblna4t1hLMbA2DZC9Y6e8U/zLuRJHg+qEOVKOoypQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xml2js": "0.5.0"
+ }
+ },
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -10139,7 +10919,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true
+ "devOptional": true
},
"node_modules/sax": {
"version": "1.4.1",
@@ -10522,6 +11302,12 @@
"node": ">=6"
}
},
+ "node_modules/state-local": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz",
+ "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==",
+ "license": "MIT"
+ },
"node_modules/std-env": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz",
@@ -10706,6 +11492,29 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/strings-file": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/strings-file/-/strings-file-0.0.5.tgz",
+ "integrity": "sha512-4/Fc8WshjKl/6MctVvdcdH3pQpbSP3J481hMUo9qMSpEK+piDYKYg8oSTGGKFMt2AyeZCQCnGF1uMq3i/xg/wQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "^0.4.13"
+ }
+ },
+ "node_modules/strings-file/node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -11140,6 +11949,16 @@
"@popperjs/core": "^2.9.0"
}
},
+ "node_modules/tmexchange": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/tmexchange/-/tmexchange-2.0.5.tgz",
+ "integrity": "sha512-fJQcBIY/ebEYDagOA0IY2PKYs2OJtBo0UGO+O2huyTkL9h+1Fg75DKw0JHkzXA1C56ejQdLW7S9YS/IL9rOpmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xml2js": "0.5.0"
+ }
+ },
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@@ -11347,7 +12166,7 @@
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
- "dev": true,
+ "devOptional": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -11631,6 +12450,15 @@
}
}
},
+ "node_modules/void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/wait-on": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz",
@@ -11940,6 +12768,42 @@
"xtend": "^4.0.0"
}
},
+ "node_modules/xliff": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/xliff/-/xliff-6.2.2.tgz",
+ "integrity": "sha512-8j1NITWDF3oRV3wkE514g1yYpk9pv3MKiOrVVaxY8YWtcQs1Ux12tfVmIwKeP5/GVfS7g0N6oRm1TqjR2MeEaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xml-js": "1.6.11"
+ }
+ },
+ "node_modules/xlsx": {
+ "version": "0.20.3",
+ "resolved": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
+ "integrity": "sha512-oLDq3jw7AcLqKWH2AhCpVTZl8mf6X2YReP+Neh0SJUzV/BdZYjth94tG5toiMB1PPrYtxOCfaoUCkvtuH+3AJA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "xlsx": "bin/xlsx.njs"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/xml-js": {
+ "version": "1.6.11",
+ "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz",
+ "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sax": "^1.2.4"
+ },
+ "bin": {
+ "xml-js": "bin/cli.js"
+ }
+ },
"node_modules/xml-parse-from-string": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz",
@@ -11983,15 +12847,15 @@
}
},
"node_modules/yaml": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
- "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz",
+ "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==",
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
- "node": ">= 14"
+ "node": ">= 14.6"
}
},
"node_modules/yargs": {
diff --git a/package.json b/package.json
index 52860e1..494c547 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,9 @@
"script:create:tool": "node scripts/create-tool.mjs",
"lint": "eslint src --max-warnings=0 --fix",
"typecheck": "tsc --project tsconfig.json --noEmit",
- "prepare": "husky install"
+ "prepare": "husky install",
+ "i18n:pull": "locize download --project-id e7156a3e-66fb-4035-a0f0-cebf1c63a3ba --path ./public/locales",
+ "i18n:sync": "locize sync --project-id e7156a3e-66fb-4035-a0f0-cebf1c63a3ba --path ./public/locales --update-values true --reference-language-only false"
},
"dependencies": {
"@emotion/react": "^11.11.4",
@@ -32,6 +34,7 @@
"@ffmpeg/util": "^0.12.2",
"@imgly/background-removal": "^1.6.0",
"@jimp/types": "^1.6.0",
+ "@monaco-editor/react": "^4.7.0",
"@mui/icons-material": "^5.15.20",
"@mui/material": "^5.15.20",
"@playwright/test": "^1.45.0",
@@ -41,6 +44,7 @@
"@types/lodash": "^4.17.5",
"@types/morsee": "^1.0.2",
"@types/omggif": "^1.0.5",
+ "@types/react-i18next": "^7.8.3",
"browser-image-compression": "^2.0.2",
"buffer": "^6.0.3",
"color": "^4.2.3",
@@ -49,10 +53,13 @@
"dayjs": "^1.11.13",
"fast-xml-parser": "^5.2.5",
"formik": "^2.4.6",
+ "i18next": "^25.3.2",
+ "i18next-http-backend": "^3.0.2",
"jimp": "^0.22.12",
"js-quantities": "^1.8.0",
"jszip": "^3.10.1",
"lint-staged": "^15.4.3",
+ "locize": "^4.0.14",
"lodash": "^4.17.21",
"mime": "^4.0.6",
"morsee": "^1.0.9",
@@ -68,6 +75,7 @@
"react-dom": "^18.3.1",
"react-filerobot-image-editor": "^4.9.1",
"react-helmet": "^6.1.0",
+ "react-i18next": "^15.6.0",
"react-image-crop": "^11.0.7",
"react-konva": "^18.2.10",
"react-router-dom": "^6.23.1",
@@ -102,6 +110,8 @@
"eslint-plugin-tailwindcss": "^3.17.0",
"happy-dom": "^12.10.3",
"husky": "^9.0.11",
+ "i18next-locize-backend": "^7.0.4",
+ "locize-cli": "^10.1.1",
"postcss": "^8.4.38",
"prettier": "3.1.1",
"start-server-and-test": "^2.0.4",
diff --git a/public/locales/de/audio.json b/public/locales/de/audio.json
new file mode 100644
index 0000000..92c1d64
--- /dev/null
+++ b/public/locales/de/audio.json
@@ -0,0 +1,42 @@
+{
+ "changeSpeed": {
+ "description": "รndern Sie die Wiedergabegeschwindigkeit von Audiodateien. Beschleunigen oder verlangsamen Sie die Wiedergabe, ohne die Tonhรถhe zu verรคndern.",
+ "inputTitle": "Audioeingang",
+ "newAudioSpeed": "Neue Audiogeschwindigkeit",
+ "outputFormat": "Ausgabeformat",
+ "resultTitle": "Bearbeitetes Audio",
+ "settingSpeed": "Geschwindigkeit einstellen",
+ "shortDescription": "รndern Sie die Geschwindigkeit von Audiodateien",
+ "speedDescription": "Standardmultiplikator: 2 bedeutet 2x schneller",
+ "title": "Audiogeschwindigkeit รคndern",
+ "toolInfo": {
+ "title": "Was ist {{title}}?"
+ }
+ },
+ "extractAudio": {
+ "description": "Extrahieren Sie Audiospuren aus Videodateien.",
+ "extractingAudio": "Audio extrahieren",
+ "inputTitle": "Eingangsvideo",
+ "outputFormat": "Ausgabeformat",
+ "outputFormatDescription": "Wรคhlen Sie das Format fรผr das zu extrahierende Audio aus.",
+ "resultTitle": "Extrahiertes Audio",
+ "shortDescription": "Extrahieren Sie Audio aus Videodateien (MP4, MOV usw.) in AAC, MP3 oder WAV.",
+ "title": "Audio aus Video extrahieren",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie die Audiospur aus Videodateien extrahieren. Sie kรถnnen zwischen verschiedenen Audioformaten wรคhlen, darunter AAC, MP3 und WAV.",
+ "title": "Was ist {{title}}?"
+ }
+ },
+ "mergeAudio": {
+ "description": "Kombinieren Sie mehrere Audiodateien zu einer einzigen Audiodatei, indem Sie sie der Reihe nach aneinanderreihen.",
+ "longDescription": "Mit diesem Tool kรถnnen Sie mehrere Audiodateien in der Reihenfolge des Hochladens zu einer einzigen Datei zusammenfรผgen. Ideal zum Kombinieren von Podcast-Segmenten, Musiktiteln oder anderen Audiodateien. Unterstรผtzt verschiedene Audioformate, darunter MP3, AAC und WAV.",
+ "shortDescription": "Mehrere Audiodateien zu einer zusammenfรผhren (MP3, AAC, WAV).",
+ "title": "Audio zusammenfรผhren"
+ },
+ "trim": {
+ "description": "Schneiden und trimmen Sie Audiodateien, um bestimmte Segmente durch Angabe von Start- und Endzeiten zu extrahieren.",
+ "longDescription": "Mit diesem Tool kรถnnen Sie Audiodateien durch Festlegen von Start- und Endzeiten kรผrzen. Sie kรถnnen bestimmte Abschnitte aus lรคngeren Audiodateien extrahieren, unerwรผnschte Teile entfernen oder kรผrzere Clips erstellen. Unterstรผtzt verschiedene Audioformate, darunter MP3, AAC und WAV. Ideal fรผr Podcast-Bearbeitung, Musikproduktion und alle anderen Audiobearbeitungsaufgaben.",
+ "shortDescription": "Schneiden Sie Audiodateien, um bestimmte Zeitsegmente zu extrahieren (MP3, AAC, WAV).",
+ "title": "Audio trimmen"
+ }
+}
diff --git a/public/locales/de/csv.json b/public/locales/de/csv.json
new file mode 100644
index 0000000..c7c9463
--- /dev/null
+++ b/public/locales/de/csv.json
@@ -0,0 +1,114 @@
+{
+ "changeCsvSeparator": {
+ "description": "รndern Sie das Trennzeichen in CSV-Dateien. Konvertieren Sie zwischen verschiedenen CSV-Formaten wie Komma, Semikolon, Tabulator oder benutzerdefinierten Trennzeichen.",
+ "shortDescription": "CSV-Dateitrennzeichen รคndern",
+ "title": "CSV-Trennzeichen รคndern"
+ },
+ "csvRowsToColumns": {
+ "description": "Dieses Tool konvertiert Zeilen einer CSV-Datei (Comma Separated Values) in Spalten. Es extrahiert die horizontalen Zeilen einzeln aus der CSV-Eingabedatei, dreht sie um 90 Grad und gibt sie als vertikale Spalten nacheinander, durch Kommas getrennt, aus.', longDescription: 'Dieses Tool konvertiert Zeilen einer CSV-Datei (Comma Separated Values) in Spalten. Wenn die CSV-Eingabedaten beispielsweise sechs Zeilen haben, enthรคlt die Ausgabe sechs Spalten, und die Elemente der Zeilen werden von oben nach unten angeordnet. In einer korrekt formatierten CSV-Datei ist die Anzahl der Werte in jeder Zeile gleich. Fehlende Felder in Zeilen kรถnnen vom Programm korrigiert werden. Sie haben die Wahl zwischen verschiedenen Optionen: Fรผllen Sie fehlende Daten mit leeren Elementen auf oder ersetzen Sie fehlende Daten durch benutzerdefinierte Elemente wie \"missing\", \"?\" oder \"x\". Wรคhrend der Konvertierung bereinigt das Tool die CSV-Datei auรerdem von unnรถtigen Informationen wie Leerzeilen (Zeilen ohne sichtbare Informationen) und Kommentaren. Damit das Tool Kommentare korrekt erkennt, kรถnnen Sie in den Optionen das Symbol am Zeilenanfang angeben, mit dem ein Kommentar beginnt. Dieses Symbol ist typischerweise ein Rautezeichen (#) oder ein doppelter Schrรคgstrich (//). CSV-abulous!",
+ "longDescription": "Dieses Tool konvertiert Zeilen einer CSV-Datei (Comma Separated Values) in Spalten. Wenn die CSV-Eingabedaten beispielsweise sechs Zeilen umfassen, enthรคlt die Ausgabe sechs Spalten, und die Elemente der Zeilen werden von oben nach unten angeordnet. In einer korrekt formatierten CSV-Datei ist die Anzahl der Werte in jeder Zeile gleich. Sollten in Zeilen jedoch Felder fehlen, kann das Programm diese korrigieren. Sie haben die Wahl zwischen verschiedenen Optionen: Fรผllen Sie fehlende Daten mit leeren Elementen auf oder ersetzen Sie fehlende Daten durch benutzerdefinierte Elemente, wie z. B.",
+ "shortDescription": "Konvertieren Sie CSV-Zeilen in Spalten.",
+ "title": "CSV-Zeilen in Spalten konvertieren"
+ },
+ "csvToJson": {
+ "columnSeparator": "Spaltentrennzeichen (z. B. , ; \\t)",
+ "commentSymbol": "Kommentarsymbol (z. B. #)",
+ "conversionOptions": "Konvertierungsoptionen",
+ "description": "Konvertieren Sie CSV-Dateien in das JSON-Format mit anpassbaren Optionen fรผr Trennzeichen, Anfรผhrungszeichen und Ausgabeformatierung. Unterstรผtzt werden Header, Kommentare und dynamische Typkonvertierung.",
+ "dynamicTypes": "Dynamische Typen",
+ "dynamicTypesDescription": "Automatische Konvertierung von Zahlen und Booleschen Werten",
+ "errorParsing": "Fehler beim Parsen der CSV-Datei: {{error}}",
+ "fieldQuote": "Feld Zitat (z. B. \")",
+ "inputCsvFormat": "Eingabe-CSV-Format",
+ "inputTitle": "Eingabe-CSV",
+ "resultTitle": "JSON-Ausgabe",
+ "shortDescription": "Konvertieren Sie CSV-Daten in das JSON-Format.",
+ "skipEmptyLines": "Leere Zeilen รผberspringen",
+ "skipEmptyLinesDescription": "Leere Zeilen in der CSV-Eingabe ignorieren",
+ "title": "Konvertieren Sie CSV in JSON",
+ "useHeaders": "Verwenden Sie รberschriften",
+ "useHeadersDescription": "Behandeln Sie die erste Zeile als Spaltenรผberschrift"
+ },
+ "csvToTsv": {
+ "description": "Laden Sie Ihre CSV-Datei im untenstehenden Formular hoch. Sie wird automatisch in eine TSV-Datei konvertiert. In den Tool-Optionen kรถnnen Sie das CSV-Eingabeformat anpassen โ Feldtrennzeichen, Anfรผhrungszeichen und Kommentarsymbol festlegen, leere CSV-Zeilen รผberspringen und festlegen, ob CSV-Spaltenรผberschriften beibehalten werden sollen.",
+ "longDescription": "Dieses Tool wandelt CSV-Daten (Comma Separated Values) in TSV-Daten (Tab Separated Values) um. Sowohl CSV als auch TSV sind gรคngige Dateiformate zur Speicherung tabellarischer Daten, verwenden jedoch unterschiedliche Trennzeichen zur Trennung der Werte โ CSV verwendet Kommas (",
+ "shortDescription": "Konvertieren Sie CSV-Daten in das TSV-Format.",
+ "title": "Konvertieren Sie CSV in TSV"
+ },
+ "csvToXml": {
+ "description": "Konvertieren Sie CSV-Dateien mit anpassbaren Optionen in das XML-Format.",
+ "shortDescription": "Konvertieren Sie CSV-Daten in das XML-Format.",
+ "title": "Konvertieren Sie CSV in XML"
+ },
+ "csvToYaml": {
+ "description": "Laden Sie Ihre CSV-Datei einfach im untenstehenden Formular hoch. Sie wird dann automatisch in eine YAML-Datei konvertiert. In den Tool-Optionen kรถnnen Sie Feldtrennzeichen, Anfรผhrungszeichen und Kommentarzeichen festlegen, um das Tool an benutzerdefinierte CSV-Formate anzupassen. Zusรคtzlich kรถnnen Sie das YAML-Ausgabeformat auswรคhlen: eines, das CSV-Header beibehรคlt, oder eines, das CSV-Header ausschlieรt.",
+ "longDescription": "Dieses Tool wandelt CSV-Daten (Comma Separated Values) in YAML-Daten (Yet Another Markup Language) um. CSV ist ein einfaches, tabellarisches Format zur Darstellung matrixartiger Datentypen mit Zeilen und Spalten. YAML hingegen ist ein erweitertes Format (eigentlich eine Obermenge von JSON), das besser lesbare Daten fรผr die Serialisierung erzeugt und Listen, Wรถrterbรผcher und verschachtelte Objekte unterstรผtzt. Das Programm unterstรผtzt verschiedene CSV-Eingabeformate โ die Eingabedaten kรถnnen durch Kommas (Standard), Semikolons, Pipes oder ein anderes Trennzeichen getrennt sein. Sie kรถnnen das genaue Trennzeichen Ihrer Daten in den Optionen festlegen. Ebenso kรถnnen Sie in den Optionen das Anfรผhrungszeichen festlegen, das zum Umschlieรen von CSV-Feldern verwendet wird (standardmรครig ein doppeltes Anfรผhrungszeichen). Sie kรถnnen auch Zeilen รผberspringen, die mit Kommentaren beginnen, indem Sie die Kommentarsymbole in den Optionen angeben. So halten Sie Ihre Daten รผbersichtlich, indem Sie unnรถtige Zeilen รผberspringen. Es gibt zwei Mรถglichkeiten, CSV in YAML zu konvertieren. Die erste Methode konvertiert jede CSV-Zeile in eine YAML-Liste. Die zweite Methode extrahiert Header aus der ersten CSV-Zeile und erstellt YAML-Objekte mit Schlรผsseln basierend auf diesen Headern. Sie kรถnnen das YAML-Ausgabeformat auch anpassen, indem Sie die Anzahl der Leerzeichen fรผr die Einrรผckung von YAML-Strukturen angeben. Wenn Sie die umgekehrte Konvertierung durchfรผhren, d. h. YAML in CSV umwandeln mรถchten, kรถnnen Sie unser Tool โYAML in CSV konvertierenโ verwenden. CSV-genial!",
+ "shortDescription": "Konvertieren Sie schnell eine CSV-Datei in eine YAML-Datei.",
+ "title": "Konvertieren Sie CSV in YAML"
+ },
+ "findIncompleteCsvRecords": {
+ "checkingOptions": "Optionen prรผfen",
+ "commentCharacterDescription": "Geben Sie das Zeichen ein, das den Beginn einer Kommentarzeile kennzeichnet. Zeilen, die mit diesem Symbol beginnen, werden รผbersprungen.",
+ "csvInputOptions": "CSV-Eingabeoptionen",
+ "csvSeparatorDescription": "Geben Sie das Zeichen ein, das zum Trennen von Spalten in der CSV-Eingabedatei verwendet wird.",
+ "deleteLinesWithNoData": "Zeilen ohne Daten lรถschen",
+ "deleteLinesWithNoDataDescription": "Entfernen Sie leere Zeilen aus der CSV-Eingabedatei.",
+ "description": "Laden Sie einfach Ihre CSV-Datei im untenstehenden Formular hoch. Das Tool prรผft automatisch, ob in Zeilen und Spalten Werte fehlen. In den Tool-Optionen kรถnnen Sie das Eingabedateiformat anpassen (Trennzeichen, Anfรผhrungszeichen und Kommentarzeichen festlegen). Zusรคtzlich kรถnnen Sie die Prรผfung auf leere Werte aktivieren, leere Zeilen รผberspringen und die Anzahl der Fehlermeldungen in der Ausgabe begrenzen.",
+ "findEmptyValues": "Leere Werte finden",
+ "findEmptyValuesDescription": "Zeigt eine Meldung zu leeren CSV-Feldern an (das sind keine fehlenden Felder, sondern Felder, die nichts enthalten).",
+ "inputTitle": "Eingabe-CSV",
+ "limitNumberOfMessages": "Anzahl der Nachrichten begrenzen",
+ "messageLimitDescription": "Legen Sie die Begrenzung der Anzahl der Nachrichten in der Ausgabe fest.",
+ "quoteCharacterDescription": "Geben Sie das Anfรผhrungszeichen ein, das zum Zitieren der CSV-Eingabefelder verwendet wird.",
+ "resultTitle": "CSV-Status",
+ "shortDescription": "Finden Sie schnell Zeilen und Spalten in CSV, in denen Werte fehlen.",
+ "title": "Unvollstรคndige CSV-Datensรคtze finden",
+ "toolInfo": {
+ "title": "Was ist ein {{title}}?"
+ }
+ },
+ "insertCsvColumns": {
+ "appendColumns": "Spalten anhรคngen",
+ "commentCharacterDescription": "Geben Sie das Zeichen ein, das den Beginn einer Kommentarzeile kennzeichnet. Zeilen, die mit diesem Symbol beginnen, werden รผbersprungen.",
+ "csvOptions": "CSV-Optionen",
+ "csvSeparator": "CSV-Trennzeichen",
+ "csvToInsert": "CSV zum Einfรผgen",
+ "csvToInsertDescription": "Geben Sie eine oder mehrere Spalten ein, die Sie in die CSV-Datei einfรผgen mรถchten. Das Zeichen zur Spaltentrennung muss mit dem Zeichen in der CSV-Eingabedatei รผbereinstimmen. Hinweis: Leere Zeilen werden ignoriert.",
+ "customFillDescription": "Wenn die CSV-Eingabedatei unvollstรคndig ist (fehlende Werte), fรผgen Sie den Datensรคtzen dann leere Felder oder benutzerdefinierte Symbole hinzu, um eine wohlgeformte CSV-Datei zu erstellen?",
+ "customFillValueDescription": "Verwenden Sie diesen benutzerdefinierten Wert, um fehlende Felder auszufรผllen. (Funktioniert nur mit dem oben beschriebenen Modus โBenutzerdefinierte Werteโ).",
+ "customPosition": "Benutzerdefinierte Position",
+ "customPositionOptionsDescription": "Wรคhlen Sie die Methode zum Einfรผgen der Spalten in die CSV-Datei.",
+ "description": "Fรผgen Sie den CSV-Daten an angegebenen Positionen neue Spalten hinzu.",
+ "fillWithCustomValues": "Mit Zollwerten fรผllen",
+ "fillWithEmptyValues": "Mit leeren Werten fรผllen",
+ "headerName": "Kopfzeilenname",
+ "headerNameDescription": "รberschrift der Spalte, nach der Sie Spalten einfรผgen mรถchten.",
+ "inputTitle": "Eingabe-CSV",
+ "insertingPositionDescription": "Geben Sie an, wo die Spalten in der CSV-Datei eingefรผgt werden sollen.",
+ "position": "Position",
+ "positionOptions": "Positionsoptionen",
+ "prependColumns": "Spalten voranstellen",
+ "quoteCharDescription": "Geben Sie das Anfรผhrungszeichen ein, das zum Zitieren der CSV-Eingabefelder verwendet wird.",
+ "resultTitle": "Ausgabe-CSV",
+ "rowNumberDescription": "Nummer der Spalte, nach der Sie Spalten einfรผgen mรถchten.",
+ "separatorDescription": "Geben Sie das Zeichen ein, das zum Trennen von Spalten in der CSV-Eingabedatei verwendet wird.",
+ "shortDescription": "Fรผgen Sie schnell eine oder mehrere neue Spalten an beliebiger Stelle in einer CSV-Datei ein.",
+ "title": "CSV-Spalten einfรผgen",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie neue Spalten an bestimmten Positionen in CSV-Daten einfรผgen. Sie kรถnnen Spalten basierend auf รberschriftennamen oder Spaltennummern an benutzerdefinierten Positionen voranstellen, anhรคngen oder einfรผgen.",
+ "title": "CSV-Spalten einfรผgen"
+ }
+ },
+ "swapCsvColumns": {
+ "description": "Laden Sie einfach Ihre CSV-Datei im untenstehenden Formular hoch und geben Sie die zu tauschenden Spalten an. Das Tool รคndert dann automatisch die Positionen der angegebenen Spalten in der Ausgabedatei. In den Tool-Optionen kรถnnen Sie die zu tauschenden Spaltenpositionen oder -namen angeben, unvollstรคndige Daten korrigieren und optional leere und auskommentierte Datensรคtze entfernen.",
+ "longDescription": "Dieses Tool reorganisiert CSV-Daten, indem es die Positionen der Spalten tauscht. Das Tauschen von Spalten verbessert die Lesbarkeit einer CSV-Datei, indem hรคufig verwendete Daten zusammen oder nach vorne platziert werden, um den Vergleich und die Bearbeitung zu erleichtern. Sie kรถnnen beispielsweise die erste Spalte mit der letzten oder die zweite Spalte mit der dritten tauschen. Um Spalten basierend auf ihren Positionen zu tauschen, wรคhlen Sie das",
+ "shortDescription": "CSV-Spalten neu anordnen.",
+ "title": "CSV-Spalten austauschen"
+ },
+ "transposeCsv": {
+ "description": "Laden Sie einfach Ihre CSV-Datei in das untenstehende Formular hoch. Das Tool transponiert Ihre CSV-Datei automatisch. In den Tool-Optionen kรถnnen Sie das Zeichen angeben, mit dem die Kommentarzeilen in der CSV-Datei beginnen, um diese zu entfernen. Falls die CSV-Datei unvollstรคndig ist (fehlende Werte), kรถnnen Sie fehlende Werte durch ein Leerzeichen oder ein benutzerdefiniertes Zeichen ersetzen.",
+ "longDescription": "Dieses Tool transponiert Komma-getrennte Werte (CSV). Es behandelt die CSV-Datei wie eine Datenmatrix und spiegelt alle Elemente entlang der Hauptdiagonale. Die Ausgabe enthรคlt dieselben CSV-Daten wie die Eingabe, wobei nun alle Zeilen zu Spalten und alle Spalten zu Zeilen werden. Nach der Transposition weist die CSV-Datei entgegengesetzte Dimensionen auf. Wenn die Eingabedatei beispielsweise 4 Spalten und 3 Zeilen enthรคlt, enthรคlt die Ausgabedatei 3 Spalten und 4 Zeilen. Wรคhrend der Konvertierung bereinigt das Programm die Daten auรerdem von unnรถtigen Zeilen und korrigiert unvollstรคndige Daten. Insbesondere lรถscht das Tool automatisch alle leeren Datensรคtze und Kommentare, die mit einem bestimmten Zeichen beginnen, das Sie in den Optionen festlegen kรถnnen. Sollten die CSV-Daten beschรคdigt oder verloren gehen, ergรคnzt das Dienstprogramm die Datei zusรคtzlich mit leeren Feldern oder benutzerdefinierten Feldern, die Sie in den Optionen festlegen kรถnnen. CSV-unverstรคndlich!",
+ "shortDescription": "Transponieren Sie schnell eine CSV-Datei.",
+ "title": "CSV transponieren"
+ }
+}
diff --git a/public/locales/de/image.json b/public/locales/de/image.json
new file mode 100644
index 0000000..8a91930
--- /dev/null
+++ b/public/locales/de/image.json
@@ -0,0 +1,98 @@
+{
+ "changeColors": {
+ "description": "Welt",
+ "shortDescription": "Schnelles Austauschen der Farben in einem Bild",
+ "title": "Farben im Bild รคndern"
+ },
+ "changeOpacity": {
+ "description": "Passen Sie die Transparenz Ihrer Bilder ganz einfach an. Laden Sie einfach Ihr Bild hoch, stellen Sie mit dem Schieberegler die gewรผnschte Deckkraft zwischen 0 (vollstรคndig transparent) und 1 (vollstรคndig undurchsichtig) ein und laden Sie das geรคnderte Bild herunter.",
+ "shortDescription": "Transparenz von Bildern anpassen",
+ "title": "Bilddeckkraft รคndern"
+ },
+ "compress": {
+ "description": "Reduzieren Sie die Bilddateigrรถรe, ohne die Qualitรคt zu beeintrรคchtigen.",
+ "inputTitle": "Eingabebild",
+ "resultTitle": "Komprimiertes Bild",
+ "shortDescription": "Komprimieren Sie Bilder, um die Dateigrรถรe zu reduzieren und gleichzeitig eine angemessene Qualitรคt beizubehalten.",
+ "title": "Bild komprimieren"
+ },
+ "compressPng": {
+ "description": "Dies ist ein Programm zum Komprimieren von PNG-Bildern. Sobald Sie Ihr PNG-Bild in den Eingabebereich einfรผgen, komprimiert das Programm es und zeigt das Ergebnis im Ausgabebereich an. In den Optionen kรถnnen Sie den Komprimierungsgrad anpassen und die alte und neue Bilddateigrรถรe einsehen.",
+ "shortDescription": "PNG schnell komprimieren",
+ "title": "PNG komprimieren"
+ },
+ "convertJgpToPng": {
+ "description": "Konvertieren Sie Ihre JPG-Bilder schnell in PNG. Importieren Sie einfach Ihr PNG-Bild im Editor links",
+ "shortDescription": "Konvertieren Sie Ihre JPG-Bilder schnell in PNG",
+ "title": "Konvertieren Sie JPG in PNG"
+ },
+ "convertToJpg": {
+ "description": "Konvertieren Sie verschiedene Bildformate (PNG, GIF, TIF, PSD, SVG, WEBP, HEIC, RAW) in JPG mit anpassbaren Qualitรคts- und Hintergrundfarbeinstellungen.",
+ "shortDescription": "Konvertieren Sie Bilder mit Qualitรคtskontrolle in JPG",
+ "title": "Bilder in JPG konvertieren"
+ },
+ "createTransparent": {
+ "description": "Welt",
+ "shortDescription": "Machen Sie ein Bild schnell transparent",
+ "title": "Transparentes PNG erstellen"
+ },
+ "crop": {
+ "description": "Schneiden Sie Bilder zu, um unerwรผnschte Bereiche zu entfernen.",
+ "inputTitle": "Eingabebild",
+ "resultTitle": "Zugeschnittenes Bild",
+ "shortDescription": "Bilder schnell zuschneiden.",
+ "title": "Bild zuschneiden"
+ },
+ "editor": {
+ "description": "Erweiterter Bildeditor mit Werkzeugen zum Zuschneiden, Drehen, Kommentieren, Anpassen von Farben und Hinzufรผgen von Wasserzeichen. Bearbeiten Sie Ihre Bilder mit professionellen Werkzeugen direkt in Ihrem Browser.",
+ "shortDescription": "Bearbeiten Sie Bilder mit erweiterten Tools und Funktionen",
+ "title": "Bildeditor"
+ },
+ "imageToText": {
+ "description": "Extrahieren Sie Text aus Bildern (JPG, PNG) mithilfe der optischen Zeichenerkennung (OCR).",
+ "shortDescription": "Extrahieren Sie mithilfe von OCR Text aus Bildern.",
+ "title": "Bild zu Text (OCR)"
+ },
+ "qrCode": {
+ "description": "Generieren Sie QR-Codes fรผr verschiedene Datentypen: URL, Text, E-Mail, Telefon, SMS, WLAN, vCard und mehr.",
+ "shortDescription": "Erstellen Sie individuelle QR-Codes fรผr verschiedene Datenformate.",
+ "title": "QR-Code-Generator"
+ },
+ "removeBackground": {
+ "description": "Welt",
+ "shortDescription": "Hintergrรผnde automatisch aus Bildern entfernen",
+ "title": "Hintergrund aus Bild entfernen"
+ },
+ "resize": {
+ "description": "Passen Sie die Grรถรe von Bildern an andere Abmessungen an.",
+ "dimensionType": "Dimensionstyp",
+ "heightDescription": "Hรถhe (in Pixeln)",
+ "inputTitle": "Eingabebild",
+ "maintainAspectRatio": "Seitenverhรคltnis beibehalten",
+ "maintainAspectRatioDescription": "Behalten Sie das ursprรผngliche Seitenverhรคltnis des Bildes bei.",
+ "percentage": "Prozentsatz",
+ "percentageDescription": "Prozentsatz der Originalgrรถรe (z. B. 50 fรผr halbe Grรถรe, 200 fรผr doppelte Grรถรe)",
+ "resizeByPercentage": "Grรถรe um Prozent รคndern",
+ "resizeByPercentageDescription": "รndern Sie die Grรถรe, indem Sie einen Prozentsatz der Originalgrรถรe angeben.",
+ "resizeByPixels": "Grรถรe in Pixeln รคndern",
+ "resizeByPixelsDescription": "รndern Sie die Grรถรe, indem Sie die Abmessungen in Pixeln angeben.",
+ "resizeMethod": "Grรถรenรคnderungsmethode",
+ "resultTitle": "Bildgrรถรe geรคndert",
+ "setHeight": "Hรถhe festlegen",
+ "setHeightDescription": "Geben Sie die Hรถhe in Pixeln an und berechnen Sie die Breite basierend auf dem Seitenverhรคltnis.",
+ "setWidth": "Breite festlegen",
+ "setWidthDescription": "Geben Sie die Breite in Pixeln an und berechnen Sie die Hรถhe basierend auf dem Seitenverhรคltnis.",
+ "shortDescription": "รndern Sie die Grรถรe von Bildern ganz einfach.",
+ "title": "Bildgrรถรe รคndern",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie die Grรถรe von JPG-, PNG-, SVG- und GIF-Bildern รคndern. Sie kรถnnen die Grรถรe รคndern, indem Sie die Abmessungen in Pixeln oder Prozent angeben und das ursprรผngliche Seitenverhรคltnis beibehalten.",
+ "title": "Bildgrรถรe รคndern"
+ },
+ "widthDescription": "Breite (in Pixeln)"
+ },
+ "rotate": {
+ "description": "Drehen Sie ein Bild um einen bestimmten Winkel.",
+ "shortDescription": "Drehen Sie ein Bild ganz einfach.",
+ "title": "Bild drehen"
+ }
+}
diff --git a/public/locales/de/json.json b/public/locales/de/json.json
new file mode 100644
index 0000000..23d63cb
--- /dev/null
+++ b/public/locales/de/json.json
@@ -0,0 +1,62 @@
+{
+ "escapeJson": {
+ "description": "Escapen Sie Sonderzeichen in JSON-Strings. Konvertieren Sie JSON-Daten in ein korrekt maskiertes Format fรผr eine sichere รbertragung oder Speicherung.",
+ "shortDescription": "Escape-Sonderzeichen in JSON",
+ "title": "Escape-JSON"
+ },
+ "jsonToXml": {
+ "description": "Konvertieren Sie JSON-Daten in das XML-Format. Transformieren Sie strukturierte JSON-Objekte in wohlgeformte XML-Dokumente.",
+ "shortDescription": "Konvertieren Sie JSON in das XML-Format",
+ "title": "JSON zu XML"
+ },
+ "minify": {
+ "description": "Entfernen Sie alle unnรถtigen Leerzeichen aus JSON.",
+ "inputTitle": "JSON-Eingabe",
+ "resultTitle": "Minimiertes JSON",
+ "shortDescription": "Minimieren Sie JSON durch Entfernen von Leerzeichen",
+ "title": "JSON minimieren",
+ "toolInfo": {
+ "description": "Bei der JSON-Minimierung werden alle unnรถtigen Leerzeichen aus JSON-Daten entfernt, ohne dass deren Gรผltigkeit verloren geht. Dazu gehรถren Leerzeichen, Zeilenumbrรผche und Einrรผckungen, die fรผr die korrekte JSON-Analyse nicht erforderlich sind. Durch die Minimierung wird die Grรถรe von JSON-Daten reduziert, wodurch die Speicherung und รbertragung effizienter wird, wรคhrend die Datenstruktur und die Werte unverรคndert bleiben.",
+ "title": "Was ist JSON-Minimierung?"
+ }
+ },
+ "prettify": {
+ "description": "Formatieren Sie JSON mit den richtigen Einrรผckungen und Abstรคnden.",
+ "indentation": "Vertiefung",
+ "inputTitle": "JSON-Eingabe",
+ "resultTitle": "Verschรถnertes JSON",
+ "shortDescription": "Formatieren und Verschรถnern von JSON-Code",
+ "title": "JSON verschรถnern",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie JSON-Daten mit den richtigen Einrรผckungen und Abstรคnden formatieren, sodass sie besser lesbar und einfacher zu bearbeiten sind.",
+ "title": "JSON verschรถnern"
+ },
+ "useSpaces": "Rรคume verwenden",
+ "useSpacesDescription": "Ausgabe mit Leerzeichen einrรผcken",
+ "useTabs": "Verwenden von Registerkarten",
+ "useTabsDescription": "Einrรผcken der Ausgabe mit Tabulatoren."
+ },
+ "stringify": {
+ "description": "Konvertieren Sie JavaScript-Objekte in das JSON-String-Format. Serialisieren Sie Datenstrukturen zur Speicherung oder รbertragung in JSON-Strings.",
+ "shortDescription": "Konvertieren Sie Objekte in JSON-Zeichenfolgen",
+ "title": "Stringify JSON"
+ },
+ "tsvToJson": {
+ "description": "Konvertieren Sie TSV-Daten (Tab-Separated Values) in das JSON-Format. Transformieren Sie tabellarische Daten in strukturierte JSON-Objekte.",
+ "shortDescription": "Konvertieren Sie TSV in das JSON-Format",
+ "title": "TSV zu JSON"
+ },
+ "validateJson": {
+ "description": "รberprรผfen Sie, ob JSON gรผltig und wohlgeformt ist.",
+ "inputTitle": "JSON-Eingabe",
+ "invalidJson": "โ {{error}}",
+ "resultTitle": "Validierungsergebnis",
+ "shortDescription": "JSON-Code auf Fehler รผberprรผfen",
+ "title": "JSON validieren",
+ "toolInfo": {
+ "description": "JSON (JavaScript Object Notation) ist ein einfaches Datenaustauschformat. Die JSON-Validierung stellt sicher, dass die Datenstruktur dem JSON-Standard entspricht. Ein gรผltiges JSON-Objekt muss Folgendes enthalten: โ Eigenschaftsnamen in doppelten Anfรผhrungszeichen. โ Ausgewogene geschweifte Klammern {}. โ Keine abschlieรenden Kommas nach dem letzten Schlรผssel-Wert-Paar. โ Korrekte Verschachtelung von Objekten und Arrays. Dieses Tool prรผft das eingegebene JSON und gibt Feedback, um hรคufige Fehler zu identifizieren und zu beheben.",
+ "title": "Was ist JSON-Validierung?"
+ },
+ "validJson": "โ
Gรผltiges JSON"
+ }
+}
diff --git a/public/locales/de/list.json b/public/locales/de/list.json
new file mode 100644
index 0000000..5487dac
--- /dev/null
+++ b/public/locales/de/list.json
@@ -0,0 +1,208 @@
+{
+ "duplicate": {
+ "concatenate": "Verketten",
+ "concatenateDescription": "Kopien verketten (wenn nicht aktiviert, werden die Elemente miteinander verwoben)",
+ "copyDescription": "Anzahl der Kopien (kann Bruchteile sein)",
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Duplizieren von Listeneintrรคgen. Geben Sie Ihre Liste ein und legen Sie die Duplizierungskriterien fest, um Kopien von Eintrรคgen zu erstellen. Ideal fรผr Datenerweiterungen, Tests oder die Erstellung wiederkehrender Muster.",
+ "duplicationOptions": "Duplizierungsoptionen",
+ "examples": {
+ "fractional": {
+ "description": "Dieses Beispiel zeigt, wie eine Liste mit einer Bruchzahl von Kopien dupliziert wird.",
+ "title": "Bruchduplizierung"
+ },
+ "interweave": {
+ "description": "Dieses Beispiel zeigt, wie Elemente miteinander verwoben werden, anstatt sie zu verketten.",
+ "title": "Verweben von Gegenstรคnden"
+ },
+ "reverse": {
+ "description": "Dieses Beispiel zeigt, wie eine Liste in umgekehrter Reihenfolge dupliziert wird.",
+ "title": "Rรผckwรคrtsduplizierung"
+ },
+ "simple": {
+ "description": "Dieses Beispiel zeigt, wie eine Liste von Wรถrtern dupliziert wird.",
+ "title": "Einfache Vervielfรคltigung"
+ }
+ },
+ "inputTitle": "Eingabeliste",
+ "joinSeparatorDescription": "Trennzeichen zum Verbinden der duplizierten Liste",
+ "resultTitle": "Duplizierte Liste",
+ "reverse": "Umkehren",
+ "reverseDescription": "Umkehren der duplizierten Elemente",
+ "shortDescription": "Doppelte Listenelemente mit angegebenen Kriterien",
+ "splitByRegex": "Aufteilen nach regulรคrem Ausdruck",
+ "splitBySymbol": "Nach Symbol teilen",
+ "splitOptions": "Teilungsoptionen",
+ "splitSeparatorDescription": "Trennzeichen zum Teilen der Liste",
+ "title": "Duplikat",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie Elemente einer Liste duplizieren. Sie kรถnnen die Anzahl der Kopien (einschlieรlich Bruchzahlen) festlegen, steuern, ob Elemente verknรผpft oder verwoben werden, und sogar die Duplikate umkehren. Es ist nรผtzlich, um wiederkehrende Muster zu erstellen, Testdaten zu generieren oder Listen mit vorhersehbarem Inhalt zu erweitern.",
+ "title": "Listenduplizierung"
+ }
+ },
+ "findMostPopular": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Auffinden der beliebtesten Elemente in einer Liste. Geben Sie Ihre Liste ein und erhalten Sie sofort die am hรคufigsten vorkommenden Elemente. Ideal fรผr Datenanalysen, Trenderkennung oder die Suche nach gemeinsamen Elementen.",
+ "shortDescription": "Am hรคufigsten vorkommende Elemente finden",
+ "title": "Finden Sie die beliebtesten"
+ },
+ "findUnique": {
+ "caseSensitiveItems": "Groร- und Kleinschreibung beachten",
+ "caseSensitiveItemsDescription": "Geben Sie Elemente mit unterschiedlicher Groร-/Kleinschreibung als eindeutige Elemente in der Liste aus.",
+ "delimiterDescription": "Legen Sie ein Trennsymbol oder einen regulรคren Ausdruck fest.",
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Auffinden eindeutiger Elemente in einer Liste. Geben Sie Ihre Liste ein und erhalten Sie sofort alle eindeutigen Werte, ohne Duplikate. Ideal fรผr Datenbereinigung, Deduplizierung oder das Auffinden eindeutiger Elemente.",
+ "findAbsolutelyUniqueItems": "Finden Sie absolut einzigartige Artikel",
+ "findAbsolutelyUniqueItemsDescription": "Zeigen Sie nur die Elemente der Liste an, die in einer einzigen Kopie vorhanden sind.",
+ "inputListDelimiter": "Eingabelisten-Trennzeichen",
+ "inputTitle": "Eingabeliste",
+ "outputListDelimiter": "Ausgabelisten-Trennzeichen",
+ "resultTitle": "Einzigartige Gegenstรคnde",
+ "shortDescription": "Suchen Sie nach eindeutigen Elementen in einer Liste",
+ "skipEmptyItems": "Leere Elemente รผberspringen",
+ "skipEmptyItemsDescription": "Schlieรen Sie die leeren Listenelemente nicht in die Ausgabe ein.",
+ "title": "Finden Sie einzigartige",
+ "trimItems": "Listenelemente kรผrzen",
+ "trimItemsDescription": "Entfernen Sie vor dem Vergleichen von Elementen fรผhrende und nachfolgende Leerzeichen.",
+ "uniqueItemOptions": "Einzigartige Artikeloptionen"
+ },
+ "group": {
+ "deleteEmptyItems": "Leere Elemente lรถschen",
+ "deleteEmptyItemsDescription": "Ignorieren Sie leere Elemente und nehmen Sie sie nicht in die Gruppen auf.",
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Gruppieren von Listenelementen. Geben Sie Ihre Liste ein und legen Sie Gruppierungskriterien fest, um Elemente in logische Gruppen zu ordnen. Ideal zum Kategorisieren von Daten, Organisieren von Informationen oder Erstellen strukturierter Listen. Unterstรผtzt benutzerdefinierte Trennzeichen und verschiedene Gruppierungsoptionen.",
+ "emptyItemsAndPadding": "Leere Elemente und Polsterung",
+ "groupNumberDescription": "Anzahl der Elemente in einer Gruppe",
+ "groupSeparatorDescription": "Gruppentrennzeichen",
+ "groupSizeAndSeparators": "Gruppengrรถรe und Trennzeichen",
+ "inputItemSeparator": "Eingabeelement-Trennzeichen",
+ "inputTitle": "Eingabeliste",
+ "itemSeparatorDescription": "Elementtrennzeichen",
+ "leftWrapDescription": "Linkes Umbruchsymbol der Gruppe.",
+ "padNonFullGroups": "Nicht volle Gruppen auffรผllen",
+ "padNonFullGroupsDescription": "Fรผllen Sie nicht volle Gruppen mit einem benutzerdefinierten Element (unten eingeben).",
+ "paddingCharDescription": "Verwenden Sie dieses Zeichen oder Element, um nicht volle Gruppen aufzufรผllen.",
+ "resultTitle": "Gruppierte Elemente",
+ "rightWrapDescription": "Rechtes Umbruchsymbol der Gruppe.",
+ "shortDescription": "Gruppieren Sie Listenelemente nach gemeinsamen Eigenschaften",
+ "splitOperators": {
+ "regex": {
+ "description": "Begrenzen Sie die Elemente der Eingabeliste mit einem regulรคren Ausdruck.",
+ "title": "Verwenden Sie einen regulรคren Ausdruck zum Aufteilen"
+ },
+ "symbol": {
+ "description": "Begrenzen Sie die Elemente der Eingabeliste durch ein Zeichen.",
+ "title": "Verwenden Sie ein Symbol zum Teilen"
+ }
+ },
+ "splitSeparatorDescription": "Legen Sie ein Trennsymbol oder einen regulรคren Ausdruck fest.",
+ "title": "Gruppe"
+ },
+ "reverse": {
+ "description": "Diese einfache browserbasierte Anwendung druckt alle Listenelemente rรผckwรคrts. Die Eingabeelemente kรถnnen durch ein beliebiges Symbol getrennt werden. Sie kรถnnen auch das Trennzeichen der umgekehrten Listenelemente รคndern.",
+ "inputTitle": "Eingabeliste",
+ "itemSeparator": "Elementtrennzeichen",
+ "itemSeparatorDescription": "Legen Sie ein Trennsymbol oder einen regulรคren Ausdruck fest.",
+ "outputListOptions": "Ausgabelistenoptionen",
+ "outputSeparatorDescription": "Trennzeichen fรผr Ausgabelistenelemente.",
+ "resultTitle": "Umgekehrte Liste",
+ "shortDescription": "Schnelles Umkehren einer Liste",
+ "splitOperators": {
+ "regex": {
+ "description": "Begrenzen Sie die Elemente der Eingabeliste mit einem regulรคren Ausdruck.",
+ "title": "Verwenden Sie einen regulรคren Ausdruck zum Aufteilen"
+ },
+ "symbol": {
+ "description": "Begrenzen Sie die Elemente der Eingabeliste durch ein Zeichen.",
+ "title": "Verwenden Sie ein Symbol zum Teilen"
+ }
+ },
+ "splitterMode": "Splitter-Modus",
+ "title": "Umkehren",
+ "toolInfo": {
+ "description": "Mit diesem Dienstprogramm kรถnnen Sie die Reihenfolge der Elemente in einer Liste umkehren. Das Dienstprogramm zerlegt die Eingabeliste zunรคchst in einzelne Elemente und durchlรคuft diese dann vom letzten bis zum ersten Element. Dabei wird jedes Element ausgegeben. Die Eingabeliste kann alles enthalten, was sich als Text darstellen lรคsst, z. B. Ziffern, Zahlen, Zeichenfolgen, Wรถrter, Sรคtze usw. Das Trennzeichen fรผr die Eingabeelemente kann auch ein regulรคrer Ausdruck sein. Beispielsweise ermรถglicht der regulรคre Ausdruck /[;,]/ die Verwendung von Elementen, die entweder durch Kommas oder Semikolons getrennt sind. Die Trennzeichen fรผr die Elemente der Eingabe- und Ausgabeliste kรถnnen in den Optionen angepasst werden. Standardmรครig sind sowohl die Eingabe- als auch die Ausgabelisten durch Kommas getrennt. Listabulous!",
+ "title": "Was ist ein Listenumkehrer?"
+ }
+ },
+ "rotate": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Rotieren von Listenelementen. Geben Sie Ihre Liste ein und legen Sie den Rotationsgrad fest, um die Elemente um eine bestimmte Anzahl von Positionen zu verschieben. Ideal fรผr Datenmanipulation, zyklische Verschiebungen oder das Neuordnen von Listen.",
+ "shortDescription": "Listenelemente um angegebene Positionen rotieren",
+ "title": "Drehen"
+ },
+ "shuffle": {
+ "delimiterDescription": "Legen Sie ein Trennsymbol oder einen regulรคren Ausdruck fest.",
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Mischen von Listenelementen. Geben Sie Ihre Liste ein und erhalten Sie sofort eine zufรคllige Version mit Elementen in zufรคlliger Reihenfolge. Perfekt, um Abwechslung zu schaffen, Zufรคlligkeit zu testen oder geordnete Daten zu vermischen.",
+ "inputListSeparator": "Eingabelistentrennzeichen",
+ "inputTitle": "Eingabeliste",
+ "joinSeparatorDescription": "Verwenden Sie dieses Trennzeichen in der zufรคlligen Liste.",
+ "outputLengthDescription": "So viele zufรคllige Elemente ausgeben",
+ "resultTitle": "Gemischte Liste",
+ "shortDescription": "Zufรคllige Reihenfolge der Listenelemente",
+ "shuffledListLength": "Lรคnge der gemischten Liste",
+ "shuffledListSeparator": "Trennzeichen fรผr gemischte Listen",
+ "title": "Shuffle"
+ },
+ "sort": {
+ "caseSensitive": "Groร-/Kleinschreibung beachten",
+ "caseSensitiveDescription": "Groร- und Kleinbuchstaben werden getrennt sortiert. Groรbuchstaben stehen in aufsteigender Reihenfolge vor Kleinbuchstaben. (Funktioniert nur im alphabetischen Sortiermodus.)",
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Sortieren von Listenelementen. Geben Sie Ihre Liste ein und legen Sie Sortierkriterien fest, um die Elemente in auf- oder absteigender Reihenfolge zu sortieren. Ideal fรผr die Datenorganisation, Textverarbeitung oder das Erstellen sortierter Listen.",
+ "inputItemSeparator": "Trennzeichen fรผr Eingabeelemente",
+ "inputTitle": "Eingabeliste",
+ "joinSeparatorDescription": "Verwenden Sie dieses Symbol als Verbindung zwischen Elementen in einer sortierten Liste.",
+ "orderDescription": "Wรคhlen Sie eine Sortierreihenfolge aus.",
+ "orderOptions": {
+ "decreasing": "Absteigende Reihenfolge",
+ "increasing": "Zunehmende Ordnung"
+ },
+ "removeDuplicates": "Duplikate entfernen",
+ "removeDuplicatesDescription": "Lรถschen Sie doppelte Listenelemente.",
+ "resultTitle": "Sortierte Liste",
+ "shortDescription": "Listenelemente in angegebener Reihenfolge sortieren",
+ "sortMethod": "Sortiermethode",
+ "sortMethodDescription": "Wรคhlen Sie eine Sortiermethode aus.",
+ "sortOptions": {
+ "alphabetic": "Alphabetisch sortieren",
+ "length": "Nach Lรคnge sortieren",
+ "numeric": "Numerisch sortieren"
+ },
+ "sortedItemProperties": "Sortierte Artikeleigenschaften",
+ "splitOperators": {
+ "regex": {
+ "description": "Begrenzen Sie die Elemente der Eingabeliste mit einem regulรคren Ausdruck.",
+ "title": "Verwenden Sie einen regulรคren Ausdruck zum Aufteilen"
+ },
+ "symbol": {
+ "description": "Trennen Sie die Elemente der Eingabeliste durch ein Zeichen.",
+ "title": "Verwenden Sie ein Symbol zum Teilen"
+ }
+ },
+ "splitSeparatorDescription": "Legen Sie ein Trennsymbol oder einen regulรคren Ausdruck fest.",
+ "title": "Sortieren"
+ },
+ "truncate": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Kรผrzen von Listen. Geben Sie Ihre Liste ein und legen Sie die maximale Anzahl der zu behaltenden Elemente fest. Ideal fรผr die Datenverarbeitung, Listenverwaltung oder die Begrenzung der Inhaltslรคnge.",
+ "shortDescription": "Liste auf die angegebene Anzahl von Elementen kรผrzen",
+ "title": "Kรผrzen"
+ },
+ "unwrap": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Entpacken von Listenelementen. Geben Sie Ihre verpackte Liste ein und legen Sie Entpackkriterien fest, um organisierte Elemente zu vereinfachen. Ideal fรผr die Datenverarbeitung, Textbearbeitung oder das Extrahieren von Inhalten aus strukturierten Listen.",
+ "shortDescription": "Listenelemente aus strukturiertem Format auspacken",
+ "title": "Auspacken"
+ },
+ "wrap": {
+ "description": "Fรผgen Sie vor und nach jedem Listenelement Text hinzu.",
+ "inputTitle": "Eingabeliste",
+ "joinSeparatorDescription": "Trennzeichen zum Verbinden der umschlossenen Liste",
+ "leftTextDescription": "Vor jedem Element hinzuzufรผgender Text",
+ "removeEmptyItems": "Leere Elemente entfernen",
+ "resultTitle": "Umbrochene Liste",
+ "rightTextDescription": "Nach jedem Element hinzuzufรผgender Text",
+ "shortDescription": "Listenelemente mit angegebenen Kriterien umbrechen",
+ "splitByRegex": "Aufteilen nach regulรคrem Ausdruck",
+ "splitBySymbol": "Nach Symbol teilen",
+ "splitOptions": "Teilungsoptionen",
+ "splitSeparatorDescription": "Trennzeichen zum Teilen der Liste",
+ "title": "Wickeln",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie vor und nach jedem Listenelement Text hinzufรผgen. Sie kรถnnen fรผr die linke und rechte Seite unterschiedlichen Text festlegen und die Verarbeitung der Liste steuern. Es ist nรผtzlich, um Listenelemente mit Anfรผhrungszeichen, Klammern oder anderen Formatierungen zu versehen, Daten fรผr verschiedene Formate vorzubereiten oder strukturierten Text zu erstellen.",
+ "title": "Listenumbruch"
+ },
+ "wrapOptions": "Wrap-Optionen"
+ }
+}
diff --git a/public/locales/de/number.json b/public/locales/de/number.json
new file mode 100644
index 0000000..a65892e
--- /dev/null
+++ b/public/locales/de/number.json
@@ -0,0 +1,89 @@
+{
+ "arithmeticSequence": {
+ "commonDifferenceDescription": "Gemeinsamer Unterschied zwischen Begriffen (d)",
+ "description": "Generieren Sie arithmetische Folgen mit anpassbaren Parametern.",
+ "firstTermDescription": "Erster Term der Folge (aโ)",
+ "numberOfTermsDescription": "Anzahl der zu generierenden Terme (n)",
+ "outputFormat": "Ausgabeformat",
+ "resultTitle": "Generierte Sequenz",
+ "separatorDescription": "Trennzeichen zwischen Begriffen",
+ "sequenceParameters": "Sequenzparameter",
+ "shortDescription": "Arithmetische Folgen generieren",
+ "title": "Arithmetische Folge",
+ "toolInfo": {
+ "description": "Eine arithmetische Folge ist eine Zahlenfolge, bei der die Differenz zwischen den aufeinanderfolgenden Termen konstant ist. Diese konstante Differenz wird als gemeinsame Differenz bezeichnet. Gegeben sind der erste Term (aโ) und die gemeinsame Differenz (d). Jeder Term kann durch Addition der gemeinsamen Differenz zum vorherigen Term ermittelt werden.",
+ "title": "Was ist eine arithmetische Folge?"
+ }
+ },
+ "generate": {
+ "arithmeticSequenceOption": "Arithmetische Sequenzoption",
+ "description": "Generieren Sie eine Zahlenfolge mit anpassbaren Parametern.",
+ "numberOfElementsDescription": "Anzahl der Elemente in der Sequenz.",
+ "resultTitle": "Generierte Zahlen",
+ "separator": "Separator",
+ "separatorDescription": "Trennen Sie Elemente in der arithmetischen Folge durch dieses Zeichen.",
+ "shortDescription": "Generieren Sie Zufallszahlen in angegebenen Bereichen",
+ "startSequenceDescription": "Starten Sie die Sequenz ab dieser Nummer.",
+ "stepDescription": "Erhรถhen Sie jedes Element um diesen Betrag",
+ "title": "Erzeugen",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie eine Zahlenfolge mit anpassbaren Parametern generieren. Sie kรถnnen den Startwert, die Schrittweite und die Anzahl der Elemente festlegen.",
+ "title": "Zahlen generieren"
+ }
+ },
+ "ohmsLaw": {
+ "description": "Berechnet Spannung, Strom und Widerstand",
+ "longDescription": "Dieser Rechner wendet das Ohmsche Gesetz (V = I ร R) an, um drei elektrische Parameter zu bestimmen, wenn die beiden anderen bekannt sind. Das Ohmsche Gesetz ist ein grundlegendes Prinzip der Elektrotechnik und beschreibt die Beziehung zwischen Spannung (V), Stromstรคrke (I) und Widerstand (R). Dieses Tool ist unverzichtbar fรผr Elektronikbastler, Elektroingenieure und Studierende, die mit Schaltkreisen arbeiten, um unbekannte Werte in ihren elektrischen Konstruktionen schnell zu berechnen.",
+ "shortDescription": "Berechnen Sie Spannung, Strom oder Widerstand in Stromkreisen mit dem Ohmschen Gesetz",
+ "title": "Ohmsches Gesetz"
+ },
+ "slackline": {
+ "description": "Berechnet die Spannung einer Slackline",
+ "longDescription": "Dieser Rechner geht von einer Last in der Mitte des Seils aus",
+ "shortDescription": "Berechne die ungefรคhre Spannung einer Slackline oder Wรคscheleine. Verlasse dich aus Sicherheitsgrรผnden nicht darauf.",
+ "title": "Slackline-Spannung"
+ },
+ "sphereArea": {
+ "description": "Flรคche einer Kugel",
+ "longDescription": "Dieser Rechner berechnet die Oberflรคche einer Kugel mit der Formel A = 4ฯrยฒ. Sie kรถnnen entweder den Radius eingeben, um die Oberflรคche zu berechnen, oder die Oberflรคche eingeben, um den gewรผnschten Radius zu berechnen. Dieses Tool ist nรผtzlich fรผr Geometriestudenten, Ingenieure, die mit sphรคrischen Objekten arbeiten, und alle, die Berechnungen mit sphรคrischen Oberflรคchen durchfรผhren mรผssen.",
+ "shortDescription": "Berechnen Sie die Oberflรคche einer Kugel anhand ihres Radius",
+ "title": "Flรคche einer Kugel"
+ },
+ "sphereVolume": {
+ "description": "Volumen einer Kugel",
+ "longDescription": "Dieser Rechner berechnet das Volumen einer Kugel mit der Formel V = (4/3)ฯrยณ. Sie kรถnnen entweder den Radius oder den Durchmesser eingeben, um das Volumen zu ermitteln, oder das Volumen eingeben, um den gewรผnschten Radius zu bestimmen. Das Tool ist nรผtzlich fรผr Studierende, Ingenieure und Fachleute, die mit kugelfรถrmigen Objekten in Bereichen wie Physik, Ingenieurwesen und Fertigung arbeiten.",
+ "shortDescription": "Berechnen Sie das Volumen einer Kugel anhand des Radius oder Durchmessers",
+ "title": "Volumen einer Kugel"
+ },
+ "sum": {
+ "description": "Berechnen Sie die Summe einer Zahlenliste. Geben Sie die Zahlen durch Kommas oder Zeilenumbrรผche getrennt ein, um die Gesamtsumme zu erhalten.",
+ "extractionTypes": {
+ "delimiter": {
+ "description": "Passen Sie hier das Zahlentrennzeichen an. (Standardmรครig ein Zeilenumbruch.)",
+ "title": "Zahlentrennzeichen"
+ },
+ "smart": {
+ "description": "Automatische Erkennung von Zahlen in der Eingabe.",
+ "title": "Smart Sum"
+ }
+ },
+ "inputTitle": "Eingang",
+ "numberExtraction": "Zahlenextraktion",
+ "printRunningSum": "Laufende Summe drucken",
+ "printRunningSumDescription": "Zeigen Sie die Summe an, wรคhrend sie Schritt fรผr Schritt berechnet wird.",
+ "resultTitle": "Gesamt",
+ "runningSum": "Laufende Summe",
+ "shortDescription": "Summe der Zahlen berechnen",
+ "title": "Summe",
+ "toolInfo": {
+ "description": "Dies ist ein browserbasiertes Online-Dienstprogramm zum Berechnen der Summe mehrerer Zahlen. Sie kรถnnen die Zahlen durch Komma, Leerzeichen oder ein beliebiges anderes Zeichen (einschlieรlich Zeilenumbruch) getrennt eingeben. Sie kรถnnen auch einfach einen Textabschnitt mit numerischen Werten einfรผgen, die Sie summieren mรถchten. Das Dienstprogramm extrahiert diese und berechnet deren Summe.",
+ "title": "Was ist ein Zahlensummenrechner?"
+ }
+ },
+ "voltageDropInWire": {
+ "description": "Berechnet die Rundreisespannung und den Leistungsverlust in einem 2-adrigen Kabel",
+ "longDescription": "Dieser Rechner hilft bei der Ermittlung des Spannungsabfalls und der Verlustleistung in einem zweiadrigen Elektrokabel. Er berรผcksichtigt Kabellรคnge, Drahtquerschnitt, Materialwiderstand und Stromfluss. Das Tool berechnet den Hin- und Rรผckspannungsabfall, den Gesamtwiderstand des Kabels und die in Wรคrme umgewandelte Leistung. Dies ist besonders nรผtzlich fรผr Elektroingenieure, Elektriker und Bastler bei der Konstruktion elektrischer Systeme, um sicherzustellen, dass die Spannungspegel an der Last innerhalb akzeptabler Grenzen bleiben.",
+ "shortDescription": "Berechnen Sie Spannungsabfall und Leistungsverlust in elektrischen Kabeln basierend auf Lรคnge, Material und Stromstรคrke",
+ "title": "Hin- und Rรผckspannungsabfall im Kabel"
+ }
+}
diff --git a/public/locales/de/pdf.json b/public/locales/de/pdf.json
new file mode 100644
index 0000000..49a336c
--- /dev/null
+++ b/public/locales/de/pdf.json
@@ -0,0 +1,113 @@
+{
+ "compressPdf": {
+ "compressedFileSize": "Komprimierte Dateigrรถรe",
+ "compressingPdf": "PDF wird komprimiert...",
+ "compressionLevel": "Komprimierungsstufe",
+ "compressionSettings": "Komprimierungseinstellungen",
+ "description": "Reduzieren Sie die PDF-Dateigrรถรe bei gleichbleibender Qualitรคt mit Ghostscript",
+ "errorCompressingPdf": "PDF konnte nicht komprimiert werden: {{error}}",
+ "errorReadingPdf": "PDF-Datei konnte nicht gelesen werden. Bitte stellen Sie sicher, dass es sich um eine gรผltige PDF-Datei handelt.",
+ "fileSize": "Originaldateigrรถรe",
+ "highCompression": "Hohe Kompression",
+ "highCompressionDescription": "Maximale Reduzierung der Dateigrรถรe mit gewissem Qualitรคtsverlust",
+ "inputTitle": "Eingabe-PDF",
+ "lowCompression": "Geringe Kompression",
+ "lowCompressionDescription": "Reduzieren Sie die Dateigrรถรe leicht mit minimalem Qualitรคtsverlust",
+ "mediumCompression": "Mittlere Kompression",
+ "mediumCompressionDescription": "Gleichgewicht zwischen Dateigrรถรe und Qualitรคt",
+ "pages": "Seitenanzahl",
+ "resultTitle": "Komprimiertes PDF",
+ "shortDescription": "Komprimieren Sie PDF-Dateien sicher in Ihrem Browser",
+ "title": "PDF komprimieren"
+ },
+ "editor": {
+ "description": "Erweiterter PDF-Editor mit Funktionen zum Kommentieren, Ausfรผllen von Formularen, Hervorheben und Exportieren. Bearbeiten Sie Ihre PDFs direkt im Browser mit professionellen Tools wie Texteinfรผgung, Zeichnen, Hervorheben, Unterschreiben und Ausfรผllen von Formularen.",
+ "shortDescription": "Bearbeiten Sie PDFs mit erweiterten Werkzeugen zum Kommentieren, Signieren und Bearbeiten",
+ "title": "PDF Editor"
+ },
+ "merge": {
+ "inputTitle": "Eingabe-PDF",
+ "loadingText": "Seiten extrahieren",
+ "resultTitle": "Zusammengefรผhrtes PDF ausgeben",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie mehrere PDF-Dateien zu einem einzigen Dokument zusammenfรผhren. Laden Sie dazu einfach die zusammenzufรผhrenden PDF-Dateien hoch. Das Tool fรผgt dann alle Seiten der Eingabedateien zu einem einzigen PDF-Dokument zusammen.",
+ "title": "Wie verwende ich das Tool zum Zusammenfรผhren von PDFs?"
+ }
+ },
+ "mergePdf": {
+ "description": "Kombinieren Sie mehrere PDF-Dateien zu einem einzigen Dokument.",
+ "inputTitle": "Eingabe-PDFs",
+ "mergingPdfs": "PDFs zusammenfรผhren",
+ "pdfOptions": "PDF-Optionen",
+ "resultTitle": "Zusammengefรผhrte PDF",
+ "shortDescription": "Mehrere PDF-Dateien zu einem einzigen Dokument zusammenfรผhren",
+ "sortByFileName": "Nach Dateinamen sortieren",
+ "sortByFileNameDescription": "PDFs alphabetisch nach Dateinamen sortieren",
+ "sortByUploadOrder": "Nach Upload-Reihenfolge sortieren",
+ "sortByUploadOrderDescription": "Behalten Sie PDFs in der Reihenfolge bei, in der sie hochgeladen wurden",
+ "title": "PDF zusammenfรผhren",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie mehrere PDF-Dateien zu einem einzigen Dokument zusammenfรผhren. Sie kรถnnen die Sortierung der PDFs wรคhlen, und das Tool fรผgt sie in der angegebenen Reihenfolge zusammen.",
+ "title": "PDF-Dateien zusammenfรผhren"
+ }
+ },
+ "pdfToEpub": {
+ "description": "Wandeln Sie PDF-Dokumente in EPUB-Dateien um, um eine bessere E-Reader-Kompatibilitรคt zu erzielen.โ, Symbol: โMaterialsymbole:Kontakte importierenโ, Komponente: lazy(() => import(โ./indexโ)), Schlรผsselwรถrter: [โpdfโ, โepubโ, โkonvertierenโ, โebookโ], Pfad: โpdf-zu-epubโ, i18n: {Name: โpdf:pdfToEpub.titleโ, Beschreibung: โpdf:pdfToEpub.descriptionโ",
+ "shortDescription": "Konvertieren Sie PDF-Dateien in das EPUB-Format",
+ "title": "PDF zu EPUB"
+ },
+ "pdfToPng": {
+ "description": "Wandeln Sie PDF-Dokumente in PNG-Panels um.",
+ "longDescription": "Laden Sie eine PDF-Datei hoch und konvertieren Sie jede Seite direkt in Ihrem Browser in ein hochwertiges PNG-Bild. Dieses Tool eignet sich ideal zum Extrahieren visueller Inhalte oder zum Teilen einzelner Seiten. Es werden keine Daten hochgeladen โ alles lรคuft lokal.",
+ "shortDescription": "Konvertieren Sie PDF in PNG-Bilder",
+ "title": "PDF zu PNG"
+ },
+ "protectPdf": {
+ "description": "Fรผgen Sie Ihren PDF-Dateien sicher in Ihrem Browser einen Passwortschutz hinzu",
+ "shortDescription": "PDF-Dateien sicher mit einem Passwort schรผtzen",
+ "title": "PDF schรผtzen"
+ },
+ "rotatePdf": {
+ "allPagesWillBeRotated": "Alle {{count}} Seiten werden gedreht",
+ "angleOptions": {
+ "clockwise90": "90ยฐ im Uhrzeigersinn",
+ "counterClockwise270": "270ยฐ (90ยฐ gegen den Uhrzeigersinn)",
+ "upsideDown180": "180ยฐ (auf den Kopf gestellt)"
+ },
+ "applyToAllPages": "Auf alle Seiten anwenden",
+ "description": "Drehen Sie Seiten in einem PDF-Dokument.",
+ "inputTitle": "Eingabe-PDF",
+ "longDescription": "รndern Sie die Ausrichtung von PDF-Seiten, indem Sie sie um 90, 180 oder 270 Grad drehen. Nรผtzlich zum Korrigieren falsch gescannter Dokumente oder zum Vorbereiten von PDFs fรผr den Druck.",
+ "pageRangesDescription": "Geben Sie Seitenzahlen oder Bereiche durch Kommas getrennt ein (z. B. 1,3,5-7).",
+ "pageRangesPlaceholder": "z.B. 1,5-8",
+ "pagesWillBeRotated": "{{count}} Seite{{count !== 1 ? 's' : ''}} wird gedreht",
+ "pdfPageCount": "PDF hat {{count}} Seite{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "Gedrehtes PDF",
+ "rotatingPages": "Seiten drehen",
+ "rotationAngle": "Drehwinkel",
+ "rotationSettings": "Rotationseinstellungen",
+ "shortDescription": "Seiten in einem PDF-Dokument drehen",
+ "title": "PDF drehen",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie Seiten in einem PDF-Dokument drehen. Sie kรถnnen alle Seiten drehen oder einzelne Seiten auswรคhlen. Wรคhlen Sie einen Drehwinkel: 90ยฐ im Uhrzeigersinn, 180ยฐ (auf dem Kopf) oder 270ยฐ (90ยฐ gegen den Uhrzeigersinn). Um bestimmte Seiten zu drehen, deaktivieren Sie โAuf alle Seiten anwendenโ und geben Sie Seitenzahlen oder -bereiche durch Kommas getrennt ein (z. B. 1, 3, 5-7).",
+ "title": "So verwenden Sie das Tool zum Drehen von PDFs"
+ }
+ },
+ "splitPdf": {
+ "description": "Extrahieren Sie bestimmte Seiten aus einem PDF-Dokument.",
+ "extractingPages": "Seiten extrahieren",
+ "inputTitle": "Eingabe-PDF",
+ "pageExtractionPreview": "{{count}} Seite{{count !== 1 ? 's' : ''}} wird extrahiert",
+ "pageRangesDescription": "Geben Sie Seitenzahlen oder Bereiche durch Kommas getrennt ein (z. B. 1,3,5-7).",
+ "pageRangesPlaceholder": "z.B. 1,5-8",
+ "pageSelection": "Seitenauswahl",
+ "pdfPageCount": "PDF hat {{count}} Seite{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "Extrahiertes PDF",
+ "shortDescription": "Extrahieren Sie bestimmte Seiten aus einer PDF-Datei",
+ "title": "PDF teilen",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie bestimmte Seiten aus einem PDF-Dokument extrahieren. Sie kรถnnen einzelne Seiten oder Seitenbereiche zum Extrahieren angeben.",
+ "title": "PDF teilen"
+ }
+ }
+}
diff --git a/public/locales/de/string.json b/public/locales/de/string.json
new file mode 100644
index 0000000..0d7e847
--- /dev/null
+++ b/public/locales/de/string.json
@@ -0,0 +1,261 @@
+{
+ "base64": {
+ "decode": "Base64-Dekodierung",
+ "description": "Kodieren oder dekodieren Sie Text mit der Base64-Kodierung.",
+ "encode": "Base64-Kodierung",
+ "inputTitle": "Eingabedaten",
+ "optionsTitle": "Base64-Optionen",
+ "resultTitle": "Ergebnis",
+ "shortDescription": "Kodieren oder dekodieren Sie Daten mit Base64.",
+ "title": "Base64-Encoder/Decoder",
+ "toolInfo": {
+ "description": "Base64 ist ein Kodierungsschema, das Daten im ASCII-String-Format darstellt, indem es sie in eine Radix-64-Darstellung รผbersetzt. Obwohl es zur Kodierung von Strings verwendet werden kann, wird es รผblicherweise zur Kodierung binรคrer Daten fรผr die รbertragung รผber Medien verwendet, die fรผr die Verarbeitung von Textdaten ausgelegt sind.",
+ "title": "Was ist Base64?"
+ }
+ },
+ "censor": {
+ "description": "Dienstprogramm zum Zensieren von Wรถrtern in Texten. Laden Sie Ihren Text in das Eingabeformular links, geben Sie alle Schimpfwรถrter in den Optionen an, und Sie erhalten sofort zensierten Text im Ausgabebereich., longDescription: 'Mit diesem Online-Tool kรถnnen Sie bestimmte Wรถrter in jedem Text zensieren. Sie kรถnnen eine Liste unerwรผnschter Wรถrter (z. B. Schimpfwรถrter oder Geheimwรถrter) angeben, die das Programm durch alternative Wรถrter ersetzt und einen lesbaren Text erstellt. Die Wรถrter kรถnnen in einem mehrzeiligen Textfeld in den Optionen angegeben werden, indem Sie pro Zeile ein Wort eingeben.', keywords: ['text', 'zensieren', 'wรถrter', 'zeichen'], component: lazy(() => import('./index')), i18n: { name: 'string:censor.title', description: 'string:censor.description",
+ "shortDescription": "Maskieren Sie Schimpfwรถrter schnell oder ersetzen Sie sie durch alternative Wรถrter.",
+ "title": "Textzensur"
+ },
+ "createPalindrome": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Erstellen von Palindromen aus beliebigem Text. Geben Sie Text ein und verwandeln Sie ihn sofort in ein Palindrom, das vorwรคrts und rรผckwรคrts gleich gelesen wird. Ideal fรผr Wortspiele, das Erstellen symmetrischer Textmuster oder das Erkunden sprachlicher Kuriositรคten.",
+ "shortDescription": "Erstellen Sie Text, der vorwรคrts und rรผckwรคrts gleich gelesen wird",
+ "title": "Palindrom erstellen"
+ },
+ "extractSubstring": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Extrahieren von Teilzeichenfolgen aus Text. Geben Sie Ihren Text ein und legen Sie Start- und Endposition fest, um den gewรผnschten Teil zu extrahieren. Ideal fรผr die Datenverarbeitung, Textanalyse oder das Extrahieren spezifischer Inhalte aus grรถรeren Textblรถcken.",
+ "shortDescription": "Extrahieren Sie einen Textabschnitt zwischen angegebenen Positionen",
+ "title": "Teilzeichenfolge extrahieren"
+ },
+ "join": {
+ "blankLinesAndTrailingSpaces": "Leere Zeilen und Leerzeichen am Ende",
+ "deleteBlankDescription": "Lรถschen Sie Zeilen, die keine Textsymbole enthalten.",
+ "deleteBlankTitle": "Leere Zeilen lรถschen",
+ "deleteTrailingDescription": "Entfernen Sie Leerzeichen und Tabulatoren am Zeilenende.",
+ "deleteTrailingTitle": "Lรถschen Sie abschlieรende Leerzeichen",
+ "description": "Fรผgen Sie Textteile mit anpassbaren Trennzeichen zusammen.",
+ "inputTitle": "Textstรผcke",
+ "joinCharacterDescription": "Symbol, das unterbrochene Textteile verbindet. (Standardmรครig Leerzeichen.)",
+ "joinCharacterPlaceholder": "Charakter beitreten",
+ "resultTitle": "Verbundener Text",
+ "shortDescription": "Verbinden Sie Textelemente mit einem festgelegten Trennzeichen",
+ "textMergedOptions": "Optionen fรผr zusammengefรผhrten Text",
+ "title": "Text verbinden",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie Textteile zusammenfรผgen. Es nimmt eine Liste von Textwerten, getrennt durch Zeilenumbrรผche, und fรผgt sie zusammen. Sie kรถnnen das Zeichen festlegen, das zwischen den Teilen des zusammengefรผgten Textes platziert wird. Auรerdem kรถnnen Sie alle Leerzeilen ignorieren und Leerzeichen und Tabulatoren am Zeilenende entfernen. Textabulous!",
+ "title": "Was ist ein Textverbinder?"
+ }
+ },
+ "palindrome": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zur รberprรผfung von Palindromen. รberprรผfen Sie sofort, ob sich Ihr Text vorwรคrts und rรผckwรคrts gleich liest. Ideal fรผr Wortrรคtsel, linguistische Analysen oder die Validierung symmetrischer Textmuster. Unterstรผtzt verschiedene Trennzeichen und die Erkennung mehrteiliger Palindrome.",
+ "shortDescription": "รberprรผfen Sie, ob der Text vorwรคrts und rรผckwรคrts gleich gelesen wird",
+ "title": "Palindrom"
+ },
+ "passwordGenerator": {
+ "avoidAmbiguous": "Vermeiden Sie mehrdeutige Zeichen (i, I, l, 0, O).",
+ "description": "Generieren Sie sichere, zufรคllige Passwรถrter mit anpassbarer Lรคnge und Zeichenart. Wรคhlen Sie zwischen Kleinbuchstaben, Groรbuchstaben, Zahlen und Sonderzeichen. Optional kรถnnen Sie mehrdeutige Zeichen vermeiden, um die Lesbarkeit zu verbessern.",
+ "includeLowercase": "Kleinbuchstaben einschlieรen (a-z)",
+ "includeNumbers": "Zahlen einschlieรen (0-9)",
+ "includeSymbols": "Sonderzeichen einschlieรen",
+ "includeUppercase": "Groรbuchstaben einschlieรen (A-Z)",
+ "lengthDesc": "Lรคnge des Passwortes",
+ "lengthPlaceholder": "z.B. 12",
+ "optionsTitle": "Passwortoptionen",
+ "resultTitle": "Generiertes Passwort",
+ "shortDescription": "Generieren Sie sichere, zufรคllige Passwรถrter mit benutzerdefinierten Optionen",
+ "title": "Passwortgenerator",
+ "toolInfo": {
+ "description": "Dieses Tool generiert sichere, zufรคllige Passwรถrter basierend auf Ihren ausgewรคhlten Kriterien. Sie kรถnnen die Lรคnge anpassen, verschiedene Zeichentypen ein- oder ausschlieรen und mehrdeutige Zeichen fรผr eine bessere Lesbarkeit vermeiden. Ideal fรผr die Erstellung sicherer Passwรถrter fรผr Konten, Anwendungen oder andere Sicherheitsanforderungen.",
+ "title": "รber den Passwortgenerator"
+ }
+ },
+ "quote": {
+ "allowDoubleQuotation": "Doppelte Anfรผhrungszeichen zulassen",
+ "description": "Fรผgen Sie mit anpassbaren Optionen Anfรผhrungszeichen um den Text hinzu.",
+ "inputTitle": "Eingabetext",
+ "leftQuoteDescription": "Anfรผhrungszeichen links",
+ "processAsMultiLine": "Als mehrzeiligen Text verarbeiten",
+ "quoteEmptyLines": "Leere Zeilen in Zitieren setzen",
+ "quoteOptions": "Angebotsoptionen",
+ "resultTitle": "Zitierter Text",
+ "rightQuoteDescription": "Anfรผhrungszeichen rechts",
+ "shortDescription": "Fรผgen Sie Anfรผhrungszeichen um Text mit verschiedenen Stilen hinzu",
+ "title": "Textzitierer",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie Text in Anfรผhrungszeichen setzen. Sie kรถnnen verschiedene Anfรผhrungszeichen wรคhlen, mehrzeiligen Text bearbeiten und die Verarbeitung leerer Zeilen steuern. Es ist nรผtzlich, um Text fรผr die Programmierung vorzubereiten, Daten zu formatieren oder stilisierten Text zu erstellen.",
+ "title": "Textzitierer"
+ }
+ },
+ "randomizeCase": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zur zufรคlligen Groร- und Kleinschreibung. Geben Sie Ihren Text ein und transformieren Sie ihn sofort mit zufรคlligen Groร- und Kleinbuchstaben. Perfekt fรผr einzigartige Texteffekte, zum Testen der Groร- und Kleinschreibung oder zum Generieren abwechslungsreicher Textmuster.",
+ "shortDescription": "Groร- und Kleinschreibung von Buchstaben im Text zufรคllig anordnen",
+ "title": "Groร-/Kleinschreibung randomisieren"
+ },
+ "removeDuplicateLines": {
+ "description": "Laden Sie Ihren Text in das Eingabeformular links und Sie erhalten sofort Text ohne doppelte Zeilen im Ausgabebereich. Leistungsstark, kostenlos und schnell. Textzeilen laden โ einzigartige Textzeilen erhalten",
+ "shortDescription": "Lรถschen Sie schnell alle wiederholten Zeilen aus dem Text",
+ "title": "Entfernen Sie doppelte Zeilen"
+ },
+ "repeat": {
+ "delimiterDescription": "Trennzeichen fรผr Ausgabekopien.",
+ "delimiterPlaceholder": "Trennzeichen",
+ "description": "Wiederholen Sie Text mehrmals mit anpassbaren Trennzeichen.",
+ "inputTitle": "Eingabetext",
+ "numberPlaceholder": "Nummer",
+ "repeatAmountDescription": "Anzahl der Wiederholungen.",
+ "repetitionsDelimiter": "Wiederholungsbegrenzer",
+ "resultTitle": "Wiederholter Text",
+ "shortDescription": "Text mehrmals wiederholen",
+ "textRepetitions": "Textwiederholungen",
+ "title": "Text wiederholen",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie einen bestimmten Text mit einem optionalen Trennzeichen mehrmals wiederholen.",
+ "title": "Text wiederholen"
+ }
+ },
+ "reverse": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Umkehren von Text. Geben Sie beliebigen Text ein und lassen Sie ihn sofort Zeichen fรผr Zeichen umkehren. Ideal zum Erstellen von Spiegeltext, Analysieren von Palindromen oder zum Experimentieren mit Textmustern. Leerzeichen und Sonderzeichen bleiben beim Umkehren erhalten.",
+ "inputTitle": "Umzukehrender Text",
+ "processMultiLine": "Mehrzeiligen Text verarbeiten",
+ "processMultiLineDescription": "Jede Zeile wird unabhรคngig umgekehrt",
+ "resultTitle": "Umgekehrter Text",
+ "reversalOptions": "Umkehroptionen",
+ "shortDescription": "Kehren Sie jeden Text Zeichen fรผr Zeichen um",
+ "skipEmptyLines": "Leere Zeilen รผberspringen",
+ "skipEmptyLinesDescription": "Leere Zeilen werden aus der Ausgabe entfernt",
+ "title": "Umkehren",
+ "trimWhitespace": "Leerzeichen entfernen",
+ "trimWhitespaceDescription": "Entfernen Sie fรผhrende und nachfolgende Leerzeichen aus jeder Zeile"
+ },
+ "rot13": {
+ "description": "Kodieren oder dekodieren Sie Text mit der ROT13-Chiffre.",
+ "inputTitle": "Eingabetext",
+ "resultTitle": "ROT13-Ergebnis",
+ "shortDescription": "Kodieren oder dekodieren Sie Text mit der ROT13-Chiffre.",
+ "title": "ROT13 Encoder/Decoder",
+ "toolInfo": {
+ "description": "ROT13 (Rotate by 13 places) ist eine einfache Buchstabenersetzungs-Chiffre, die einen Buchstaben durch den 13. Buchstaben im Alphabet ersetzt. ROT13 ist ein Sonderfall der Caesar-Chiffre, die im antiken Rom entwickelt wurde. Da das englische Alphabet 26 Buchstaben umfasst, ist ROT13 seine eigene Umkehrung. Das heiรt, um ROT13 rรผckgรคngig zu machen, wird derselbe Algorithmus angewendet, sodass dieselbe Aktion zum Verschlรผsseln und Entschlรผsseln verwendet werden kann.",
+ "title": "Was ist ROT13?"
+ }
+ },
+ "rotate": {
+ "description": "Drehen Sie Zeichen im Text um angegebene Positionen.",
+ "inputTitle": "Eingabetext",
+ "processAsMultiLine": "Als mehrzeiligen Text verarbeiten (jede Zeile einzeln drehen)",
+ "resultTitle": "Gedrehter Text",
+ "rotateLeft": "Nach links drehen",
+ "rotateRight": "Nach rechts drehen",
+ "rotationOptions": "Rotationsoptionen",
+ "shortDescription": "Verschieben Sie Zeichen im Text um die Position.",
+ "stepDescription": "Anzahl der zu drehenden Positionen",
+ "title": "Text drehen",
+ "toolInfo": {
+ "description": "Mit diesem Werkzeug kรถnnen Sie Zeichen in einer Zeichenfolge um eine bestimmte Anzahl von Positionen drehen. Sie kรถnnen nach links oder rechts drehen und mehrzeiligen Text verarbeiten, indem Sie jede Zeile einzeln drehen. Die Zeichenfolgenrotation ist nรผtzlich fรผr einfache Texttransformationen, die Erstellung von Mustern oder die Implementierung grundlegender Verschlรผsselungstechniken.",
+ "title": "Saitenrotation"
+ }
+ },
+ "split": {
+ "charAfterChunkDescription": "Zeichen nach jedem Block",
+ "charBeforeChunkDescription": "Zeichen vor jedem Block",
+ "chunksDescription": "Anzahl der gleich langen Chunks in der Ausgabe.",
+ "chunksTitle": "Verwenden Sie eine Anzahl von Chunks",
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Teilen von Text. Geben Sie Ihren Text ein und wรคhlen Sie ein Trennzeichen, um ihn in mehrere Teile aufzuteilen. Ideal fรผr die Datenverarbeitung, Textbearbeitung oder das Extrahieren bestimmter Inhalte aus grรถรeren Textblรถcken.",
+ "lengthDescription": "Anzahl der Symbole, die in jeden Ausgabeblock eingefรผgt werden.",
+ "lengthTitle": "Lรคnge zum Teilen verwenden",
+ "outputSeparatorDescription": "Zeichen, das zwischen die geteilten Blรถcke eingefรผgt wird.\n(Standardmรครig ist es das Zeilenumbruchzeichen โ\\nโ.)",
+ "outputSeparatorOptions": "Ausgabetrennzeichenoptionen",
+ "regexDescription": "Regulรคrer Ausdruck, der zum Aufteilen von Text verwendet wird.\n(Standardmรครig mehrere Leerzeichen.)",
+ "regexTitle": "Verwenden Sie einen regulรคren Ausdruck zum Aufteilen",
+ "resultTitle": "Textstรผcke",
+ "shortDescription": "Text mithilfe eines Trennzeichens in mehrere Teile aufteilen",
+ "splitSeparatorOptions": "Optionen fรผr geteilte Trennzeichen",
+ "symbolDescription": "Zeichen, das zum Aufteilen des Textes verwendet wird.\n(Standardmรครig Leerzeichen.)",
+ "symbolTitle": "Verwenden Sie ein Symbol zum Teilen",
+ "title": "Teilt"
+ },
+ "statistic": {
+ "characterFrequencyAnalysis": "Zeichenhรคufigkeitsanalyse",
+ "characterFrequencyAnalysisDescription": "Zรคhlen Sie, wie oft jedes Zeichen im Text vorkommt",
+ "delimitersOptions": "Trennzeichenoptionen",
+ "description": "Analysieren Sie Texte und erstellen Sie umfassende Statistiken.",
+ "includeEmptyLines": "Leere Zeilen einschlieรen",
+ "includeEmptyLinesDescription": "Berรผcksichtigen Sie beim Zรคhlen von Zeilen auch Leerzeilen",
+ "inputTitle": "Eingabetext",
+ "resultTitle": "Textstatistik",
+ "sentenceDelimitersDescription": "Geben Sie benutzerdefinierte Zeichen ein, die zur Abgrenzung von Sรคtzen in Ihrer Sprache verwendet werden (durch Komma getrennt), oder lassen Sie das Feld als Standard leer.",
+ "sentenceDelimitersPlaceholder": "z.ย B. ., !, ?, ...",
+ "shortDescription": "Erhalten Sie Statistiken zu Ihrem Text",
+ "statisticsOptions": "Statistikoptionen",
+ "title": "Textstatistik",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie Text analysieren und umfassende Statistiken erstellen, darunter Zeichenanzahl, Wortanzahl, Zeilenanzahl und Hรคufigkeitsanalyse von Zeichen und Wรถrtern.",
+ "title": "Was ist ein {{title}}?"
+ },
+ "wordDelimitersDescription": "Geben Sie einen benutzerdefinierten regulรคren Ausdruck ein, um Wรถrter zu zรคhlen, oder lassen Sie das Feld fรผr die Standardeinstellung leer.",
+ "wordDelimitersPlaceholder": "zB. \\s.,;:!?\"ยซยป()โฆ",
+ "wordFrequencyAnalysis": "Worthรคufigkeitsanalyse",
+ "wordFrequencyAnalysisDescription": "Zรคhlen Sie, wie oft jedes Wort im Text vorkommt"
+ },
+ "textReplacer": {
+ "description": "Ersetzen Sie Textmuster durch neue Inhalte.",
+ "findPatternInText": "Dieses Muster im Text finden",
+ "findPatternUsingRegexp": "Suchen eines Musters mithilfe eines regulรคren Ausdrucks",
+ "inputTitle": "Zu ersetzender Text",
+ "newTextPlaceholder": "Neuer Text",
+ "regexpDescription": "Geben Sie den regulรคren Ausdruck ein, den Sie ersetzen mรถchten.",
+ "replacePatternDescription": "Geben Sie das Muster ein, das zum Ersetzen verwendet werden soll.",
+ "replaceText": "Text ersetzen",
+ "resultTitle": "Text mit Ersetzungen",
+ "searchPatternDescription": "Geben Sie das Textmuster ein, das Sie ersetzen mรถchten.",
+ "searchText": "Suchtext",
+ "shortDescription": "Ersetzen Sie schnell Text in Ihrem Inhalt",
+ "title": "Textersetzung",
+ "toolInfo": {
+ "description": "Ersetzen Sie mit diesem einfachen, browserbasierten Tool ganz einfach Text in Ihren Inhalten. Geben Sie einfach Ihren Text ein, legen Sie den zu ersetzenden Text und den Ersetzungswert fest und erhalten Sie sofort die aktualisierte Version.",
+ "title": "Textersetzung"
+ }
+ },
+ "toMorse": {
+ "dashSymbolDescription": "Symbol, das dem Bindestrich im Morsecode entspricht.",
+ "description": "Konvertieren Sie Text in Morsecode.",
+ "dotSymbolDescription": "Symbol, das dem Punkt im Morsecode entspricht.",
+ "longSignal": "Langes Signal",
+ "resultTitle": "Morsezeichen",
+ "shortDescription": "Text schnell in Morse kodieren",
+ "shortSignal": "Kurzes Signal",
+ "title": "Zeichenfolge zu Morse"
+ },
+ "truncate": {
+ "addTruncationIndicator": "Trunkierungsindikator hinzufรผgen",
+ "charactersPlaceholder": "Charaktere",
+ "description": "Kรผrzen Sie den Text auf eine bestimmte Lรคnge.",
+ "indicatorDescription": "Zeichen, die am Ende (oder Anfang) des Textes hinzugefรผgt werden sollen. Hinweis: Sie werden zur Lรคnge gezรคhlt.",
+ "inputTitle": "Eingabetext",
+ "leftSideDescription": "Entfernen Sie Zeichen vom Anfang des Textes.",
+ "leftSideTruncation": "Linksseitige Kรผrzung",
+ "lengthAndLines": "Lรคnge und Linien",
+ "lineByLineDescription": "Kรผrzen Sie jede Zeile einzeln.",
+ "lineByLineTruncating": "Zeilenweises Abschneiden",
+ "maxLengthDescription": "Anzahl der Zeichen, die im Text verbleiben sollen.",
+ "numberPlaceholder": "Nummer",
+ "resultTitle": "Abgeschnittener Text",
+ "rightSideDescription": "Entfernen Sie Zeichen vom Ende des Textes.",
+ "rightSideTruncation": "Rechtsseitige Kรผrzung",
+ "shortDescription": "Text auf eine bestimmte Lรคnge kรผrzen",
+ "suffixAndAffix": "Suffix und Affix",
+ "title": "Text abschneiden",
+ "toolInfo": {
+ "description": "Laden Sie Ihren Text in das Eingabeformular links und Sie erhalten rechts automatisch gekรผrzten Text.",
+ "title": "Text kรผrzen"
+ },
+ "truncationSide": "Abschneideseite"
+ },
+ "uppercase": {
+ "description": "Wandeln Sie Text in Groรbuchstaben um.",
+ "inputTitle": "Eingabetext",
+ "resultTitle": "Groรbuchstaben",
+ "shortDescription": "Text in Groรbuchstaben umwandeln",
+ "title": "In Groรbuchstaben umwandeln"
+ }
+}
diff --git a/public/locales/de/time.json b/public/locales/de/time.json
new file mode 100644
index 0000000..59d0858
--- /dev/null
+++ b/public/locales/de/time.json
@@ -0,0 +1,100 @@
+{
+ "checkLeapYears": {
+ "description": "Prรผfen Sie, ob ein Jahr ein Schaltjahr ist, und erhalten Sie Informationen zum Schaltjahr.",
+ "inputTitle": "Jahr eingeben",
+ "resultTitle": "Schaltjahrergebnis",
+ "shortDescription": "Prรผfen, ob ein Jahr ein Schaltjahr ist",
+ "title": "Schaltjahre prรผfen",
+ "toolInfo": {
+ "description": "Ein Schaltjahr ist ein Jahr mit einem zusรคtzlichen Tag (29. Februar), um das Kalenderjahr mit dem astronomischen Jahr zu synchronisieren. Schaltjahre gibt es alle vier Jahre, mit Ausnahme der Jahre, die durch 100, aber nicht durch 400 teilbar sind.",
+ "title": "Was ist ein Schaltjahr?"
+ }
+ },
+ "convertDaysToHours": {
+ "addHoursName": "Stundennamen hinzufรผgen",
+ "addHoursNameDescription": "Hรคngen Sie die Zeichenfolge โStundenโ an die Ausgabewerte an",
+ "description": "Wandeln Sie Tage mit anpassbaren Optionen in Stunden um.",
+ "hoursName": "Stunden Name",
+ "shortDescription": "Tage in Stunden umrechnen",
+ "title": "Tage in Stunden umrechnen",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie Tage in Stunden umrechnen. Sie kรถnnen Tage als Zahlen oder mit Einheiten eingeben, und das Tool rechnet sie in Stunden um. Sie kรถnnen den Ausgabewerten auch das Suffix โStundenโ anhรคngen.",
+ "title": "Tage in Stunden umrechnen"
+ }
+ },
+ "convertHoursToDays": {
+ "addDaysName": "Tagesnamen hinzufรผgen",
+ "addDaysNameDescription": "Hรคngen Sie die Zeichenfolge โTageโ an die Ausgabewerte an",
+ "daysName": "Tage Name",
+ "description": "Wandeln Sie Stunden mit anpassbaren Optionen in Tage um.",
+ "shortDescription": "Stunden in Tage umrechnen",
+ "title": "Stunden in Tage umrechnen",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie Stunden in Tage umrechnen. Sie kรถnnen Stunden als Zahlen oder mit Einheiten eingeben, und das Tool rechnet sie in Tage um. Sie kรถnnen den Ausgabewerten auch das Suffix โTageโ anhรคngen.",
+ "title": "Stunden in Tage umrechnen"
+ }
+ },
+ "convertSecondsToTime": {
+ "addPadding": "Polsterung hinzufรผgen",
+ "addPaddingDescription": "Fรผgen Sie Stunden, Minuten und Sekunden mit Nullen aufgefรผllt hinzu.",
+ "description": "Konvertiert Sekunden in ein lesbares Zeitformat (Stunden:Minuten:Sekunden). Geben Sie die Anzahl der Sekunden ein, um die formatierte Zeit zu erhalten.",
+ "shortDescription": "Sekunden in das Zeitformat konvertieren",
+ "timePadding": "Zeitauffรผllung",
+ "title": "Sekunden in Zeit umrechnen",
+ "toolInfo": {
+ "title": "Was ist ein {{title}}?"
+ }
+ },
+ "convertTimeToSeconds": {
+ "description": "Konvertieren Sie die formatierte Zeit (HH:MM:SS) in Sekunden.",
+ "inputTitle": "Eingabezeit",
+ "resultTitle": "Sekunden",
+ "shortDescription": "Konvertieren Sie das Zeitformat in Sekunden",
+ "title": "Zeit in Sekunden umrechnen",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie formatierte Zeitzeichenfolgen (HH:MM:SS) in Sekunden umwandeln. Es ist nรผtzlich fรผr die Berechnung von Dauern und Zeitintervallen.",
+ "title": "Zeit in Sekunden umrechnen"
+ }
+ },
+ "crontabGuru": {
+ "description": "Generieren und verstehen Sie Cron-Ausdrรผcke. Erstellen Sie Cron-Zeitplรคne fรผr automatisierte Aufgaben und Systemjobs.",
+ "shortDescription": "Cron-Ausdrรผcke generieren und verstehen",
+ "title": "Crontab Guru"
+ },
+ "timeBetweenDates": {
+ "description": "Berechnen Sie die Zeitdifferenz zwischen zwei Daten. Ermitteln Sie die genaue Dauer in Tagen, Stunden, Minuten und Sekunden.",
+ "endDate": "Enddatum",
+ "endDateTime": "Enddatum und -zeit",
+ "endTime": "Endzeit",
+ "endTimezone": "Endzeitzone",
+ "shortDescription": "Berechnen Sie die Zeit zwischen zwei Daten",
+ "startDate": "Startdatum",
+ "startDateTime": "Startdatum und -zeit",
+ "startTime": "Startzeit",
+ "startTimezone": "Startzeitzone",
+ "title": "Zeit zwischen den Terminen",
+ "toolInfo": {
+ "description": "Berechnen Sie die genaue Zeitdifferenz zwischen zwei Datums- und Uhrzeitangaben, mit Unterstรผtzung fรผr verschiedene Zeitzonen. Dieses Tool bietet eine detaillierte Aufschlรผsselung der Zeitdifferenz in verschiedenen Einheiten (Jahre, Monate, Tage, Stunden, Minuten und Sekunden).",
+ "title": "Zeit zwischen Daten-Rechner"
+ }
+ },
+ "truncateClockTime": {
+ "description": "Kรผrzen Sie die Uhrzeit, um Sekunden oder Minuten zu entfernen. Runden Sie die Zeit auf die nรคchste Stunde, Minute oder ein benutzerdefiniertes Intervall.",
+ "printDroppedComponents": "Drucken gelรถschter Komponenten",
+ "shortDescription": "Kรผrzen Sie die Uhrzeit auf die angegebene Genauigkeit",
+ "timePadding": "Zeitauffรผllung",
+ "title": "Uhrzeit kรผrzen",
+ "toolInfo": {
+ "title": "Was ist ein {{title}}?"
+ },
+ "truncateMinutesAndSeconds": "Minuten und Sekunden kรผrzen",
+ "truncateMinutesAndSecondsDescription": "Lassen Sie beides weg โ die Minuten- und Sekundenkomponenten jeder Uhrzeit.",
+ "truncateOnlySeconds": "Nur Sekunden abschneiden",
+ "truncateOnlySecondsDescription": "Entfernen Sie die Sekundenkomponente aus jeder Uhrzeit.",
+ "truncationSide": "Abschneideseite",
+ "useZeroPadding": "Null-Padding verwenden",
+ "zeroPaddingDescription": "Sorgen Sie dafรผr, dass alle Zeitkomponenten immer zweistellig sind.",
+ "zeroPrintDescription": "Die weggelassenen Teile werden als Nullwerte โ00โ angezeigt.",
+ "zeroPrintTruncatedParts": "Abgeschnittene Teile ohne Druck"
+ }
+}
diff --git a/public/locales/de/translation.json b/public/locales/de/translation.json
new file mode 100644
index 0000000..459cbf1
--- /dev/null
+++ b/public/locales/de/translation.json
@@ -0,0 +1,250 @@
+{
+ "audio": {
+ "changeSpeed": {
+ "description": "รndern Sie die Wiedergabegeschwindigkeit von Audiodateien. Beschleunigen oder verlangsamen Sie die Wiedergabe, ohne die Tonhรถhe zu verรคndern.",
+ "name": "Audiogeschwindigkeit รคndern",
+ "shortDescription": "รndern Sie die Geschwindigkeit von Audiodateien"
+ },
+ "extractAudio": {
+ "description": "Extrahieren Sie die Audiospur aus einer Videodatei und speichern Sie sie als separate Audiodatei im gewรผnschten Format (AAC, MP3, WAV).",
+ "name": "Audio extrahieren",
+ "shortDescription": "Extrahieren Sie Audio aus Videodateien (MP4, MOV usw.) in AAC, MP3 oder WAV."
+ }
+ },
+ "baseFileInput": {
+ "copyFailed": "Kopieren fehlgeschlagen: {{error}}",
+ "dropFileHere": "Lassen Sie Ihre {{type}} Hier",
+ "fileCopied": "Datei kopiert",
+ "selectFileDescription": "Klicken Sie hier, um eine {{type}} Drรผcken Sie auf Ihrem Gerรคt Strg+V, um eine {{type}} aus der Zwischenablage oder ziehen Sie eine Datei per Drag & Drop vom Desktop"
+ },
+ "categories": {
+ "audio": {
+ "description": "Tools fรผr die Arbeit mit Audio โ Audio aus Video extrahieren, Audiogeschwindigkeit anpassen, mehrere Audiodateien zusammenfรผhren und vieles mehr.",
+ "title": "Audio-Tools"
+ },
+ "csv": {
+ "description": "Tools zum Arbeiten mit CSV-Dateien โ konvertieren Sie CSV in verschiedene Formate, bearbeiten Sie CSV-Daten, validieren Sie die CSV-Struktur und verarbeiten Sie CSV-Dateien effizient.",
+ "title": "CSV-Tools"
+ },
+ "gif": {
+ "description": "Tools zum Arbeiten mit GIF-Animationen โ transparente GIFs erstellen, GIF-Frames extrahieren, Text zu GIFs hinzufรผgen, zuschneiden, drehen, GIFs umkehren und vieles mehr.",
+ "title": "GIF-Tools"
+ },
+ "image-generic": {
+ "description": "Tools zum Arbeiten mit Bildern โ komprimieren, Grรถรe รคndern, zuschneiden, in JPG konvertieren, drehen, Hintergrund entfernen und vieles mehr.",
+ "title": "Bildwerkzeuge"
+ },
+ "json": {
+ "description": "Tools fรผr die Arbeit mit JSON-Datenstrukturen โ Verschรถnern und Minimieren von JSON-Objekten, Verflachen von JSON-Arrays, Stringifizieren von JSON-Werten, Analysieren von Daten und vieles mehr",
+ "title": "JSON-Tools"
+ },
+ "list": {
+ "description": "Tools zum Arbeiten mit Listen โ Sortieren, Umkehren, Zufallssortieren von Listen, Suchen eindeutiger und doppelter Listenelemente, รndern der Trennzeichen von Listenelementen und vieles mehr.",
+ "title": "Tools auflisten"
+ },
+ "number": {
+ "description": "Tools fรผr die Arbeit mit Zahlen โ Zahlenfolgen generieren, Zahlen in Wรถrter und Wรถrter in Zahlen umwandeln, sortieren, runden, Zahlen faktorisieren und vieles mehr.",
+ "title": "Zahlenwerkzeuge"
+ },
+ "pdf": {
+ "description": "Tools zum Arbeiten mit PDF-Dateien โ Text aus PDFs extrahieren, PDFs in andere Formate konvertieren, PDFs bearbeiten und vieles mehr.",
+ "title": "PDF-Tools"
+ },
+ "png": {
+ "description": "Tools zum Arbeiten mit PNG-Bildern โ konvertieren Sie PNGs in JPGs, erstellen Sie transparente PNGs, รคndern Sie PNG-Farben, beschneiden Sie, drehen Sie, รคndern Sie die Grรถรe von PNGs und vieles mehr.",
+ "title": "PNG-Tools"
+ },
+ "seeAll": "Alles sehen {{title}}",
+ "string": {
+ "description": "Tools zum Arbeiten mit Text โ Text in Bilder umwandeln, Text suchen und ersetzen, Text in Fragmente aufteilen, Textzeilen verbinden, Text wiederholen und vieles mehr.",
+ "title": "Textwerkzeuge"
+ },
+ "time": {
+ "description": "Tools zum Arbeiten mit Zeit und Datum โ Zeitunterschiede berechnen, zwischen Zeitzonen umrechnen, Datumsangaben formatieren, Datumssequenzen generieren und vieles mehr.",
+ "title": "Zeitwerkzeuge"
+ },
+ "try": "Versuchen {{title}}",
+ "video": {
+ "description": "Tools zum Arbeiten mit Videos โ Extrahieren Sie Frames aus Videos, erstellen Sie GIFs aus Videos, konvertieren Sie Videos in verschiedene Formate und vieles mehr.",
+ "title": "Video-Tools"
+ },
+ "xml": {
+ "description": "Tools zum Arbeiten mit XML-Datenstrukturen โ Viewer, Beautifier, Validator und vieles mehr",
+ "title": "XML-Tools"
+ }
+ },
+ "csv": {
+ "findIncompleteCsvRecords": {
+ "description": "Laden Sie einfach Ihre CSV-Datei im untenstehenden Formular hoch. Das Tool prรผft automatisch, ob in Zeilen und Spalten Werte fehlen. In den Tool-Optionen kรถnnen Sie das Eingabedateiformat anpassen (Trennzeichen, Anfรผhrungszeichen und Kommentarzeichen festlegen). Zusรคtzlich kรถnnen Sie die Prรผfung auf leere Werte aktivieren, leere Zeilen รผberspringen und die Anzahl der Fehlermeldungen in der Ausgabe begrenzen.",
+ "name": "Unvollstรคndige CSV-Datensรคtze finden",
+ "shortDescription": "Finden Sie schnell Zeilen und Spalten in CSV, in denen Werte fehlen."
+ }
+ },
+ "hero": {
+ "brand": "OmniTools",
+ "description": "Steigern Sie Ihre Produktivitรคt mit OmniTools, dem ultimativen Toolkit fรผr schnelles Arbeiten! Greifen Sie direkt von Ihrem Browser aus auf Tausende benutzerfreundliche Dienstprogramme zum Bearbeiten von Bildern, Texten, Listen und Daten zu.",
+ "examples": {
+ "calculateNumberSum": "Zahlensumme berechnen",
+ "changeGifSpeed": "GIF-Geschwindigkeit รคndern",
+ "compressPng": "PNG komprimieren",
+ "createTransparentImage": "Erstellen Sie ein transparentes Bild",
+ "prettifyJson": "JSON verschรถnern",
+ "sortList": "Sortieren einer Liste",
+ "splitPdf": "PDF teilen",
+ "splitText": "Einen Text teilen",
+ "trimVideo": "Video zuschneiden"
+ },
+ "searchPlaceholder": "Alle Tools durchsuchen",
+ "title": "Erledigen Sie Dinge schnell mit"
+ },
+ "inputFooter": {
+ "clear": "Klar",
+ "copyToClipboard": "In die Zwischenablage kopieren",
+ "importFromFile": "Aus Datei importieren"
+ },
+ "list": {
+ "group": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Gruppieren von Listenelementen. Geben Sie Ihre Liste ein und legen Sie Gruppierungskriterien fest, um Elemente in logische Gruppen zu ordnen. Ideal zum Kategorisieren von Daten, Organisieren von Informationen oder Erstellen strukturierter Listen. Unterstรผtzt benutzerdefinierte Trennzeichen und verschiedene Gruppierungsoptionen.",
+ "name": "Gruppe",
+ "shortDescription": "Gruppieren Sie Listenelemente nach gemeinsamen Eigenschaften"
+ },
+ "reverse": {
+ "description": "Diese einfache browserbasierte Anwendung druckt alle Listenelemente rรผckwรคrts. Die Eingabeelemente kรถnnen durch ein beliebiges Symbol getrennt werden. Sie kรถnnen auch das Trennzeichen der umgekehrten Listenelemente รคndern.",
+ "name": "Umkehren",
+ "shortDescription": "Schnelles Umkehren einer Liste"
+ },
+ "sort": {
+ "description": "Dies ist eine sehr einfache browserbasierte Anwendung, die Elemente in einer Liste sortiert und in auf- oder absteigender Reihenfolge anordnet. Sie kรถnnen die Elemente alphabetisch, numerisch oder nach Lรคnge sortieren. Sie kรถnnen auch doppelte und leere Elemente entfernen sowie einzelne Elemente mit Leerzeichen kรผrzen. Sie kรถnnen die Elemente der Eingabeliste durch ein beliebiges Trennzeichen oder alternativ durch einen regulรคren Ausdruck trennen. Zusรคtzlich kรถnnen Sie ein neues Trennzeichen fรผr die sortierte Ausgabeliste erstellen.",
+ "name": "Sortieren",
+ "shortDescription": "Schnelles Sortieren einer Liste"
+ }
+ },
+ "navbar": {
+ "buyMeACoffee": "Kauf mir einen Kaffee",
+ "home": "Heim",
+ "tools": "Werkzeuge"
+ },
+ "number": {
+ "generate": {
+ "description": "Berechnen Sie schnell eine Liste von Ganzzahlen in Ihrem Browser. Geben Sie dazu einfach die erste Ganzzahl an, รคndern Sie den Wert und die Gesamtzahl in den Optionen unten. Das Dienstprogramm generiert dann die entsprechende Anzahl Ganzzahlen.",
+ "name": "Zahlen generieren",
+ "shortDescription": "Berechnen Sie schnell eine Liste von Ganzzahlen in Ihrem Browser"
+ },
+ "sum": {
+ "description": "Dies ist eine sehr einfache browserbasierte Anwendung zum Summieren von Zahlen. Die eingegebenen Zahlen kรถnnen durch ein beliebiges Symbol getrennt werden. Sie kรถnnen auch das Trennzeichen der summierten Zahlen รคndern.",
+ "name": "Summenzahlen",
+ "shortDescription": "Schnelles Summieren einer Zahlenliste"
+ }
+ },
+ "numericInputWithUnit": {
+ "unit": "Einheit"
+ },
+ "pdf": {
+ "compressPdf": {
+ "description": "Reduzieren Sie die PDF-Dateigrรถรe bei gleichbleibender Qualitรคt mit Ghostscript",
+ "name": "PDF komprimieren",
+ "shortDescription": "Komprimieren Sie PDF-Dateien sicher in Ihrem Browser"
+ },
+ "mergePdf": {
+ "description": "Kombinieren Sie mehrere PDF-Dateien zu einem einzigen Dokument.",
+ "name": "PDF zusammenfรผhren",
+ "shortDescription": "Mehrere PDF-Dateien zu einem einzigen Dokument zusammenfรผhren"
+ },
+ "pdfToEpub": {
+ "description": "Wandeln Sie PDF-Dokumente in EPUB-Dateien um, um eine bessere E-Reader-Kompatibilitรคt zu erzielen.",
+ "name": "PDF zu EPUB",
+ "shortDescription": "Konvertieren Sie PDF-Dateien in das EPUB-Format"
+ },
+ "protectPdf": {
+ "description": "Fรผgen Sie Ihren PDF-Dateien sicher in Ihrem Browser einen Passwortschutz hinzu",
+ "name": "PDF schรผtzen",
+ "shortDescription": "PDF-Dateien sicher mit einem Passwort schรผtzen"
+ },
+ "splitPdf": {
+ "description": "Extrahieren Sie bestimmte Seiten aus einer PDF-Datei mithilfe von Seitenzahlen oder Bereichen (z. B. 1,5-8).",
+ "name": "PDF teilen",
+ "shortDescription": "Extrahieren Sie bestimmte Seiten aus einer PDF-Datei"
+ }
+ },
+ "resultFooter": {
+ "copy": "In die Zwischenablage kopieren",
+ "download": "Herunterladen"
+ },
+ "string": {
+ "createPalindrome": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Erstellen von Palindromen aus beliebigem Text. Geben Sie Text ein und verwandeln Sie ihn sofort in ein Palindrom, das vorwรคrts und rรผckwรคrts gleich gelesen wird. Ideal fรผr Wortspiele, das Erstellen symmetrischer Textmuster oder das Erkunden sprachlicher Kuriositรคten.",
+ "name": "Palindrom erstellen",
+ "shortDescription": "Erstellen Sie Text, der vorwรคrts und rรผckwรคrts gleich gelesen wird"
+ },
+ "palindrome": {
+ "description": "Das weltweit einfachste browserbasierte Tool zur รberprรผfung von Palindromen. รberprรผfen Sie sofort, ob sich Ihr Text vorwรคrts und rรผckwรคrts gleich liest. Ideal fรผr Wortrรคtsel, linguistische Analysen oder die Validierung symmetrischer Textmuster. Unterstรผtzt verschiedene Trennzeichen und die Erkennung mehrteiliger Palindrome.",
+ "name": "Palindrom",
+ "shortDescription": "รberprรผfen Sie, ob der Text vorwรคrts und rรผckwรคrts gleich gelesen wird"
+ },
+ "repeat": {
+ "description": "Mit diesem Tool kรถnnen Sie einen bestimmten Text mit einem optionalen Trennzeichen mehrmals wiederholen.",
+ "name": "Text wiederholen",
+ "shortDescription": "Text mehrmals wiederholen"
+ },
+ "reverse": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zum Umkehren von Text. Geben Sie beliebigen Text ein und lassen Sie ihn sofort Zeichen fรผr Zeichen umkehren. Ideal zum Erstellen von Spiegeltext, Analysieren von Palindromen oder zum Experimentieren mit Textmustern. Leerzeichen und Sonderzeichen bleiben beim Umkehren erhalten.",
+ "name": "Umkehren",
+ "shortDescription": "Kehren Sie jeden Text Zeichen fรผr Zeichen um"
+ },
+ "toMorse": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zur Konvertierung von Text in Morsecode. Laden Sie Ihren Text in das Eingabeformular links und Sie erhalten sofort Morsecode im Ausgabebereich. Leistungsstark, kostenlos und schnell. Text laden โ Morsecode erhalten.",
+ "name": "Zeichenfolge zu Morse",
+ "shortDescription": "Text schnell in Morse kodieren"
+ },
+ "uppercase": {
+ "description": "Das weltweit einfachste browserbasierte Dienstprogramm zur Konvertierung von Text in Groรbuchstaben. Geben Sie einfach Ihren Text ein, und er wird automatisch in Groรbuchstaben umgewandelt. Ideal fรผr รberschriften, Hervorhebungen oder die Standardisierung des Textformats. Unterstรผtzt verschiedene Textformate und behรคlt Sonderzeichen bei.",
+ "name": "Groรbuchstaben",
+ "shortDescription": "Text in Groรbuchstaben umwandeln"
+ }
+ },
+ "toolExamples": {
+ "subtitle": "Klicken Sie hier, um es auszuprobieren!",
+ "title": "{{title}} Beispiele"
+ },
+ "toolFileResult": {
+ "copied": "Datei kopiert",
+ "copyFailed": "Kopieren fehlgeschlagen: {{error}}",
+ "loading": "Wird geladen... Dies kann einen Moment dauern.",
+ "result": "Ergebnis"
+ },
+ "toolHeader": {
+ "seeExamples": "Beispiele ansehen"
+ },
+ "toolLayout": {
+ "allToolsTitle": "Alle {{type}}"
+ },
+ "toolMultiFileResult": {
+ "copied": "Datei kopiert",
+ "copyFailed": "Kopieren fehlgeschlagen: {{error}}",
+ "loading": "Wird geladen... Dies kann einen Moment dauern.",
+ "result": "Ergebnis"
+ },
+ "toolMultipleAudioInput": {
+ "inputTitle": "Eingang {{type}}",
+ "noFilesSelected": "Keine Dateien ausgewรคhlt"
+ },
+ "toolMultiplePdfInput": {
+ "inputTitle": "Eingang {{type}}",
+ "noFilesSelected": "Keine Dateien ausgewรคhlt"
+ },
+ "toolOptions": {
+ "title": "Werkzeugoptionen"
+ },
+ "toolTextInput": {
+ "copied": "Text kopiert",
+ "copyFailed": "Kopieren fehlgeschlagen: {{error}}",
+ "input": "Eingabetext",
+ "placeholder": "Geben Sie hier Ihren Text ein..."
+ },
+ "toolTextResult": {
+ "copied": "Text kopiert",
+ "copyFailed": "Kopieren fehlgeschlagen: {{error}}",
+ "loading": "Wird geladen... Dies kann einen Moment dauern.",
+ "result": "Ergebnis"
+ }
+}
diff --git a/public/locales/de/video.json b/public/locales/de/video.json
new file mode 100644
index 0000000..3f110b9
--- /dev/null
+++ b/public/locales/de/video.json
@@ -0,0 +1,113 @@
+{
+ "changeSpeed": {
+ "defaultMultiplier": "Standardmultiplikator: 2 bedeutet 2x schneller",
+ "description": "รndern Sie die Wiedergabegeschwindigkeit von Videodateien. Beschleunigen oder verlangsamen Sie Videos, wรคhrend die Audiosynchronisation erhalten bleibt. Unterstรผtzt verschiedene Geschwindigkeitsmultiplikatoren und gรคngige Videoformate.",
+ "inputTitle": "Eingangsvideo",
+ "newVideoSpeed": "Neue Videogeschwindigkeit",
+ "resultTitle": "Bearbeitetes Video",
+ "settingSpeed": "Geschwindigkeit einstellen",
+ "shortDescription": "รndern der Videowiedergabegeschwindigkeit",
+ "title": "Videogeschwindigkeit รคndern",
+ "toolInfo": {
+ "title": "Was ist ein {{title}}?"
+ }
+ },
+ "compress": {
+ "default": "Standard",
+ "description": "Komprimieren Sie Videos, indem Sie sie auf verschiedene Auflรถsungen wie 240p, 480p, 720p usw. skalieren. Dieses Tool hilft, die Dateigrรถรe zu reduzieren und gleichzeitig eine akzeptable Qualitรคt beizubehalten. Unterstรผtzt gรคngige Videoformate wie MP4, WebM und OGG.",
+ "inputTitle": "Eingangsvideo",
+ "loadingText": "Video wird komprimiert...",
+ "lossless": "Verlustfrei",
+ "quality": "Qualitรคt (CRF)",
+ "resolution": "Auflรถsung",
+ "resultTitle": "Komprimiertes Video",
+ "shortDescription": "Komprimieren Sie Videos durch Skalieren auf verschiedene Auflรถsungen",
+ "title": "Video komprimieren",
+ "worst": "Am schlimmsten"
+ },
+ "cropVideo": {
+ "cropCoordinates": "Zuschneidekoordinaten",
+ "croppingVideo": "Video zuschneiden",
+ "description": "Schneiden Sie das Video zu, um unerwรผnschte Bereiche zu entfernen.",
+ "errorBeyondHeight": "Der Zuschneidebereich geht รผber die Videohรถhe hinaus ({{height}}px)",
+ "errorBeyondWidth": "Der Zuschneidebereich geht รผber die Videobreite hinaus ({{width}}px)",
+ "errorCroppingVideo": "Fehler beim Zuschneiden des Videos. Bitte รผberprรผfen Sie die Parameter und die Videodatei.",
+ "errorLoadingDimensions": "Videoabmessungen konnten nicht geladen werden",
+ "errorNonNegativeCoordinates": "X- und Y-Koordinaten dรผrfen nicht negativ sein",
+ "errorPositiveDimensions": "Breite und Hรถhe mรผssen positiv sein",
+ "height": "Hรถhe",
+ "inputTitle": "Eingangsvideo",
+ "loadVideoForDimensions": "Laden Sie ein Video, um die Abmessungen anzuzeigen",
+ "resultTitle": "Zugeschnittenes Video",
+ "shortDescription": "Video zuschneiden, um unerwรผnschte Bereiche zu entfernen",
+ "title": "Video zuschneiden",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie Videodateien zuschneiden, um unerwรผnschte Bereiche zu entfernen. Sie kรถnnen den Zuschneidebereich festlegen, indem Sie die X- und Y-Koordinaten sowie die Breiten- und Hรถhenmaรe festlegen.",
+ "title": "Video zuschneiden"
+ },
+ "videoDimensions": "Videoabmessungen: {{width}} ร {{height}} Pixel",
+ "videoInformation": "Videoinformationen",
+ "width": "Breite",
+ "xCoordinate": "X (links)",
+ "yCoordinate": "Y (oben)"
+ },
+ "flip": {
+ "description": "Drehen Sie Videodateien horizontal oder vertikal. Spiegeln Sie Videos fรผr Spezialeffekte oder zum Korrigieren von Ausrichtungsproblemen.",
+ "flippingVideo": "Video spiegeln",
+ "horizontalLabel": "Horizontal (Spiegel)",
+ "inputTitle": "Eingangsvideo",
+ "orientation": "Orientierung",
+ "resultTitle": "Gespiegeltes Video",
+ "shortDescription": "Video horizontal oder vertikal spiegeln",
+ "title": "Video umdrehen",
+ "verticalLabel": "Vertikal (auf dem Kopf stehend)"
+ },
+ "gif": {
+ "changeSpeed": {
+ "description": "รndern Sie die Wiedergabegeschwindigkeit von GIF-Animationen. Beschleunigen oder verlangsamen Sie GIFs, ohne die Animation zu verlangsamen.",
+ "shortDescription": "รndern Sie die Geschwindigkeit der GIF-Animation",
+ "title": "GIF-Geschwindigkeit รคndern"
+ }
+ },
+ "loop": {
+ "description": "Erstellen Sie ein Loop-Video, indem Sie das Originalvideo mehrmals wiederholen.",
+ "inputTitle": "Eingangsvideo",
+ "loopingVideo": "Videoschleife",
+ "loops": "Schleifen",
+ "numberOfLoops": "Anzahl der Schleifen",
+ "resultTitle": "Videoschleife",
+ "shortDescription": "Erstellen Sie Loop-Videodateien",
+ "title": "Video in Endlosschleife",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie ein Loop-Video erstellen, indem Sie das Originalvideo mehrmals wiederholen. Sie kรถnnen festlegen, wie oft das Video wiederholt werden soll.",
+ "title": "Was ist ein {{title}}?"
+ }
+ },
+ "rotate": {
+ "180Degrees": "180ยฐ (auf den Kopf gestellt)",
+ "270Degrees": "270ยฐ (90ยฐ gegen den Uhrzeigersinn)",
+ "90Degrees": "90ยฐ im Uhrzeigersinn",
+ "description": "Drehen Sie Videodateien um 90, 180 oder 270 Grad. Korrigieren Sie die Videoausrichtung oder erstellen Sie Spezialeffekte mit prรคziser Rotationssteuerung.",
+ "inputTitle": "Eingangsvideo",
+ "resultTitle": "Gedrehtes Video",
+ "rotatingVideo": "Rotierendes Video",
+ "rotation": "Drehung",
+ "shortDescription": "Video um angegebene Gradzahlen drehen",
+ "title": "Video drehen"
+ },
+ "trim": {
+ "description": "Kรผrzen Sie Videodateien, indem Sie Start- und Endzeiten festlegen. Entfernen Sie unerwรผnschte Abschnitte am Anfang oder Ende von Videos.",
+ "endTime": "Endzeit",
+ "inputTitle": "Eingangsvideo",
+ "resultTitle": "Getrimmtes Video",
+ "shortDescription": "Schneiden Sie das Video, indem Sie unerwรผnschte Abschnitte entfernen",
+ "startTime": "Startzeit",
+ "timestamps": "Zeitstempel",
+ "title": "Video trimmen"
+ },
+ "videoToGif": {
+ "description": "Konvertieren Sie Videodateien in das animierte GIF-Format. Extrahieren Sie bestimmte Zeitbereiche und erstellen Sie gemeinsam nutzbare animierte Bilder.",
+ "shortDescription": "Video in animiertes GIF konvertieren",
+ "title": "Video zu GIF"
+ }
+}
diff --git a/public/locales/de/xml.json b/public/locales/de/xml.json
new file mode 100644
index 0000000..cb38726
--- /dev/null
+++ b/public/locales/de/xml.json
@@ -0,0 +1,38 @@
+{
+ "xmlBeautifier": {
+ "description": "Formatieren Sie XML mit den richtigen Einrรผckungen und Abstรคnden.",
+ "indentation": "Vertiefung",
+ "inputTitle": "XML-Eingabe",
+ "resultTitle": "Verschรถnertes XML",
+ "shortDescription": "XML-Code formatieren und verschรถnern",
+ "title": "XML-Verschรถnerer",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie XML-Daten mit den richtigen Einrรผckungen und Abstรคnden formatieren, sodass sie besser lesbar und einfacher zu bearbeiten sind.",
+ "title": "XML-Verschรถnerer"
+ },
+ "useSpaces": "Rรคume verwenden",
+ "useSpacesDescription": "Ausgabe mit Leerzeichen einrรผcken",
+ "useTabs": "Verwenden von Registerkarten",
+ "useTabsDescription": "Einrรผcken der Ausgabe mit Tabulatoren."
+ },
+ "xmlValidator": {
+ "description": "Validieren Sie die XML-Syntax und -Struktur.",
+ "placeholder": "XML hier einfรผgen oder importieren ...",
+ "shortDescription": "XML-Code auf Fehler validieren",
+ "title": "XML-Validator",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie die XML-Syntax und -Struktur validieren. Es prรผft die korrekte XML-Formatierung und gibt bei festgestellten Problemen detaillierte Fehlermeldungen aus.",
+ "title": "XML-Validator"
+ }
+ },
+ "xmlViewer": {
+ "description": "Zeigen Sie die XML-Struktur in einem Baumformat an und erkunden Sie sie.",
+ "inputTitle": "XML-Eingabe",
+ "resultTitle": "XML-Strukturansicht",
+ "title": "XML-Viewer",
+ "toolInfo": {
+ "description": "Mit diesem Tool kรถnnen Sie XML-Daten in einem hierarchischen Baumformat anzeigen, wodurch die Untersuchung und das Verstรคndnis der Struktur von XML-Dokumenten erleichtert wird.",
+ "title": "XML-Viewer"
+ }
+ }
+}
diff --git a/public/locales/en/audio.json b/public/locales/en/audio.json
new file mode 100644
index 0000000..5184efe
--- /dev/null
+++ b/public/locales/en/audio.json
@@ -0,0 +1,61 @@
+{
+ "changeSpeed": {
+ "description": "Change the playback speed of audio files. Speed up or slow down audio while maintaining pitch.",
+ "inputTitle": "Input Audio",
+ "newAudioSpeed": "New Audio Speed",
+ "outputFormat": "Output Format",
+ "resultTitle": "Edited Audio",
+ "settingSpeed": "Setting Speed",
+ "shortDescription": "Change the speed of audio files",
+ "speedDescription": "Default multiplier: 2 means 2x faster",
+ "title": "Change audio speed",
+ "toolInfo": {
+ "title": "What is {{title}}?"
+ }
+ },
+ "extractAudio": {
+ "description": "Extract audio track from video files.",
+ "extractingAudio": "Extracting Audio",
+ "inputTitle": "Input Video",
+ "outputFormat": "Output Format",
+ "outputFormatDescription": "Select the format for the audio to be extracted as.",
+ "resultTitle": "Extracted Audio",
+ "shortDescription": "Extract audio from video files (MP4, MOV, etc.) to AAC, MP3, or WAV.",
+ "title": "Extract Audio from Video",
+ "toolInfo": {
+ "description": "This tool allows you to extract the audio track from video files. You can choose from different audio formats including AAC, MP3, and WAV.",
+ "title": "What is {{title}}?"
+ }
+ },
+ "mergeAudio": {
+ "description": "Combine multiple audio files into a single audio file by concatenating them in sequence.",
+ "inputTitle": "Input Audio Files",
+ "longDescription": "This tool allows you to merge multiple audio files into a single file by concatenating them in the order you upload them. Perfect for combining podcast segments, music tracks, or any audio files that need to be joined together. Supports various audio formats including MP3, AAC, and WAV.",
+ "mergingAudio": "Merging Audio",
+ "outputFormat": "Output Format",
+ "resultTitle": "Merged Audio",
+ "shortDescription": "Merge multiple audio files into one (MP3, AAC, WAV).",
+ "title": "Merge Audio",
+ "toolInfo": {
+ "title": "What is {{title}}?"
+ }
+ },
+ "trim": {
+ "description": "Cut and trim audio files to extract specific segments by specifying start and end times.",
+ "endTime": "End Time",
+ "endTimeDescription": "End time in format HH:MM:SS (e.g., 00:01:30)",
+ "inputTitle": "Input Audio",
+ "longDescription": "This tool allows you to trim audio files by specifying start and end times. You can extract specific segments from longer audio files, remove unwanted parts, or create shorter clips. Supports various audio formats including MP3, AAC, and WAV. Perfect for podcast editing, music production, or any audio editing needs.",
+ "outputFormat": "Output Format",
+ "resultTitle": "Trimmed Audio",
+ "shortDescription": "Trim audio files to extract specific time segments (MP3, AAC, WAV).",
+ "startTime": "Start Time",
+ "startTimeDescription": "Start time in format HH:MM:SS (e.g., 00:00:30)",
+ "timeSettings": "Time Settings",
+ "title": "Trim Audio",
+ "toolInfo": {
+ "title": "What is {{title}}?"
+ },
+ "trimmingAudio": "Trimming Audio"
+ }
+}
diff --git a/public/locales/en/csv.json b/public/locales/en/csv.json
new file mode 100644
index 0000000..5f533d4
--- /dev/null
+++ b/public/locales/en/csv.json
@@ -0,0 +1,120 @@
+{
+ "changeCsvSeparator": {
+ "description": "Change the delimiter/separator in CSV files. Convert between different CSV formats like comma, semicolon, tab, or custom separators.",
+ "shortDescription": "Change CSV file delimiter",
+ "title": "Change CSV Separator"
+ },
+ "csvRowsToColumns": {
+ "description": "This tool converts rows of a CSV (Comma Separated Values) file into columns. It extracts the horizontal lines from the input CSV one by one, rotates them 90 degrees, and outputs them as vertical columns one after another, separated by commas.', longDescription: 'This tool converts rows of a CSV (Comma Separated Values) file into columns. For example, if the input CSV data has 6 rows, then the output will have 6 columns and the elements of the rows will be arranged from the top to bottom. In a well-formed CSV, the number of values in each row is the same. However, in cases when rows are missing fields, the program can fix them and you can choose from the available options: fill missing data with empty elements or replace missing data with custom elements, such as \"missing\", \"?\", or \"x\". During the conversion process, the tool also cleans the CSV file from unnecessary information, such as empty lines (these are lines without visible information) and comments. To help the tool correctly identify comments, in the options, you can specify the symbol at the beginning of a line that starts a comment. This symbol is typically a hash \"#\" or double slash \"//\". Csv-abulous!.",
+ "longDescription": "This tool converts rows of a CSV (Comma Separated Values) file into columns. For example, if the input CSV data has 6 rows, then the output will have 6 columns and the elements of the rows will be arranged from the top to bottom. In a well-formed CSV, the number of values in each row is the same. However, in cases when rows are missing fields, the program can fix them and you can choose from the available options: fill missing data with empty elements or replace missing data with custom elements, such as",
+ "shortDescription": "Convert CSV rows to columns.",
+ "title": "Convert CSV Rows to Columns"
+ },
+ "csvToJson": {
+ "columnSeparator": "Column Separator (e.g., , ; \\t)",
+ "commentSymbol": "Comment Symbol (e.g., #)",
+ "conversionOptions": "Conversion Options",
+ "description": "Convert CSV files to JSON format with customizable options for delimiters, quotes, and output formatting. Support for headers, comments, and dynamic type conversion.",
+ "dynamicTypes": "Dynamic Types",
+ "dynamicTypesDescription": "Automatically convert numbers and booleans",
+ "error": "Error",
+ "errorParsing": "Error parsing CSV: {{error}}",
+ "fieldQuote": "Field Quote (e.g., \")",
+ "inputCsvFormat": "Input CSV Format",
+ "inputTitle": "Input CSV",
+ "invalidCsvFormat": "Invalid CSV format",
+ "resultTitle": "Output JSON",
+ "shortDescription": "Convert CSV data to JSON format.",
+ "skipEmptyLines": "Skip Empty Lines",
+ "skipEmptyLinesDescription": "Ignore empty lines in the input CSV",
+ "title": "Convert CSV to JSON",
+ "toolInfo": {
+ "description": "This tool transforms Comma Separated Values (CSV) files to JavaScript Object Notation (JSON) data structures. It supports various CSV formats with customizable delimiters, quote characters, and comment symbols. The converter can treat the first row as headers, skip empty lines, and automatically detect data types like numbers and booleans. The resulting JSON can be used for data migration, backups, or as input for other applications.",
+ "title": "What Is a CSV to JSON Converter?"
+ },
+ "useHeaders": "Use Headers",
+ "useHeadersDescription": "Treat the first row as column headers"
+ },
+ "csvToTsv": {
+ "description": "Upload your CSV file in the form below and it will automatically get converted to a TSV file. In the tool options, you can customize the input CSV format โ specify the field delimiter, quotation character, and comment symbol, as well as skip empty CSV lines, and choose whether to preserve CSV column headers.",
+ "longDescription": "This tool transforms Comma Separated Values (CSV) data to Tab Separated Values (TSV) data. Both CSV and TSV are popular file formats for storing tabular data but they use different delimiters to separate values โ CSV uses commas (",
+ "shortDescription": "Convert CSV data to TSV format.",
+ "title": "Convert CSV to TSV"
+ },
+ "csvToXml": {
+ "description": "Convert CSV files to XML format with customizable options.",
+ "shortDescription": "Convert CSV data to XML format.",
+ "title": "Convert CSV to XML"
+ },
+ "csvToYaml": {
+ "description": "Just upload your CSV file in the form below and it will automatically get converted to a YAML file. In the tool options, you can specify the field delimiter character, field quote character, and comment character to adapt the tool to custom CSV formats. Additionally, you can select the output YAML format: one that preserves CSV headers or one that excludes CSV headers.",
+ "longDescription": "This tool transforms CSV (Comma Separated Values) data into the YAML (Yet Another Markup Language) data. CSV is a simple, tabular format that is used to represent matrix-like data types consisting of rows and columns. YAML, on the other hand, is a more advanced format (actually a superset of JSON), which creates more human-readable data for serialization, and it supports lists, dictionaries, and nested objects. This program supports various input CSV formats โ the input data can be comma-separated (default), semicolon-separated, pipe-separated, or use another completely different delimiter. You can specify the exact delimiter your data uses in the options. Similarly, in the options, you can specify the quote character that is used to wrap CSV fields (by default a double-quote symbol). You can also skip lines that start with comments by specifying the comment symbols in the options. This allows you to keep your data clean by skipping unnecessary lines. There are two ways to convert CSV to YAML. The first method converts each CSV row into a YAML list. The second method extracts headers from the first CSV row and creates YAML objects with keys based on these headers. You can also customize the output YAML format by specifying the number of spaces for indenting YAML structures. If you need to perform the reverse conversion, that is, transform YAML into CSV, you can use our Convert YAML to CSV tool. Csv-abulous!",
+ "shortDescription": "Quickly convert a CSV file to a YAML file.",
+ "title": "Convert CSV to YAML"
+ },
+ "findIncompleteCsvRecords": {
+ "checkingOptions": "Checking Options",
+ "commentCharacterDescription": "Enter the character indicating the start of a comment line. Lines starting with this symbol will be skipped.",
+ "csvInputOptions": "CSV Input Options",
+ "csvSeparatorDescription": "Enter the character used to delimit columns in the CSV input file.",
+ "deleteLinesWithNoData": "Delete Lines with No Data",
+ "deleteLinesWithNoDataDescription": "Remove empty lines from CSV input file.",
+ "description": "Just upload your CSV file in the form below and this tool will automatically check if none of the rows or columns are missing values. In the tool options, you can adjust the input file format (specify the delimiter, quote character, and comment character). Additionally, you can enable checking for empty values, skip empty lines, and set a limit on the number of error messages in the output.",
+ "findEmptyValues": "Find Empty Values",
+ "findEmptyValuesDescription": "Display a message about CSV fields that are empty (These are not missing fields but fields that contain nothing).",
+ "inputTitle": "Input CSV",
+ "limitNumberOfMessages": "Limit number of messages",
+ "messageLimitDescription": "Set the limit of number of messages in the output.",
+ "quoteCharacterDescription": "Enter the quote character used to quote the CSV input fields.",
+ "resultTitle": "CSV Status",
+ "shortDescription": "Quickly find rows and columns in CSV that are missing values.",
+ "title": "Find incomplete CSV records",
+ "toolInfo": {
+ "title": "What is a {{title}}?"
+ }
+ },
+ "insertCsvColumns": {
+ "appendColumns": "Append columns",
+ "commentCharacterDescription": "Enter the character indicating the start of a comment line. Lines starting with this symbol will be skipped.",
+ "csvOptions": "CSV Options",
+ "csvSeparator": "CSV separator",
+ "csvToInsert": "CSV to insert",
+ "csvToInsertDescription": "Enter one or more columns you want to insert into the CSV. the character used to delimit columns has to be the same with the one in the CSV input file. Ps: Blank lines will be ignored",
+ "customFillDescription": "If the input CSV file is incomplete (missing values), then add empty fields or custom symbols to records to make a well-formed CSV?",
+ "customFillValueDescription": "Use this custom value to fill in missing fields. (Works only with \"Custom Values\" mode above.)",
+ "customPosition": "Custom position",
+ "customPositionOptionsDescription": "Select the method to insert the columns in the CSV file.",
+ "description": "Add new columns to CSV data at specified positions.",
+ "fillWithCustomValues": "Fill With Customs Values",
+ "fillWithEmptyValues": "Fill With Empty Values",
+ "headerName": "Header name",
+ "headerNameDescription": "Header of the column you want to insert columns after.",
+ "inputTitle": "Input CSV",
+ "insertingPositionDescription": "Specify where to insert the columns in the CSV file.",
+ "position": "Position",
+ "positionOptions": "Position Options",
+ "prependColumns": "Prepend columns",
+ "quoteCharDescription": "Enter the quote character used to quote the CSV input fields.",
+ "resultTitle": "Output CSV",
+ "rowNumberDescription": "Number of the column you want to insert columns after.",
+ "separatorDescription": "Enter the character used to delimit columns in the CSV input file.",
+ "shortDescription": "Quickly insert one or more new columns anywhere in a CSV file.",
+ "title": "Insert CSV columns",
+ "toolInfo": {
+ "description": "This tool allows you to insert new columns into CSV data at specified positions. You can prepend, append, or insert columns at custom positions based on header names or column numbers.",
+ "title": "Insert CSV Columns"
+ }
+ },
+ "swapCsvColumns": {
+ "description": "Just upload your CSV file in the form below, specify the columns to swap, and the tool will automatically change the positions of the specified columns in the output file. In the tool options, you can specify the column positions or names that you want to swap, as well as fix incomplete data and optionally remove empty records and records that have been commented out.",
+ "longDescription": "This tool reorganizes CSV data by swapping the positions of its columns. Swapping columns can enhance the readability of a CSV file by placing frequently used data together or in the front for easier data comparison and editing. For example, you can swap the first column with the last or swap the second column with the third. To swap columns based on their positions, select the",
+ "shortDescription": "Reorder CSV columns.",
+ "title": "Swap CSV Columns"
+ },
+ "transposeCsv": {
+ "description": "Just upload your CSV file in the form below, and this tool will automatically transpose your CSV. In the tool options, you can specify the character that starts the comment lines in the CSV to remove them. Additionally, if the CSV is incomplete (missing values), you can replace missing values with the empty character or a custom character.",
+ "longDescription": "This tool transposes Comma Separated Values (CSV). It treats the CSV as a matrix of data and flips all elements across the main diagonal. The output contains the same CSV data as the input, but now all the rows have become columns, and all the columns have become rows. After transposition, the CSV file will have opposite dimensions. For example, if the input file has 4 columns and 3 rows, the output file will have 3 columns and 4 rows. During conversion, the program also cleans the data from unnecessary lines and corrects incomplete data. Specifically, the tool automatically deletes all empty records and comments that begin with a specific character, which you can set in the option. Additionally, in cases where the CSV data is corrupted or lost, the utility completes the file with empty fields or custom fields that can be specified in the options. Csv-abulous!",
+ "shortDescription": "Quickly transpose a CSV file.",
+ "title": "Transpose CSV"
+ }
+}
diff --git a/public/locales/en/image.json b/public/locales/en/image.json
new file mode 100644
index 0000000..9a03c73
--- /dev/null
+++ b/public/locales/en/image.json
@@ -0,0 +1,105 @@
+{
+ "changeColors": {
+ "description": "World",
+ "shortDescription": "Quickly swap colors in a image",
+ "title": "Change colors in image"
+ },
+ "changeOpacity": {
+ "description": "Easily adjust the transparency of your images. Simply upload your image, use the slider to set the desired opacity level between 0 (fully transparent) and 1 (fully opaque), and download the modified image.",
+ "shortDescription": "Adjust transparency of images",
+ "title": "Change image Opacity"
+ },
+ "compress": {
+ "compressedSize": "Compressed Size",
+ "compressionOptions": "Compression options",
+ "description": "Reduce image file size while maintaining quality.",
+ "failedToCompress": "Failed to compress image. Please try again.",
+ "fileSizes": "File sizes",
+ "inputTitle": "Input image",
+ "maxFileSizeDescription": "Maximum file size in megabytes",
+ "originalSize": "Original Size",
+ "qualityDescription": "Image quality percentage (lower means smaller file size)",
+ "resultTitle": "Compressed image",
+ "shortDescription": "Compress images to reduce file size while maintaining reasonable quality.",
+ "title": "Compress Image"
+ },
+ "compressPng": {
+ "description": "This is a program that compresses PNG pictures. As soon as you paste your PNG picture in the input area, the program will compress it and show the result in the output area. In the options, you can adjust the compression level, as well as find the old and new picture file sizes.",
+ "shortDescription": "Quickly compress a PNG",
+ "title": "Compress png"
+ },
+ "convertJgpToPng": {
+ "description": "Quickly convert your JPG images to PNG. Just import your PNG image in the editor on the left",
+ "shortDescription": "Quickly convert your JPG images to PNG",
+ "title": "Convert JPG to PNG"
+ },
+ "convertToJpg": {
+ "description": "Convert various image formats (PNG, GIF, TIF, PSD, SVG, WEBP, HEIC, RAW) to JPG with customizable quality and background color settings.",
+ "shortDescription": "Convert images to JPG with quality control",
+ "title": "Convert Images to JPG"
+ },
+ "createTransparent": {
+ "description": "World",
+ "shortDescription": "Quickly make an image transparent",
+ "title": "Create transparent PNG"
+ },
+ "crop": {
+ "description": "Crop images to remove unwanted areas.",
+ "inputTitle": "Input image",
+ "resultTitle": "Cropped image",
+ "shortDescription": "Crop images quickly.",
+ "title": "Crop Image"
+ },
+ "editor": {
+ "description": "Advanced image editor with tools for cropping, rotating, annotating, adjusting colors, and adding watermarks. Edit your images with professional-grade tools directly in your browser.",
+ "shortDescription": "Edit images with advanced tools and features",
+ "title": "Image Editor"
+ },
+ "imageToText": {
+ "description": "Extract text from images (JPG, PNG) using optical character recognition (OCR).",
+ "shortDescription": "Extract text from images using OCR.",
+ "title": "Image to Text (OCR)"
+ },
+ "qrCode": {
+ "description": "Generate QR codes for different data types: URL, Text, Email, Phone, SMS, WiFi, vCard, and more.",
+ "shortDescription": "Create customized QR codes for various data formats.",
+ "title": "QR Code Generator"
+ },
+ "removeBackground": {
+ "description": "World",
+ "shortDescription": "Automatically remove backgrounds from images",
+ "title": "Remove Background from Image"
+ },
+ "resize": {
+ "description": "Resize images to different dimensions.",
+ "dimensionType": "Dimension Type",
+ "heightDescription": "Height (in pixels)",
+ "inputTitle": "Input Image",
+ "maintainAspectRatio": "Maintain Aspect Ratio",
+ "maintainAspectRatioDescription": "Maintain the original aspect ratio of the image.",
+ "percentage": "Percentage",
+ "percentageDescription": "Percentage of original size (e.g., 50 for half size, 200 for double size)",
+ "resizeByPercentage": "Resize by Percentage",
+ "resizeByPercentageDescription": "Resize by specifying a percentage of the original size.",
+ "resizeByPixels": "Resize by Pixels",
+ "resizeByPixelsDescription": "Resize by specifying dimensions in pixels.",
+ "resizeMethod": "Resize Method",
+ "resultTitle": "Resized Image",
+ "setHeight": "Set Height",
+ "setHeightDescription": "Specify the height in pixels and calculate width based on aspect ratio.",
+ "setWidth": "Set Width",
+ "setWidthDescription": "Specify the width in pixels and calculate height based on aspect ratio.",
+ "shortDescription": "Resize images easily.",
+ "title": "Resize Image",
+ "toolInfo": {
+ "description": "This tool allows you to resize JPG, PNG, SVG, or GIF images. You can resize by specifying dimensions in pixels or by percentage, with options to maintain the original aspect ratio.",
+ "title": "Resize Image"
+ },
+ "widthDescription": "Width (in pixels)"
+ },
+ "rotate": {
+ "description": "Rotate an image by a specified angle.",
+ "shortDescription": "Rotate an image easily.",
+ "title": "Rotate Image"
+ }
+}
diff --git a/public/locales/en/json.json b/public/locales/en/json.json
new file mode 100644
index 0000000..75f59d0
--- /dev/null
+++ b/public/locales/en/json.json
@@ -0,0 +1,67 @@
+{
+ "comparison": {
+ "description": "Compare two JSON objects to identify differences in structure and values.",
+ "shortDescription": "Find differences between two JSON objects",
+ "title": "Compare JSON"
+ },
+ "escapeJson": {
+ "description": "Escape special characters in JSON strings. Convert JSON data to properly escaped format for safe transmission or storage.",
+ "shortDescription": "Escape special characters in JSON",
+ "title": "Escape JSON"
+ },
+ "jsonToXml": {
+ "description": "Convert JSON data to XML format. Transform structured JSON objects into well-formed XML documents.",
+ "shortDescription": "Convert JSON to XML format",
+ "title": "JSON to XML"
+ },
+ "minify": {
+ "description": "Remove all unnecessary whitespace from JSON.",
+ "inputTitle": "Input JSON",
+ "resultTitle": "Minified JSON",
+ "shortDescription": "Minify JSON by removing whitespace",
+ "title": "Minify JSON",
+ "toolInfo": {
+ "description": "JSON minification is the process of removing all unnecessary whitespace characters from JSON data while maintaining its validity. This includes removing spaces, newlines, and indentation that aren't required for the JSON to be parsed correctly. Minification reduces the size of JSON data, making it more efficient for storage and transmission while keeping the exact same data structure and values.",
+ "title": "What Is JSON Minification?"
+ }
+ },
+ "prettify": {
+ "description": "Format JSON with proper indentation and spacing.",
+ "indentation": "Indentation",
+ "inputTitle": "Input JSON",
+ "resultTitle": "Prettified JSON",
+ "shortDescription": "Format and beautify JSON code",
+ "title": "Prettify JSON",
+ "toolInfo": {
+ "description": "This tool allows you to format JSON data with proper indentation and spacing, making it more readable and easier to work with.",
+ "title": "Prettify JSON"
+ },
+ "useSpaces": "Use Spaces",
+ "useSpacesDescription": "Indent output with spaces",
+ "useTabs": "Use Tabs",
+ "useTabsDescription": "Indent output with tabs."
+ },
+ "stringify": {
+ "description": "Convert JavaScript objects to JSON string format. Serialize data structures into JSON strings for storage or transmission.",
+ "shortDescription": "Convert objects to JSON string",
+ "title": "Stringify JSON"
+ },
+ "tsvToJson": {
+ "description": "Convert TSV (Tab-Separated Values) data to JSON format. Transform tabular data into structured JSON objects.",
+ "shortDescription": "Convert TSV to JSON format",
+ "title": "TSV to JSON"
+ },
+ "validateJson": {
+ "description": "Check if JSON is valid and well-formed.",
+ "inputTitle": "Input JSON",
+ "invalidJson": "โ {{error}}",
+ "resultTitle": "Validation Result",
+ "shortDescription": "Validate JSON code for errors",
+ "title": "Validate JSON",
+ "toolInfo": {
+ "description": "JSON (JavaScript Object Notation) is a lightweight data-interchange format. JSON validation ensures that the structure of the data conforms to the JSON standard. A valid JSON object must have: - Property names enclosed in double quotes. - Properly balanced curly braces {}. - No trailing commas after the last key-value pair. - Proper nesting of objects and arrays. This tool checks the input JSON and provides feedback to help identify and fix common errors.",
+ "title": "What is JSON Validation?"
+ },
+ "validJson": "โ
Valid JSON"
+ }
+}
diff --git a/public/locales/en/list.json b/public/locales/en/list.json
new file mode 100644
index 0000000..ddb04d1
--- /dev/null
+++ b/public/locales/en/list.json
@@ -0,0 +1,258 @@
+{
+ "duplicate": {
+ "concatenate": "Concatenate",
+ "concatenateDescription": "Concatenate copies (if unchecked, items will be interweaved)",
+ "copyDescription": "Number of copies (can be fractional)",
+ "description": "World's simplest browser-based utility for duplicating list items. Input your list and specify duplication criteria to create copies of items. Perfect for data expansion, testing, or creating repeated patterns.",
+ "duplicationOptions": "Duplication Options",
+ "error": "Error",
+ "example1Description": "This example shows how to duplicate a list of words.",
+ "example1Title": "Simple duplication",
+ "example2Description": "This example shows how to duplicate a list in reverse order.",
+ "example2Title": "Reverse duplication",
+ "example3Description": "This example shows how to interweave items instead of concatenating them.",
+ "example3Title": "Interweaving items",
+ "example4Description": "This example shows how to duplicate a list with a fractional number of copies.",
+ "example4Title": "Fractional duplication",
+ "examples": {
+ "fractional": {
+ "description": "This example shows how to duplicate a list with a fractional number of copies.",
+ "title": "Fractional duplication"
+ },
+ "interweave": {
+ "description": "This example shows how to interweave items instead of concatenating them.",
+ "title": "Interweaving items"
+ },
+ "reverse": {
+ "description": "This example shows how to duplicate a list in reverse order.",
+ "title": "Reverse duplication"
+ },
+ "simple": {
+ "description": "This example shows how to duplicate a list of words.",
+ "title": "Simple duplication"
+ }
+ },
+ "inputTitle": "Input List",
+ "joinSeparatorDescription": "Separator to join the duplicated list",
+ "resultTitle": "Duplicated List",
+ "reverse": "Reverse",
+ "reverseDescription": "Reverse the duplicated items",
+ "shortDescription": "Duplicate list items with specified criteria",
+ "splitByRegex": "Split by Regular Expression",
+ "splitBySymbol": "Split by Symbol",
+ "splitOptions": "Split Options",
+ "splitSeparatorDescription": "Separator to split the list",
+ "title": "Duplicate",
+ "toolInfo": {
+ "description": "This tool allows you to duplicate items in a list. You can specify the number of copies (including fractional values), control whether items are concatenated or interweaved, and even reverse the duplicated items. It's useful for creating repeated patterns, generating test data, or expanding lists with predictable content.",
+ "title": "List Duplication"
+ },
+ "unknownError": "An unknown error occurred",
+ "validation": {
+ "copyMustBeNumber": "Number of copies must be a number",
+ "copyMustBePositive": "Number of copies must be positive",
+ "copyRequired": "Number of copies is required",
+ "joinSeparatorRequired": "The join separator is required",
+ "separatorRequired": "The separator is required"
+ }
+ },
+ "findMostPopular": {
+ "description": "World's simplest browser-based utility for finding the most popular items in a list. Input your list and instantly get the items that appear most frequently. Perfect for data analysis, trend identification, or finding common elements.",
+ "displayFormatDescription": "How to display the most popular list items?",
+ "displayOptions": {
+ "count": "Show item count",
+ "percentage": "Show item percentage",
+ "total": "Show item total"
+ },
+ "extractListItems": "How to Extract List Items?",
+ "ignoreItemCase": "Ignore Item Case",
+ "ignoreItemCaseDescription": "Compare all list items in lowercase.",
+ "inputTitle": "Input list",
+ "itemComparison": "Item comparison",
+ "outputFormat": "Top item output format",
+ "removeEmptyItems": "Remove empty items",
+ "removeEmptyItemsDescription": "Ignore empty items from comparison.",
+ "resultTitle": "Most popular items",
+ "shortDescription": "Find most frequently occurring items",
+ "sortOptions": {
+ "alphabetic": "Sort Alphabetically",
+ "count": "Sort by count"
+ },
+ "sortingMethodDescription": "Select a sorting method.",
+ "splitOperators": {
+ "regex": {
+ "description": "Delimit input list items with a regular expression.",
+ "title": "Use a Regex for Splitting"
+ },
+ "symbol": {
+ "description": "Delimit input list items with a character.",
+ "title": "Use a Symbol for Splitting"
+ }
+ },
+ "splitSeparatorDescription": "Set a delimiting symbol or regular expression.",
+ "title": "Find most popular",
+ "trimItems": "Trim top list items",
+ "trimItemsDescription": "Remove leading and trailing spaces before comparing items"
+ },
+ "findUnique": {
+ "caseSensitiveItems": "Case Sensitive Items",
+ "caseSensitiveItemsDescription": "Output items with different case as unique elements in the list.",
+ "delimiterDescription": "Set a delimiting symbol or regular expression.",
+ "description": "World's simplest browser-based utility for finding unique items in a list. Input your list and instantly get all unique values with duplicates removed. Perfect for data cleaning, deduplication, or finding distinct elements.",
+ "findAbsolutelyUniqueItems": "Find Absolutely Unique Items",
+ "findAbsolutelyUniqueItemsDescription": "Display only those items of the list that exist in a single copy.",
+ "inputListDelimiter": "Input List Delimiter",
+ "inputTitle": "Input List",
+ "outputListDelimiter": "Output List Delimiter",
+ "resultTitle": "Unique Items",
+ "shortDescription": "Find unique items in a list",
+ "skipEmptyItems": "Skip Empty Items",
+ "skipEmptyItemsDescription": "Don't include the empty list items in the output.",
+ "title": "Find unique",
+ "trimItems": "Trim List Items",
+ "trimItemsDescription": "Remove leading and trailing spaces before comparing items.",
+ "uniqueItemOptions": "Unique Item Options"
+ },
+ "group": {
+ "deleteEmptyItems": "Delete Empty Items",
+ "deleteEmptyItemsDescription": "Ignore empty items and don't include them in the groups.",
+ "description": "World's simplest browser-based utility for grouping list items. Input your list and specify grouping criteria to organize items into logical groups. Perfect for categorizing data, organizing information, or creating structured lists. Supports custom separators and various grouping options.",
+ "emptyItemsAndPadding": "Empty Items and Padding",
+ "groupNumberDescription": "Number of items in a group",
+ "groupSeparatorDescription": "Group separator character",
+ "groupSizeAndSeparators": "Group Size and Separators",
+ "inputItemSeparator": "Input Item Separator",
+ "inputTitle": "Input list",
+ "itemSeparatorDescription": "Item separator character",
+ "leftWrapDescription": "Group's left wrap symbol.",
+ "padNonFullGroups": "Pad Non-full Groups",
+ "padNonFullGroupsDescription": "Fill non-full groups with a custom item (enter below).",
+ "paddingCharDescription": "Use this character or item to pad non-full groups.",
+ "resultTitle": "Grouped items",
+ "rightWrapDescription": "Group's right wrap symbol.",
+ "shortDescription": "Group list items by common properties",
+ "splitOperators": {
+ "regex": {
+ "description": "Delimit input list items with a regular expression.",
+ "title": "Use a Regex for Splitting"
+ },
+ "symbol": {
+ "description": "Delimit input list items with a character.",
+ "title": "Use a Symbol for Splitting"
+ }
+ },
+ "splitSeparatorDescription": "Set a delimiting symbol or regular expression.",
+ "title": "Group"
+ },
+ "reverse": {
+ "description": "This is a super simple browser-based application prints all list items in reverse. The input items can be separated by any symbol and you can also change the separator of the reversed list items.",
+ "inputTitle": "Input list",
+ "itemSeparator": "Item Separator",
+ "itemSeparatorDescription": "Set a delimiting symbol or regular expression.",
+ "outputListOptions": "Output List Options",
+ "outputSeparatorDescription": "Output list item separator.",
+ "resultTitle": "Reversed list",
+ "shortDescription": "Quickly reverse a list",
+ "splitOperators": {
+ "regex": {
+ "description": "Delimit input list items with a regular expression.",
+ "title": "Use a Regex for Splitting"
+ },
+ "symbol": {
+ "description": "Delimit input list items with a character.",
+ "title": "Use a Symbol for Splitting"
+ }
+ },
+ "splitterMode": "Splitter Mode",
+ "title": "Reverse",
+ "toolInfo": {
+ "description": "With this utility, you can reverse the order of items in a list. The utility first splits the input list into individual items and then iterates through them from the last item to the first item, printing each item to the output during the iteration. The input list may contain anything that can be represented as textual data, which includes digits, numbers, strings, words, sentences, etc. The input item separator can also be a regular expression. For example, the regex /[;,]/ will allow you to use items that are either comma- or semicolon-separated. The input and output list items delimiters can be customized in the options. By default, both input and output lists are comma-separated. Listabulous!",
+ "title": "What Is a List Reverser?"
+ }
+ },
+ "rotate": {
+ "description": "World's simplest browser-based utility for rotating list items. Input your list and specify rotation amount to shift items by a specified number of positions. Perfect for data manipulation, circular shifts, or reordering lists.",
+ "shortDescription": "Rotate list items by specified positions",
+ "title": "Rotate"
+ },
+ "shuffle": {
+ "delimiterDescription": "Set a delimiting symbol or regular expression.",
+ "description": "World's simplest browser-based utility for shuffling list items. Input your list and instantly get a randomized version with items in random order. Perfect for creating variety, testing randomness, or mixing up ordered data.",
+ "inputListSeparator": "Input list separator",
+ "inputTitle": "Input list",
+ "joinSeparatorDescription": "Use this separator in the randomized list.",
+ "outputLengthDescription": "Output this many random items",
+ "resultTitle": "Shuffled list",
+ "shortDescription": "Randomize the order of list items",
+ "shuffledListLength": "Shuffled List Length",
+ "shuffledListSeparator": "Shuffled List Separator",
+ "title": "Shuffle"
+ },
+ "sort": {
+ "caseSensitive": "Case Sensitive Sort",
+ "caseSensitiveDescription": "Sort uppercase and lowercase items separately. Capital letters precede lowercase letters in an ascending list. (Works only in alphabetical sorting mode.)",
+ "description": "World's simplest browser-based utility for sorting list items. Input your list and specify sorting criteria to organize items in ascending or descending order. Perfect for data organization, text processing, or creating ordered lists.",
+ "inputItemSeparator": "Input item separator",
+ "inputTitle": "Input list",
+ "joinSeparatorDescription": "Use this symbol as a joiner between items in a sorted list.",
+ "orderDescription": "Select a sorting order.",
+ "orderOptions": {
+ "decreasing": "Decreasing order",
+ "increasing": "Increasing order"
+ },
+ "removeDuplicates": "Remove duplicates",
+ "removeDuplicatesDescription": "Delete duplicate list items.",
+ "resultTitle": "Sorted list",
+ "shortDescription": "Sort list items in specified order",
+ "sortMethod": "Sort method",
+ "sortMethodDescription": "Select a sorting method.",
+ "sortOptions": {
+ "alphabetic": "Sort Alphabetically",
+ "length": "Sort by Length",
+ "numeric": "Sort Numerically"
+ },
+ "sortedItemProperties": "Sorted item properties",
+ "splitOperators": {
+ "regex": {
+ "description": "Delimit input list items with a regular expression.",
+ "title": "Use a Regex for Splitting"
+ },
+ "symbol": {
+ "description": "Delimit input list items with a character.",
+ "title": "Use a Symbol for Splitting"
+ }
+ },
+ "splitSeparatorDescription": "Set a delimiting symbol or regular expression.",
+ "title": "Sort"
+ },
+ "truncate": {
+ "description": "World's simplest browser-based utility for truncating lists. Input your list and specify the maximum number of items to keep. Perfect for data processing, list management, or limiting content length.",
+ "shortDescription": "Truncate list to specified number of items",
+ "title": "Truncate"
+ },
+ "unwrap": {
+ "description": "World's simplest browser-based utility for unwrapping list items. Input your wrapped list and specify unwrapping criteria to flatten organized items. Perfect for data processing, text manipulation, or extracting content from structured lists.",
+ "shortDescription": "Unwrap list items from structured format",
+ "title": "Unwrap"
+ },
+ "wrap": {
+ "description": "Add text before and after each list item.",
+ "inputTitle": "Input List",
+ "joinSeparatorDescription": "Separator to join the wrapped list",
+ "leftTextDescription": "Text to add before each item",
+ "removeEmptyItems": "Remove empty items",
+ "resultTitle": "Wrapped List",
+ "rightTextDescription": "Text to add after each item",
+ "shortDescription": "Wrap list items with specified criteria",
+ "splitByRegex": "Split by Regular Expression",
+ "splitBySymbol": "Split by Symbol",
+ "splitOptions": "Split Options",
+ "splitSeparatorDescription": "Separator to split the list",
+ "title": "Wrap",
+ "toolInfo": {
+ "description": "This tool allows you to add text before and after each item in a list. You can specify different text for the left and right sides, and control how the list is processed. It's useful for adding quotes, brackets, or other formatting to list items, preparing data for different formats, or creating structured text.",
+ "title": "List Wrapping"
+ },
+ "wrapOptions": "Wrap Options"
+ }
+}
diff --git a/public/locales/en/number.json b/public/locales/en/number.json
new file mode 100644
index 0000000..9d57f64
--- /dev/null
+++ b/public/locales/en/number.json
@@ -0,0 +1,97 @@
+{
+ "arithmeticSequence": {
+ "commonDifferenceDescription": "Common difference between terms (d)",
+ "description": "Generate arithmetic sequences with customizable parameters.",
+ "firstTermDescription": "First term of the sequence (aโ)",
+ "numberOfTermsDescription": "Number of terms to generate (n)",
+ "outputFormat": "Output Format",
+ "resultTitle": "Generated Sequence",
+ "separatorDescription": "Separator between terms",
+ "sequenceParameters": "Sequence Parameters",
+ "shortDescription": "Generate arithmetic sequences",
+ "title": "Arithmetic Sequence",
+ "toolInfo": {
+ "description": "An arithmetic sequence is a sequence of numbers where the difference between each consecutive term is constant. This constant difference is called the common difference. Given the first term (aโ) and the common difference (d), each term can be found by adding the common difference to the previous term.",
+ "title": "What is an Arithmetic Sequence?"
+ }
+ },
+ "generate": {
+ "arithmeticSequenceOption": "Arithmetic sequence option",
+ "description": "Generate a sequence of numbers with customizable parameters.",
+ "numberOfElementsDescription": "Number of elements in sequence.",
+ "resultTitle": "Generated numbers",
+ "separator": "Separator",
+ "separatorDescription": "Separate elements in the arithmetic sequence by this character.",
+ "shortDescription": "Generate random numbers in specified ranges",
+ "startSequenceDescription": "Start sequence from this number.",
+ "stepDescription": "Increase each element by this amount",
+ "title": "Generate",
+ "toolInfo": {
+ "description": "This tool allows you to generate a sequence of numbers with customizable parameters. You can specify the starting value, step size, and number of elements.",
+ "title": "Generate numbers"
+ }
+ },
+ "ohmsLaw": {
+ "description": "Calculates voltage, current and resistance",
+ "longDescription": "This calculator applies Ohm's Law (V = I ร R) to determine any of the three electrical parameters when the other two are known. Ohm's Law is a fundamental principle in electrical engineering that describes the relationship between voltage (V), current (I), and resistance (R). This tool is essential for electronics hobbyists, electrical engineers, and students working with circuits to quickly solve for unknown values in their electrical designs.",
+ "shortDescription": "Calculate voltage, current, or resistance in electrical circuits using Ohm's Law",
+ "title": "Ohm's Law"
+ },
+ "slackline": {
+ "description": "Calculates tension in a slackline",
+ "longDescription": "This calculator assumes a load in the center of the rope",
+ "shortDescription": "Calculate the approximate tension of a slackline or clothesline. Do not rely on this for safety.",
+ "title": "Slackline Tension"
+ },
+ "sphereArea": {
+ "description": "Area of a Sphere",
+ "longDescription": "This calculator determines the surface area of a sphere using the formula A = 4ฯrยฒ. You can either input the radius to find the surface area or enter the surface area to calculate the required radius. This tool is useful for students studying geometry, engineers working with spherical objects, and anyone needing to perform calculations involving spherical surfaces.",
+ "shortDescription": "Calculate the surface area of a sphere based on its radius",
+ "title": "Area of a Sphere"
+ },
+ "sphereVolume": {
+ "description": "Volume of a Sphere",
+ "longDescription": "This calculator computes the volume of a sphere using the formula V = (4/3)ฯrยณ. You can input either the radius or diameter to find the volume, or enter the volume to determine the required radius. The tool is valuable for students, engineers, and professionals working with spherical objects in fields such as physics, engineering, and manufacturing.",
+ "shortDescription": "Calculate the volume of a sphere using radius or diameter",
+ "title": "Volume of a Sphere"
+ },
+ "sum": {
+ "description": "Calculate the sum of a list of numbers. Enter numbers separated by commas or newlines to get their total sum.",
+ "example1Description": "In this example, we calculate the sum of ten positive integers. These integers are listed as a column and their total sum equals 19494.",
+ "example1Title": "Sum of Ten Positive Numbers",
+ "example2Description": "This example reverses a column of twenty three-syllable nouns and prints all the words from the bottom to top. To separate the list items, it uses the \\n character as input item separator, which means that each item is on its own line.",
+ "example2Title": "Count Trees in the Park",
+ "example3Description": "In this example, we add together ninety different values โ positive numbers, negative numbers, integers and decimal fractions. We set the input separator to a comma and after adding all of them together, we get 0 as output.",
+ "example3Title": "Sum of Integers and Decimals",
+ "example4Description": "In this example, we calculate the sum of all ten digits and enable the option \"Print Running Sum\". We get the intermediate values of the sum in the process of addition. Thus, we have the following sequence in the output: 0, 1 (0 + 1), 3 (0 + 1 + 2), 6 (0 + 1 + 2 + 3), 10 (0 + 1 + 2 + 3 + 4), and so on.",
+ "example4Title": "Running Sum of Numbers",
+ "extractionTypes": {
+ "delimiter": {
+ "description": "Customize the number separator here. (By default a line break.)",
+ "title": "Number Delimiter"
+ },
+ "smart": {
+ "description": "Auto detect numbers in the input.",
+ "title": "Smart Sum"
+ }
+ },
+ "inputTitle": "Input",
+ "numberExtraction": "Number Extraction",
+ "printRunningSum": "Print Running Sum",
+ "printRunningSumDescription": "Display the sum as it's calculated step by step.",
+ "resultTitle": "Total",
+ "runningSum": "Running Sum",
+ "shortDescription": "Calculate sum of numbers",
+ "title": "Sum",
+ "toolInfo": {
+ "description": "This is an online browser-based utility for calculating the sum of a bunch of numbers. You can enter the numbers separated by a comma, space, or any other character, including the line break. You can also simply paste a fragment of textual data that contains numerical values that you want to sum up and the utility will extract them and find their sum.",
+ "title": "What Is a Number Sum Calculator?"
+ }
+ },
+ "voltageDropInWire": {
+ "description": "Calculates round trip voltage and power loss in a 2 conductor cable",
+ "longDescription": "This calculator helps determine the voltage drop and power loss in a two-conductor electrical cable. It takes into account the cable length, wire gauge (cross-sectional area), material resistivity, and current flow. The tool calculates the round-trip voltage drop, total resistance of the cable, and the power dissipated as heat. This is particularly useful for electrical engineers, electricians, and hobbyists when designing electrical systems to ensure voltage levels remain within acceptable limits at the load.",
+ "shortDescription": "Calculate voltage drop and power loss in electrical cables based on length, material, and current",
+ "title": "Round trip voltage drop in cable"
+ }
+}
diff --git a/public/locales/en/pdf.json b/public/locales/en/pdf.json
new file mode 100644
index 0000000..d6b2860
--- /dev/null
+++ b/public/locales/en/pdf.json
@@ -0,0 +1,114 @@
+{
+ "compressPdf": {
+ "compressedFileSize": "Compressed File Size",
+ "compressingPdf": "Compressing PDF...",
+ "compressionLevel": "Compression Level",
+ "compressionSettings": "Compression Settings",
+ "description": "Reduce PDF file size while maintaining quality using Ghostscript",
+ "errorCompressingPdf": "Failed to compress PDF: {{error}}",
+ "errorReadingPdf": "Failed to read PDF file. Please make sure it is a valid PDF.",
+ "fileSize": "Original File Size",
+ "highCompression": "High Compression",
+ "highCompressionDescription": "Maximum file size reduction with some quality loss",
+ "inputTitle": "Input PDF",
+ "longDescription": "Compress PDF files securely in your browser using Ghostscript. Your files never leave your device, ensuring complete privacy while reducing file sizes for email sharing, uploading to websites, or saving storage space. Powered by WebAssembly technology.",
+ "lowCompression": "Low Compression",
+ "lowCompressionDescription": "Slightly reduce file size with minimal quality loss",
+ "mediumCompression": "Medium Compression",
+ "mediumCompressionDescription": "Balance between file size and quality",
+ "pages": "Number of Pages",
+ "resultTitle": "Compressed PDF",
+ "shortDescription": "Compress PDF files securely in your browser",
+ "title": "Compress PDF"
+ },
+ "editor": {
+ "description": "Advanced PDF editor with annotation, form-fill, highlight, and export capabilities. Edit your PDFs directly in the browser with professional-grade tools including text insertion, drawing, highlighting, signing and form filling.",
+ "shortDescription": "Edit PDFs with advanced annotation, signing and editing tools",
+ "title": "PDF Editor"
+ },
+ "merge": {
+ "inputTitle": "Input PDF",
+ "loadingText": "Extracting pages",
+ "resultTitle": "Output merged PDF",
+ "toolInfo": {
+ "description": "This tool allows you to merge multiple PDF files into a single document. To use the tool, simply upload the PDF files you want to merge. The tool will then combine all pages from the input files into a single PDF document.",
+ "title": "How to Use the Merge PDF Tool?"
+ }
+ },
+ "mergePdf": {
+ "description": "Combine multiple PDF files into a single document.",
+ "inputTitle": "Input PDFs",
+ "mergingPdfs": "Merging PDFs",
+ "pdfOptions": "PDF Options",
+ "resultTitle": "Merged PDF",
+ "shortDescription": "Merge multiple PDF files into a single document",
+ "sortByFileName": "Sort by file name",
+ "sortByFileNameDescription": "Sort PDFs alphabetically by file name",
+ "sortByUploadOrder": "Sort by upload order",
+ "sortByUploadOrderDescription": "Keep PDFs in the order they were uploaded",
+ "title": "Merge PDF",
+ "toolInfo": {
+ "description": "This tool allows you to combine multiple PDF files into a single document. You can choose how to sort the PDFs and the tool will merge them in the specified order.",
+ "title": "Merge PDF Files"
+ }
+ },
+ "pdfToEpub": {
+ "description": "Transform PDF documents into EPUB files for better e-reader compatibility.', icon: 'material-symbols:import-contacts', component: lazy(() => import('./index')), keywords: ['pdf', 'epub', 'convert', 'ebook'], path: 'pdf-to-epub', i18n: { name: 'pdf:pdfToEpub.title', description: 'pdf:pdfToEpub.description",
+ "shortDescription": "Convert PDF files to EPUB format",
+ "title": "PDF to EPUB"
+ },
+ "pdfToPng": {
+ "description": "Transform PDF documents into PNG panels.",
+ "longDescription": "Upload a PDF and convert each page into a high-quality PNG image directly in your browser. This tool is ideal for extracting visual content or sharing individual pages. No data is uploaded โ everything runs locally.",
+ "shortDescription": "Convert PDF into PNG images",
+ "title": "PDF to PNG"
+ },
+ "protectPdf": {
+ "description": "Add password protection to your PDF files securely in your browser",
+ "shortDescription": "Password protect PDF files securely",
+ "title": "Protect PDF"
+ },
+ "rotatePdf": {
+ "allPagesWillBeRotated": "All {{count}} pages will be rotated",
+ "angleOptions": {
+ "clockwise90": "90ยฐ Clockwise",
+ "counterClockwise270": "270ยฐ (90ยฐ Counter-clockwise)",
+ "upsideDown180": "180ยฐ (Upside down)"
+ },
+ "applyToAllPages": "Apply to all pages",
+ "description": "Rotate pages in a PDF document.",
+ "inputTitle": "Input PDF",
+ "longDescription": "Change the orientation of PDF pages by rotating them 90, 180, or 270 degrees. Useful for fixing incorrectly scanned documents or preparing PDFs for printing.",
+ "pageRangesDescription": "Enter page numbers or ranges separated by commas (e.g., 1,3,5-7)",
+ "pageRangesPlaceholder": "e.g., 1,5-8",
+ "pagesWillBeRotated": "{{count}} page{{count !== 1 ? 's' : ''}} will be rotated",
+ "pdfPageCount": "PDF has {{count}} page{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "Rotated PDF",
+ "rotatingPages": "Rotating pages",
+ "rotationAngle": "Rotation Angle",
+ "rotationSettings": "Rotation Settings",
+ "shortDescription": "Rotate pages in a PDF document",
+ "title": "Rotate PDF",
+ "toolInfo": {
+ "description": "This tool allows you to rotate pages in a PDF document. You can rotate all pages or specify individual pages to rotate. Choose a rotation angle: 90ยฐ Clockwise, 180ยฐ (Upside down), or 270ยฐ (90ยฐ Counter-clockwise). To rotate specific pages, uncheck \"Apply to all pages\" and enter page numbers or ranges separated by commas (e.g., 1,3,5-7).",
+ "title": "How to Use the Rotate PDF Tool"
+ }
+ },
+ "splitPdf": {
+ "description": "Extract specific pages from a PDF document.",
+ "extractingPages": "Extracting pages",
+ "inputTitle": "Input PDF",
+ "pageExtractionPreview": "{{count}} page{{count !== 1 ? 's' : ''}} will be extracted",
+ "pageRangesDescription": "Enter page numbers or ranges separated by commas (e.g., 1,3,5-7)",
+ "pageRangesPlaceholder": "e.g., 1,5-8",
+ "pageSelection": "Page Selection",
+ "pdfPageCount": "PDF has {{count}} page{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "Extracted PDF",
+ "shortDescription": "Extract specific pages from a PDF file",
+ "title": "Split PDF",
+ "toolInfo": {
+ "description": "This tool allows you to extract specific pages from a PDF document. You can specify individual pages or ranges of pages to extract.",
+ "title": "Split PDF"
+ }
+ }
+}
diff --git a/public/locales/en/string.json b/public/locales/en/string.json
new file mode 100644
index 0000000..142f8b9
--- /dev/null
+++ b/public/locales/en/string.json
@@ -0,0 +1,261 @@
+{
+ "base64": {
+ "decode": "Base64 Decode",
+ "description": "Encode or decode text using Base64 encoding.",
+ "encode": "Base64 Encode",
+ "inputTitle": "Input Data",
+ "optionsTitle": "Base64 Options",
+ "resultTitle": "Result",
+ "shortDescription": "Encode or decode data using Base64.",
+ "title": "Base64 Encoder/Decoder",
+ "toolInfo": {
+ "description": "Base64 is an encoding scheme that represents data in an ASCII string format by translating it into a radix-64 representation. Although it can be used to encode strings, it is commonly used to encode binary data for transmission over media that are designed to deal with textual data.",
+ "title": "What is Base64?"
+ }
+ },
+ "censor": {
+ "description": "utility for censoring words in text. Load your text in the input form on the left, specify all the bad words in the options, and you'll instantly get censored text in the output area.\", longDescription: 'With this online tool, you can censor certain words in any text. You can specify a list of unwanted words (such as swear words or secret words) and the program will replace them with alternative words and create a safe-to-read text. The words can be specified in a multi-line text field in the options by entering one word per line.', keywords: ['text', 'censor', 'words', 'characters'], component: lazy(() => import('./index')), i18n: { name: 'string:censor.title', description: 'string:censor.description",
+ "shortDescription": "Quickly mask bad words or replace them with alternative words.",
+ "title": "Text Censor"
+ },
+ "createPalindrome": {
+ "description": "World's simplest browser-based utility for creating palindromes from any text. Input text and instantly transform it into a palindrome that reads the same forward and backward. Perfect for word games, creating symmetrical text patterns, or exploring linguistic curiosities.",
+ "shortDescription": "Create text that reads the same forward and backward",
+ "title": "Create palindrome"
+ },
+ "extractSubstring": {
+ "description": "World's simplest browser-based utility for extracting substrings from text. Input your text and specify start and end positions to extract the desired portion. Perfect for data processing, text analysis, or extracting specific content from larger text blocks.",
+ "shortDescription": "Extract a portion of text between specified positions",
+ "title": "Extract substring"
+ },
+ "join": {
+ "blankLinesAndTrailingSpaces": "Blank Lines and Trailing Spaces",
+ "deleteBlankDescription": "Delete lines that don't have text symbols.",
+ "deleteBlankTitle": "Delete Blank Lines",
+ "deleteTrailingDescription": "Remove spaces and tabs at the end of the lines.",
+ "deleteTrailingTitle": "Delete Trailing Spaces",
+ "description": "Join text pieces together with customizable separators.",
+ "inputTitle": "Text Pieces",
+ "joinCharacterDescription": "Symbol that connects broken pieces of text. (Space by default.)",
+ "joinCharacterPlaceholder": "Join Character",
+ "resultTitle": "Joined Text",
+ "shortDescription": "Join text elements with a specified separator",
+ "textMergedOptions": "Text Merged Options",
+ "title": "Join Text",
+ "toolInfo": {
+ "description": "With this tool you can join parts of the text together. It takes a list of text values, separated by newlines, and merges them together. You can set the character that will be placed between the parts of the combined text. Also, you can ignore all empty lines and remove spaces and tabs at the end of all lines. Textabulous!",
+ "title": "What Is a Text Joiner?"
+ }
+ },
+ "palindrome": {
+ "description": "World's simplest browser-based utility for checking if text is a palindrome. Instantly verify if your text reads the same forward and backward. Perfect for word puzzles, linguistic analysis, or validating symmetrical text patterns. Supports various delimiters and multi-word palindrome detection.",
+ "shortDescription": "Check if text reads the same forward and backward",
+ "title": "Palindrome"
+ },
+ "passwordGenerator": {
+ "avoidAmbiguous": "Avoid ambiguous characters (i, I, l, 0, O)",
+ "description": "Generate secure random passwords with customizable length and character types. Choose from lowercase, uppercase, numbers, and special characters. Option to avoid ambiguous characters for better readability.",
+ "includeLowercase": "Include lowercase letters (a-z)",
+ "includeNumbers": "Include numbers (0-9)",
+ "includeSymbols": "Include special characters",
+ "includeUppercase": "Include uppercase letters (A-Z)",
+ "lengthDesc": "Length of the password",
+ "lengthPlaceholder": "e.g. 12",
+ "optionsTitle": "Password Options",
+ "resultTitle": "Generated Password",
+ "shortDescription": "Generate secure random passwords with custom options",
+ "title": "Password Generator",
+ "toolInfo": {
+ "description": "This tool generates secure random passwords based on your selected criteria. You can customize the length, include or exclude different character types, and avoid ambiguous characters for better readability. Perfect for creating strong passwords for accounts, applications, or any security needs.",
+ "title": "About Password Generator"
+ }
+ },
+ "quote": {
+ "allowDoubleQuotation": "Allow double quotation",
+ "description": "Add quotes around text with customizable options.",
+ "inputTitle": "Input Text",
+ "leftQuoteDescription": "Left quote character(s)",
+ "processAsMultiLine": "Process as multi-line text",
+ "quoteEmptyLines": "Quote empty lines",
+ "quoteOptions": "Quote Options",
+ "resultTitle": "Quoted Text",
+ "rightQuoteDescription": "Right quote character(s)",
+ "shortDescription": "Add quotes around text with various styles",
+ "title": "Text Quoter",
+ "toolInfo": {
+ "description": "This tool allows you to add quotes around text. You can choose different quote characters, handle multi-line text, and control how empty lines are processed. It's useful for preparing text for programming, formatting data, or creating stylized text.",
+ "title": "Text Quoter"
+ }
+ },
+ "randomizeCase": {
+ "description": "World's simplest browser-based utility for randomizing text case. Input your text and instantly transform it with random upper and lower case letters. Perfect for creating unique text effects, testing case sensitivity, or generating varied text patterns.",
+ "shortDescription": "Randomize the case of letters in text",
+ "title": "Randomize case"
+ },
+ "removeDuplicateLines": {
+ "description": "Load your text in the input form on the left and you'll instantly get text with no duplicate lines in the output area. Powerful, free, and fast. Load text lines โ get unique text lines",
+ "shortDescription": "Quickly delete all repeated lines from text",
+ "title": "Remove duplicate lines"
+ },
+ "repeat": {
+ "delimiterDescription": "Delimiter for output copies.",
+ "delimiterPlaceholder": "Delimiter",
+ "description": "Repeat text multiple times with customizable separators.",
+ "inputTitle": "Input text",
+ "numberPlaceholder": "Number",
+ "repeatAmountDescription": "Number of repetitions.",
+ "repetitionsDelimiter": "Repetitions Delimiter",
+ "resultTitle": "Repeated text",
+ "shortDescription": "Repeat text multiple times",
+ "textRepetitions": "Text Repetitions",
+ "title": "Repeat Text",
+ "toolInfo": {
+ "description": "This tool allows you to repeat a given text multiple times with an optional separator.",
+ "title": "Repeat text"
+ }
+ },
+ "reverse": {
+ "description": "World's simplest browser-based utility for reversing text. Input any text and get it instantly reversed, character by character. Perfect for creating mirror text, analyzing palindromes, or playing with text patterns. Preserves spaces and special characters while reversing.",
+ "inputTitle": "Text to reverse",
+ "processMultiLine": "Process multi-line text",
+ "processMultiLineDescription": "Each line will be reversed independently",
+ "resultTitle": "Reversed text",
+ "reversalOptions": "Reversal options",
+ "shortDescription": "Reverse any text character by character",
+ "skipEmptyLines": "Skip empty lines",
+ "skipEmptyLinesDescription": "Empty lines will be removed from the output",
+ "title": "Reverse",
+ "trimWhitespace": "Trim whitespace",
+ "trimWhitespaceDescription": "Remove leading and trailing whitespace from each line"
+ },
+ "rot13": {
+ "description": "Encode or decode text using ROT13 cipher.",
+ "inputTitle": "Input Text",
+ "resultTitle": "ROT13 Result",
+ "shortDescription": "Encode or decode text using ROT13 cipher.",
+ "title": "ROT13 Encoder/Decoder",
+ "toolInfo": {
+ "description": "ROT13 (rotate by 13 places) is a simple letter substitution cipher that replaces a letter with the 13th letter after it in the alphabet. ROT13 is a special case of the Caesar cipher which was developed in ancient Rome. Because there are 26 letters in the English alphabet, ROT13 is its own inverse; that is, to undo ROT13, the same algorithm is applied, so the same action can be used for encoding and decoding.",
+ "title": "What Is ROT13?"
+ }
+ },
+ "rotate": {
+ "description": "Rotate characters in text by specified positions.",
+ "inputTitle": "Input Text",
+ "processAsMultiLine": "Process as multi-line text (rotate each line separately)",
+ "resultTitle": "Rotated Text",
+ "rotateLeft": "Rotate Left",
+ "rotateRight": "Rotate Right",
+ "rotationOptions": "Rotation Options",
+ "shortDescription": "Shift characters in text by position.",
+ "stepDescription": "Number of positions to rotate",
+ "title": "Rotate Text",
+ "toolInfo": {
+ "description": "This tool allows you to rotate characters in a string by a specified number of positions. You can rotate to the left or right, and process multi-line text by rotating each line separately. String rotation is useful for simple text transformations, creating patterns, or implementing basic encryption techniques.",
+ "title": "String Rotation"
+ }
+ },
+ "split": {
+ "charAfterChunkDescription": "Character after each chunk",
+ "charBeforeChunkDescription": "Character before each chunk",
+ "chunksDescription": "Number of chunks of equal length in the output.",
+ "chunksTitle": "Use a Number of Chunks",
+ "description": "World's simplest browser-based utility for splitting text. Input your text and specify a separator to split it into multiple parts. Perfect for data processing, text manipulation, or extracting specific content from larger text blocks.",
+ "lengthDescription": "Number of characters that will be put in each output chunk.",
+ "lengthTitle": "Use Length for Splitting",
+ "outputSeparatorDescription": "Character that will be put between the split chunks. (It's newline \"\\n\" by default.)",
+ "outputSeparatorOptions": "Output Separator Options",
+ "regexDescription": "Regular expression that will be used to break text into parts. (Multiple spaces by default.)",
+ "regexTitle": "Use a Regex for Splitting",
+ "resultTitle": "Split Result",
+ "shortDescription": "Split text into multiple parts using a separator",
+ "splitSeparatorOptions": "Split separator options",
+ "symbolDescription": "Character that will be used to break text into parts. (Space by default.)",
+ "symbolTitle": "Use a Symbol for Splitting",
+ "title": "Split"
+ },
+ "statistic": {
+ "characterFrequencyAnalysis": "Character Frequency Analysis",
+ "characterFrequencyAnalysisDescription": "Count how often each character appears in the text",
+ "delimitersOptions": "Delimiters Options",
+ "description": "Analyze text and generate comprehensive statistics.",
+ "includeEmptyLines": "Include Empty Lines",
+ "includeEmptyLinesDescription": "Include blank lines when counting lines",
+ "inputTitle": "Input text",
+ "resultTitle": "Text Statistics",
+ "sentenceDelimitersDescription": "Enter custom characters used to delimit sentences in your language (separated by comma) or leave it blank for default.",
+ "sentenceDelimitersPlaceholder": "e.g. ., !, ?, ...",
+ "shortDescription": "Get statistics about your text",
+ "statisticsOptions": "Statistics Options",
+ "title": "Text Statistics",
+ "toolInfo": {
+ "description": "This tool allows you to analyze text and generate comprehensive statistics including character count, word count, line count, and frequency analysis of characters and words.",
+ "title": "What is a {{title}}?"
+ },
+ "wordDelimitersDescription": "Enter custom Regex to count Words or leave it blank for default.",
+ "wordDelimitersPlaceholder": "eg. \\s.,;:!?\"ยซยป()โฆ",
+ "wordFrequencyAnalysis": "Word Frequency Analysis",
+ "wordFrequencyAnalysisDescription": "Count how often each word appears in the text"
+ },
+ "textReplacer": {
+ "description": "Replace text patterns with new content.",
+ "findPatternInText": "Find This Pattern in Text",
+ "findPatternUsingRegexp": "Find a Pattern Using a RegExp",
+ "inputTitle": "Text to replace",
+ "newTextPlaceholder": "New text",
+ "regexpDescription": "Enter the regular expression that you want to replace.",
+ "replacePatternDescription": "Enter the pattern to use for replacement.",
+ "replaceText": "Replace Text",
+ "resultTitle": "Text with replacements",
+ "searchPatternDescription": "Enter the text pattern that you want to replace.",
+ "searchText": "Search text",
+ "shortDescription": "Quickly replace text in your content",
+ "title": "Text Replacer",
+ "toolInfo": {
+ "description": "Easily replace specific text in your content with this simple, browser-based tool. Just input your text, set the text you want to replace and the replacement value, and instantly get the updated version.",
+ "title": "Text Replacer"
+ }
+ },
+ "toMorse": {
+ "dashSymbolDescription": "Symbol that will correspond to the dash in Morse code.",
+ "description": "Convert text to Morse code.",
+ "dotSymbolDescription": "Symbol that will correspond to the dot in Morse code.",
+ "longSignal": "Long Signal",
+ "resultTitle": "Morse code",
+ "shortDescription": "Quickly encode text to morse",
+ "shortSignal": "Short Signal",
+ "title": "String To morse"
+ },
+ "truncate": {
+ "addTruncationIndicator": "Add Truncation Indicator",
+ "charactersPlaceholder": "Characters",
+ "description": "Shorten text to a specified length.",
+ "indicatorDescription": "Characters to add at the end (or start) of the text. Note: They count towards the length.",
+ "inputTitle": "Input text",
+ "leftSideDescription": "Remove characters from the start of the text.",
+ "leftSideTruncation": "Left-side Truncation",
+ "lengthAndLines": "Length and Lines",
+ "lineByLineDescription": "Truncate each line separately.",
+ "lineByLineTruncating": "Line-by-line Truncating",
+ "maxLengthDescription": "Number of characters to leave in the text.",
+ "numberPlaceholder": "Number",
+ "resultTitle": "Truncated text",
+ "rightSideDescription": "Remove characters from the end of the text.",
+ "rightSideTruncation": "Right-side Truncation",
+ "shortDescription": "Truncate text to a specified length",
+ "suffixAndAffix": "Suffix and Affix",
+ "title": "Truncate Text",
+ "toolInfo": {
+ "description": "Load your text in the input form on the left and you will automatically get truncated text on the right.",
+ "title": "Truncate text"
+ },
+ "truncationSide": "Truncation Side"
+ },
+ "uppercase": {
+ "description": "Convert text to uppercase letters.",
+ "inputTitle": "Input text",
+ "resultTitle": "Uppercase text",
+ "shortDescription": "Convert text to uppercase",
+ "title": "Convert to Uppercase"
+ }
+}
diff --git a/public/locales/en/time.json b/public/locales/en/time.json
new file mode 100644
index 0000000..3b3e93a
--- /dev/null
+++ b/public/locales/en/time.json
@@ -0,0 +1,102 @@
+{
+ "checkLeapYears": {
+ "description": "Check if a year is a leap year and get leap year information.",
+ "exampleDescription": "One of our friends was born on a leap year on February 29th and as a consequence, she has a birthday only once every 4 years. As we can never really remember when her birthday is, we are using our program to create a reminder list of the upcoming leap years. To create a list of her next birthdays, we load a sequence of years from 2025 to 2040 into the input and get the status of each year. If the program says that it's a leap year, then we know that we'll be invited to a birthday party on February 29th.",
+ "exampleTitle": "Find Birthdays on February 29",
+ "inputTitle": "Input year",
+ "resultTitle": "Leap year result",
+ "shortDescription": "Check if a year is a leap year",
+ "title": "Check Leap Years",
+ "toolInfo": {
+ "description": "A leap year is a year containing one additional day (February 29) to keep the calendar year synchronized with the astronomical year. Leap years occur every 4 years, except for years that are divisible by 100 but not by 400.",
+ "title": "What is a Leap Year?"
+ }
+ },
+ "convertDaysToHours": {
+ "addHoursName": "Add Hours Name",
+ "addHoursNameDescription": "Append the string hours to output values",
+ "description": "Convert days to hours with customizable options.",
+ "hoursName": "Hours Name",
+ "shortDescription": "Convert days to hours",
+ "title": "Convert Days to Hours",
+ "toolInfo": {
+ "description": "This tool allows you to convert days to hours. You can input days as numbers or with units, and the tool will convert them to hours. You can also choose to append the 'hours' suffix to the output values.",
+ "title": "Convert Days to Hours"
+ }
+ },
+ "convertHoursToDays": {
+ "addDaysName": "Add Days Name",
+ "addDaysNameDescription": "Append the string days to output values",
+ "daysName": "Days Name",
+ "description": "Convert hours to days with customizable options.",
+ "shortDescription": "Convert hours to days",
+ "title": "Convert Hours to Days",
+ "toolInfo": {
+ "description": "This tool allows you to convert hours to days. You can input hours as numbers or with units, and the tool will convert them to days. You can also choose to append the 'days' suffix to the output values.",
+ "title": "Convert Hours to Days"
+ }
+ },
+ "convertSecondsToTime": {
+ "addPadding": "Add Padding",
+ "addPaddingDescription": "Add zero padding to hours, minutes, and seconds.",
+ "description": "Convert seconds to a readable time format (hours:minutes:seconds). Enter the number of seconds to get the formatted time.",
+ "shortDescription": "Convert seconds to time format",
+ "timePadding": "Time Padding",
+ "title": "Convert Seconds to Time",
+ "toolInfo": {
+ "title": "What is a {{title}}?"
+ }
+ },
+ "convertTimeToSeconds": {
+ "description": "Convert formatted time (HH:MM:SS) to seconds.",
+ "inputTitle": "Input time",
+ "resultTitle": "Seconds",
+ "shortDescription": "Convert time format to seconds",
+ "title": "Convert Time to Seconds",
+ "toolInfo": {
+ "description": "This tool allows you to convert formatted time strings (HH:MM:SS) to seconds. It's useful for calculating durations and time intervals.",
+ "title": "Convert Time to Seconds"
+ }
+ },
+ "crontabGuru": {
+ "description": "Generate and understand cron expressions. Create cron schedules for automated tasks and system jobs.",
+ "shortDescription": "Generate and understand cron expressions",
+ "title": "Crontab Guru"
+ },
+ "timeBetweenDates": {
+ "description": "Calculate the time difference between two dates. Get the exact duration in days, hours, minutes, and seconds.",
+ "endDate": "End Date",
+ "endDateTime": "End Date & Time",
+ "endTime": "End Time",
+ "endTimezone": "End Timezone",
+ "shortDescription": "Calculate time between two dates",
+ "startDate": "Start Date",
+ "startDateTime": "Start Date & Time",
+ "startTime": "Start Time",
+ "startTimezone": "Start Timezone",
+ "title": "Time Between Dates",
+ "toolInfo": {
+ "description": "Calculate the exact time difference between two dates and times, with support for different timezones. This tool provides a detailed breakdown of the time difference in various units (years, months, days, hours, minutes, and seconds).",
+ "title": "Time Between Dates Calculator"
+ }
+ },
+ "truncateClockTime": {
+ "description": "Truncate clock time to remove seconds or minutes. Round time to the nearest hour, minute, or custom interval.",
+ "printDroppedComponents": "Print Dropped Components",
+ "shortDescription": "Truncate clock time to specified precision",
+ "timePadding": "Time Padding",
+ "title": "Truncate Clock Time",
+ "toolInfo": {
+ "title": "What is a {{title}}?"
+ },
+ "truncateMinutesAndSeconds": "Truncate Minutes and Seconds",
+ "truncateMinutesAndSecondsDescription": "Drop both โ the minutes and seconds components from each clock time.",
+ "truncateOnlySeconds": "Truncate Only Seconds",
+ "truncateOnlySecondsDescription": "Drop the seconds component from each clock time.",
+ "truncationSide": "Truncation Side",
+ "useZeroPadding": "Use Zero Padding",
+ "zeroPaddingDescription": "Make all time components always be two digits wide.",
+ "zeroPrintDescription": "Display the dropped parts as zero values \"00\".",
+ "zeroPrintTruncatedParts": "Zero-print Truncated Parts"
+ }
+}
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
new file mode 100644
index 0000000..789e161
--- /dev/null
+++ b/public/locales/en/translation.json
@@ -0,0 +1,250 @@
+{
+ "audio": {
+ "changeSpeed": {
+ "description": "Change the playback speed of audio files. Speed up or slow down audio while maintaining pitch.",
+ "name": "Change audio speed",
+ "shortDescription": "Change the speed of audio files"
+ },
+ "extractAudio": {
+ "description": "Extract the audio track from a video file and save it as a separate audio file in your chosen format (AAC, MP3, WAV).",
+ "name": "Extract audio",
+ "shortDescription": "Extract audio from video files (MP4, MOV, etc.) to AAC, MP3, or WAV."
+ }
+ },
+ "baseFileInput": {
+ "copyFailed": "Failed to copy: {{error}}",
+ "dropFileHere": "Drop your {{type}} here",
+ "fileCopied": "File copied",
+ "selectFileDescription": "Click here to select a {{type}} from your device, press Ctrl+V to use a {{type}} from your clipboard, or drag and drop a file from desktop"
+ },
+ "categories": {
+ "audio": {
+ "description": "Tools for working with audio โ extract audio from video, adjusting audio speed, merging multiple audio files and much more.",
+ "title": "Audio Tools"
+ },
+ "csv": {
+ "description": "Tools for working with CSV files - convert CSV to different formats, manipulate CSV data, validate CSV structure, and process CSV files efficiently.",
+ "title": "CSV Tools"
+ },
+ "gif": {
+ "description": "Tools for working with GIF animations โ create transparent GIFs, extract GIF frames, add text to GIF, crop, rotate, reverse GIFs, and much more.",
+ "title": "GIF Tools"
+ },
+ "image-generic": {
+ "description": "Tools for working with pictures โ compress, resize, crop, convert to JPG, rotate, remove background and much more.",
+ "title": "Image Tools"
+ },
+ "json": {
+ "description": "Tools for working with JSON data structures โ prettify and minify JSON objects, flatten JSON arrays, stringify JSON values, analyze data, and much more",
+ "title": "JSON Tools"
+ },
+ "list": {
+ "description": "Tools for working with lists โ sort, reverse, randomize lists, find unique and duplicate list items, change list item separators, and much more.",
+ "title": "List Tools"
+ },
+ "number": {
+ "description": "Tools for working with numbers โ generate number sequences, convert numbers to words and words to numbers, sort, round, factor numbers, and much more.",
+ "title": "Number Tools"
+ },
+ "pdf": {
+ "description": "Tools for working with PDF files - extract text from PDFs, convert PDFs to other formats, manipulate PDFs, and much more.",
+ "title": "PDF Tools"
+ },
+ "png": {
+ "description": "Tools for working with PNG images โ convert PNGs to JPGs, create transparent PNGs, change PNG colors, crop, rotate, resize PNGs, and much more.",
+ "title": "PNG Tools"
+ },
+ "seeAll": "See all {{title}}",
+ "string": {
+ "description": "Tools for working with text โ convert text to images, find and replace text, split text into fragments, join text lines, repeat text, and much more.",
+ "title": "Text Tools"
+ },
+ "time": {
+ "description": "Tools for working with time and date โ calculate time differences, convert between time zones, format dates, generate date sequences, and much more.",
+ "title": "Time Tools"
+ },
+ "try": "Try {{title}}",
+ "video": {
+ "description": "Tools for working with videos โ extract frames from videos, create GIFs from videos, convert videos to different formats, and much more.",
+ "title": "Video Tools"
+ },
+ "xml": {
+ "description": "Tools for working with XML data structures - viewer, beautifier, validator and much more",
+ "title": "XML Tools"
+ }
+ },
+ "csv": {
+ "findIncompleteCsvRecords": {
+ "description": "Just upload your CSV file in the form below and this tool will automatically check if none of the rows or columns are missing values. In the tool options, you can adjust the input file format (specify the delimiter, quote character, and comment character). Additionally, you can enable checking for empty values, skip empty lines, and set a limit on the number of error messages in the output.",
+ "name": "Find incomplete CSV records",
+ "shortDescription": "Quickly find rows and columns in CSV that are missing values."
+ }
+ },
+ "hero": {
+ "brand": "OmniTools",
+ "description": "Boost your productivity with OmniTools, the ultimate toolkit for getting things done quickly! Access thousands of user-friendly utilities for editing images, text, lists, and data, all directly from your browser.",
+ "examples": {
+ "calculateNumberSum": "Calculate number sum",
+ "changeGifSpeed": "Change GIF speed",
+ "compressPng": "Compress PNG",
+ "createTransparentImage": "Create a transparent image",
+ "prettifyJson": "Prettify JSON",
+ "sortList": "Sort a list",
+ "splitPdf": "Split PDF",
+ "splitText": "Split a text",
+ "trimVideo": "Trim video"
+ },
+ "searchPlaceholder": "Search all tools",
+ "title": "Get Things Done Quickly with"
+ },
+ "inputFooter": {
+ "clear": "Clear",
+ "copyToClipboard": "Copy to clipboard",
+ "importFromFile": "Import from file"
+ },
+ "list": {
+ "group": {
+ "description": "World's simplest browser-based utility for grouping list items. Input your list and specify grouping criteria to organize items into logical groups. Perfect for categorizing data, organizing information, or creating structured lists. Supports custom separators and various grouping options.",
+ "name": "Group",
+ "shortDescription": "Group list items by common properties"
+ },
+ "reverse": {
+ "description": "This is a super simple browser-based application prints all list items in reverse. The input items can be separated by any symbol and you can also change the separator of the reversed list items.",
+ "name": "Reverse",
+ "shortDescription": "Quickly reverse a list"
+ },
+ "sort": {
+ "description": "This is a super simple browser-based application that sorts items in a list and arranges them in increasing or decreasing order. You can sort the items alphabetically, numerically, or by their length. You can also remove duplicate and empty items, as well as trim individual items that have whitespace around them. You can use any separator character to separate the input list items or alternatively use a regular expression to separate them. Additionally, you can create a new delimiter for the sorted output list.",
+ "name": "Sort",
+ "shortDescription": "Quickly sort a list"
+ }
+ },
+ "navbar": {
+ "buyMeACoffee": "Buy me a coffee",
+ "home": "Home",
+ "tools": "Tools"
+ },
+ "number": {
+ "generate": {
+ "description": "Quickly calculate a list of integers in your browser. To get your list, just specify the first integer, change value and total count in the options below, and this utility will generate that many integers",
+ "name": "Generate numbers",
+ "shortDescription": "Quickly calculate a list of integers in your browser"
+ },
+ "sum": {
+ "description": "This is a super simple browser-based application that sums numbers. The input numbers can be separated by any symbol and you can also change the separator of the summed numbers.",
+ "name": "Sum numbers",
+ "shortDescription": "Quickly sum a list of numbers"
+ }
+ },
+ "numericInputWithUnit": {
+ "unit": "Unit"
+ },
+ "pdf": {
+ "compressPdf": {
+ "description": "Reduce PDF file size while maintaining quality using Ghostscript",
+ "name": "Compress PDF",
+ "shortDescription": "Compress PDF files securely in your browser"
+ },
+ "mergePdf": {
+ "description": "Combine multiple PDF files into a single document.",
+ "name": "Merge PDF",
+ "shortDescription": "Merge multiple PDF files into a single document"
+ },
+ "pdfToEpub": {
+ "description": "Transform PDF documents into EPUB files for better e-reader compatibility.",
+ "name": "PDF to EPUB",
+ "shortDescription": "Convert PDF files to EPUB format"
+ },
+ "protectPdf": {
+ "description": "Add password protection to your PDF files securely in your browser",
+ "name": "Protect PDF",
+ "shortDescription": "Password protect PDF files securely"
+ },
+ "splitPdf": {
+ "description": "Extract specific pages from a PDF file using page numbers or ranges (e.g., 1,5-8)",
+ "name": "Split PDF",
+ "shortDescription": "Extract specific pages from a PDF file"
+ }
+ },
+ "resultFooter": {
+ "copy": "Copy to clipboard",
+ "download": "Download"
+ },
+ "string": {
+ "createPalindrome": {
+ "description": "World's simplest browser-based utility for creating palindromes from any text. Input text and instantly transform it into a palindrome that reads the same forward and backward. Perfect for word games, creating symmetrical text patterns, or exploring linguistic curiosities.",
+ "name": "Create palindrome",
+ "shortDescription": "Create text that reads the same forward and backward"
+ },
+ "palindrome": {
+ "description": "World's simplest browser-based utility for checking if text is a palindrome. Instantly verify if your text reads the same forward and backward. Perfect for word puzzles, linguistic analysis, or validating symmetrical text patterns. Supports various delimiters and multi-word palindrome detection.",
+ "name": "Palindrome",
+ "shortDescription": "Check if text reads the same forward and backward"
+ },
+ "repeat": {
+ "description": "This tool allows you to repeat a given text multiple times with an optional separator.",
+ "name": "Repeat text",
+ "shortDescription": "Repeat text multiple times"
+ },
+ "reverse": {
+ "description": "World's simplest browser-based utility for reversing text. Input any text and get it instantly reversed, character by character. Perfect for creating mirror text, analyzing palindromes, or playing with text patterns. Preserves spaces and special characters while reversing.",
+ "name": "Reverse",
+ "shortDescription": "Reverse any text character by character"
+ },
+ "toMorse": {
+ "description": "World's simplest browser-based utility for converting text to Morse code. Load your text in the input form on the left and you'll instantly get Morse code in the output area. Powerful, free, and fast. Load text โ get Morse code.",
+ "name": "String To morse",
+ "shortDescription": "Quickly encode text to morse"
+ },
+ "uppercase": {
+ "description": "World's simplest browser-based utility for converting text to uppercase. Just input your text and it will be automatically converted to all capital letters. Perfect for creating headlines, emphasizing text, or standardizing text format. Supports various text formats and preserves special characters.",
+ "name": "Uppercase",
+ "shortDescription": "Convert text to uppercase letters"
+ }
+ },
+ "toolExamples": {
+ "subtitle": "Click to try!",
+ "title": "{{title}} Examples"
+ },
+ "toolFileResult": {
+ "copied": "File copied",
+ "copyFailed": "Failed to copy: {{error}}",
+ "loading": "Loading... This may take a moment.",
+ "result": "Result"
+ },
+ "toolHeader": {
+ "seeExamples": "See Examples"
+ },
+ "toolLayout": {
+ "allToolsTitle": "All {{type}}"
+ },
+ "toolMultiFileResult": {
+ "copied": "File copied",
+ "copyFailed": "Failed to copy: {{error}}",
+ "loading": "Loading... This may take a moment.",
+ "result": "Result"
+ },
+ "toolMultipleAudioInput": {
+ "inputTitle": "Input {{type}}",
+ "noFilesSelected": "No files selected"
+ },
+ "toolMultiplePdfInput": {
+ "inputTitle": "Input {{type}}",
+ "noFilesSelected": "No files selected"
+ },
+ "toolOptions": {
+ "title": "Tool options"
+ },
+ "toolTextInput": {
+ "copied": "Text copied",
+ "copyFailed": "Failed to copy: {{error}}",
+ "input": "Input text",
+ "placeholder": "Enter your text here..."
+ },
+ "toolTextResult": {
+ "copied": "Text copied",
+ "copyFailed": "Failed to copy: {{error}}",
+ "loading": "Loading... This may take a moment.",
+ "result": "Result"
+ }
+}
diff --git a/public/locales/en/video.json b/public/locales/en/video.json
new file mode 100644
index 0000000..7419941
--- /dev/null
+++ b/public/locales/en/video.json
@@ -0,0 +1,120 @@
+{
+ "changeSpeed": {
+ "defaultMultiplier": "Default multiplier: 2 means 2x faster",
+ "description": "Change the playback speed of video files. Speed up or slow down videos while maintaining audio synchronization. Supports various speed multipliers and common video formats.",
+ "inputTitle": "Input Video",
+ "newVideoSpeed": "New Video Speed",
+ "resultTitle": "Edited Video",
+ "settingSpeed": "Setting Speed",
+ "shortDescription": "Change video playback speed",
+ "title": "Change Video Speed",
+ "toolInfo": {
+ "title": "What is a {{title}}?"
+ }
+ },
+ "compress": {
+ "default": "Default",
+ "description": "Compress videos by scaling them to different resolutions like 240p, 480p, 720p, etc. This tool helps reduce file size while maintaining acceptable quality. Supports common video formats like MP4, WebM, and OGG.",
+ "inputTitle": "Input Video",
+ "loadingText": "Compressing video...",
+ "lossless": "Lossless",
+ "quality": "Quality (CRF)",
+ "resolution": "Resolution",
+ "resultTitle": "Compressed Video",
+ "shortDescription": "Compress videos by scaling to different resolutions",
+ "title": "Compress Video",
+ "worst": "Worst"
+ },
+ "cropVideo": {
+ "cropCoordinates": "Crop Coordinates",
+ "croppingVideo": "Cropping Video",
+ "description": "Crop video to remove unwanted areas.",
+ "errorBeyondHeight": "Crop area extends beyond video height ({{height}}px)",
+ "errorBeyondWidth": "Crop area extends beyond video width ({{width}}px)",
+ "errorCroppingVideo": "Error cropping video. Please check parameters and video file.",
+ "errorLoadingDimensions": "Failed to load video dimensions",
+ "errorNonNegativeCoordinates": "X and Y coordinates must be non-negative",
+ "errorPositiveDimensions": "Width and height must be positive",
+ "height": "Height",
+ "inputTitle": "Input Video",
+ "loadVideoForDimensions": "Load a video to see dimensions",
+ "resultTitle": "Cropped Video",
+ "shortDescription": "Crop video to remove unwanted areas",
+ "longDescription": "This tool allows you to crop video files to remove unwanted areas or focus on specific parts of the video. Useful for removing black bars, adjusting aspect ratios, or focusing on important content. Supports various video formats including MP4, MOV, and AVI.",
+ "title": "Crop Video",
+ "toolInfo": {
+ "description": "This tool allows you to crop video files to remove unwanted areas. You can specify the crop area by setting the X, Y coordinates and width, height dimensions.",
+ "title": "Crop Video"
+ },
+ "videoDimensions": "Video dimensions: {{width}} ร {{height}} pixels",
+ "videoInformation": "Video Information",
+ "width": "Width",
+ "xCoordinate": "X (left)",
+ "yCoordinate": "Y (top)"
+ },
+ "flip": {
+ "description": "Flip video files horizontally or vertically. Mirror videos for special effects or correct orientation issues.",
+ "flippingVideo": "Flipping Video",
+ "horizontalLabel": "Horizontal (Mirror)",
+ "inputTitle": "Input Video",
+ "orientation": "Orientation",
+ "resultTitle": "Flipped Video",
+ "shortDescription": "Flip video horizontally or vertically",
+ "title": "Flip Video",
+ "verticalLabel": "Vertical (Upside Down)"
+ },
+ "gif": {
+ "changeSpeed": {
+ "description": "Change the playback speed of GIF animations. Speed up or slow down GIFs while maintaining smooth animation.",
+ "shortDescription": "Change GIF animation speed",
+ "title": "Change GIF Speed"
+ }
+ },
+ "loop": {
+ "description": "Create a looping video by repeating the original video multiple times.",
+ "inputTitle": "Input Video",
+ "loopingVideo": "Looping Video",
+ "loops": "Loops",
+ "numberOfLoops": "Number of Loops",
+ "resultTitle": "Looped Video",
+ "shortDescription": "Create looping video files",
+ "title": "Loop Video",
+ "toolInfo": {
+ "description": "This tool allows you to create a looping video by repeating the original video multiple times. You can specify how many times the video should loop.",
+ "title": "What is a {{title}}?"
+ }
+ },
+ "mergeVideo": {
+ "description": "Combine multiple video files into one continuous video.",
+ "longDescription": "This tool allows you to merge or append multiple video files into a single continuous video. Simply upload your video files, arrange them in the desired order, and merge them into one file for easy sharing or editing.",
+ "shortDescription": "Append and merge videos easily.",
+ "title": "Merge videos"
+ },
+ "rotate": {
+ "180Degrees": "180ยฐ (Upside down)",
+ "270Degrees": "270ยฐ (90ยฐ Counter-clockwise)",
+ "90Degrees": "90ยฐ Clockwise",
+ "description": "Rotate video files by 90, 180, or 270 degrees. Correct video orientation or create special effects with precise rotation control.",
+ "inputTitle": "Input Video",
+ "resultTitle": "Rotated Video",
+ "rotatingVideo": "Rotating Video",
+ "rotation": "Rotation",
+ "shortDescription": "Rotate video by specified degrees",
+ "title": "Rotate Video"
+ },
+ "trim": {
+ "description": "Trim video files by specifying start and end times. Remove unwanted sections from the beginning or end of videos.",
+ "endTime": "End Time",
+ "inputTitle": "Input Video",
+ "resultTitle": "Trimmed Video",
+ "shortDescription": "Trim video by removing unwanted sections",
+ "startTime": "Start Time",
+ "timestamps": "Timestamps",
+ "title": "Trim Video"
+ },
+ "videoToGif": {
+ "description": "Convert video files to animated GIF format. Extract specific time ranges and create shareable animated images.",
+ "shortDescription": "Convert video to animated GIF",
+ "title": "Video to GIF"
+ }
+}
diff --git a/public/locales/en/xml.json b/public/locales/en/xml.json
new file mode 100644
index 0000000..8acd4fc
--- /dev/null
+++ b/public/locales/en/xml.json
@@ -0,0 +1,38 @@
+{
+ "xmlBeautifier": {
+ "description": "Format XML with proper indentation and spacing.",
+ "indentation": "Indentation",
+ "inputTitle": "Input XML",
+ "resultTitle": "Beautified XML",
+ "shortDescription": "Format and beautify XML code",
+ "title": "XML Beautifier",
+ "toolInfo": {
+ "description": "This tool allows you to format XML data with proper indentation and spacing, making it more readable and easier to work with.",
+ "title": "XML Beautifier"
+ },
+ "useSpaces": "Use Spaces",
+ "useSpacesDescription": "Indent output with spaces",
+ "useTabs": "Use Tabs",
+ "useTabsDescription": "Indent output with tabs."
+ },
+ "xmlValidator": {
+ "description": "Validate XML syntax and structure.",
+ "placeholder": "Paste or import XML here...",
+ "shortDescription": "Validate XML code for errors",
+ "title": "XML Validator",
+ "toolInfo": {
+ "description": "This tool allows you to validate XML syntax and structure. It checks if the XML is well-formed and provides detailed error messages for any issues found.",
+ "title": "XML Validator"
+ }
+ },
+ "xmlViewer": {
+ "description": "View and explore XML structure in a tree format.",
+ "inputTitle": "Input XML",
+ "resultTitle": "XML Tree View",
+ "title": "XML Viewer",
+ "toolInfo": {
+ "description": "This tool allows you to view XML data in a hierarchical tree format, making it easier to explore and understand the structure of XML documents.",
+ "title": "XML Viewer"
+ }
+ }
+}
diff --git a/public/locales/es/audio.json b/public/locales/es/audio.json
new file mode 100644
index 0000000..e8698ca
--- /dev/null
+++ b/public/locales/es/audio.json
@@ -0,0 +1,42 @@
+{
+ "changeSpeed": {
+ "description": "Cambia la velocidad de reproducciรณn de los archivos de audio. Acelera o ralentiza el audio manteniendo el tono.",
+ "inputTitle": "Entrada de audio",
+ "newAudioSpeed": "Nueva velocidad de audio",
+ "outputFormat": "Formato de salida",
+ "resultTitle": "Audio editado",
+ "settingSpeed": "Ajuste de velocidad",
+ "shortDescription": "Cambiar la velocidad de los archivos de audio",
+ "speedDescription": "Multiplicador predeterminado: 2 significa 2 veces mรกs rรกpido",
+ "title": "Cambiar la velocidad del audio",
+ "toolInfo": {
+ "title": "Quรฉ es {{title}}?"
+ }
+ },
+ "extractAudio": {
+ "description": "Extraer pistas de audio de archivos de vรญdeo.",
+ "extractingAudio": "Extrayendo audio",
+ "inputTitle": "Vรญdeo de entrada",
+ "outputFormat": "Formato de salida",
+ "outputFormatDescription": "Seleccione el formato en el que se extraerรก el audio.",
+ "resultTitle": "Audio extraรญdo",
+ "shortDescription": "Extrae audio de archivos de vรญdeo (MP4, MOV, etc.) a AAC, MP3 o WAV.",
+ "title": "Extraer audio de un vรญdeo",
+ "toolInfo": {
+ "description": "Esta herramienta te permite extraer la pista de audio de archivos de video. Puedes elegir entre diferentes formatos de audio, como AAC, MP3 y WAV.",
+ "title": "Quรฉ es {{title}}?"
+ }
+ },
+ "mergeAudio": {
+ "description": "Combine varios archivos de audio en un solo archivo de audio concatenรกndolos en secuencia.",
+ "longDescription": "Esta herramienta te permite fusionar varios archivos de audio en uno solo concatenรกndolos en el orden en que los subes. Es perfecta para combinar segmentos de podcast, pistas de mรบsica o cualquier archivo de audio que necesite unirse. Admite varios formatos de audio, como MP3, AAC y WAV.",
+ "shortDescription": "Fusionar varios archivos de audio en uno (MP3, AAC, WAV).",
+ "title": "Fusionar audio"
+ },
+ "trim": {
+ "description": "Corte y recorte archivos de audio para extraer segmentos especรญficos especificando las horas de inicio y finalizaciรณn.",
+ "longDescription": "Esta herramienta te permite recortar archivos de audio especificando la hora de inicio y la hora de fin. Puedes extraer segmentos especรญficos de archivos de audio mรกs largos, eliminar partes no deseadas o crear clips mรกs cortos. Compatible con varios formatos de audio, como MP3, AAC y WAV. Ideal para ediciรณn de podcasts, producciรณn musical o cualquier otra necesidad de ediciรณn de audio.",
+ "shortDescription": "Recorta archivos de audio para extraer segmentos de tiempo especรญficos (MP3, AAC, WAV).",
+ "title": "Recortar audio"
+ }
+}
diff --git a/public/locales/es/csv.json b/public/locales/es/csv.json
new file mode 100644
index 0000000..3e4eed9
--- /dev/null
+++ b/public/locales/es/csv.json
@@ -0,0 +1,114 @@
+{
+ "changeCsvSeparator": {
+ "description": "Cambie el delimitador/separador en archivos CSV. Convierta entre diferentes formatos CSV, como coma, punto y coma, tabulaciรณn o separadores personalizados.",
+ "shortDescription": "Cambiar el delimitador del archivo CSV",
+ "title": "Cambiar el separador CSV"
+ },
+ "csvRowsToColumns": {
+ "description": "Esta herramienta convierte las filas de un archivo CSV (Valores Separados por Comas) en columnas. Extrae las lรญneas horizontales del CSV de entrada una por una, las gira 90 grados y las genera como columnas verticales, una tras otra, separadas por comas.', longDescription: 'Esta herramienta convierte las filas de un archivo CSV (Valores Separados por Comas) en columnas. Por ejemplo, si los datos CSV de entrada tienen 6 filas, la salida tendrรก 6 columnas y los elementos de las filas se ordenarรกn de arriba a abajo. En un CSV bien formado, el nรบmero de valores en cada fila es el mismo. Sin embargo, si faltan campos en las filas, el programa puede corregirlos y usted puede elegir entre las opciones disponibles: rellenar los datos faltantes con elementos vacรญos o reemplazarlos con elementos personalizados, como \"missing\", \"?\" o \"x\". Durante el proceso de conversiรณn, la herramienta tambiรฉn limpia el archivo CSV de informaciรณn innecesaria, como lรญneas vacรญas (lรญneas sin informaciรณn visible) y comentarios. Para que la herramienta identifique correctamente los comentarios, en las opciones, puede especificar el sรญmbolo al principio de la lรญnea que inicia un comentario. Este sรญmbolo suele ser una almohadilla \"#\" o una doble barra \"//\". ยกCsv-abuloso!",
+ "longDescription": "Esta herramienta convierte las filas de un archivo CSV (valores separados por comas) en columnas. Por ejemplo, si los datos CSV de entrada tienen 6 filas, la salida tendrรก 6 columnas y los elementos de las filas se ordenarรกn de arriba a abajo. En un CSV bien formado, el nรบmero de valores en cada fila es el mismo. Sin embargo, si faltan campos en las filas, el programa puede corregirlos y usted puede elegir entre las opciones disponibles: rellenar los datos faltantes con elementos vacรญos o reemplazarlos con elementos personalizados, como",
+ "shortDescription": "Convertir filas CSV en columnas.",
+ "title": "Convertir filas CSV en columnas"
+ },
+ "csvToJson": {
+ "columnSeparator": "Separador de columnas (p. ej., , ; \\t)",
+ "commentSymbol": "Sรญmbolo de comentario (p. ej., #)",
+ "conversionOptions": "Opciones de conversiรณn",
+ "description": "Convierte archivos CSV a formato JSON con opciones personalizables para delimitadores, comillas y formato de salida. Admite encabezados, comentarios y conversiรณn dinรกmica de tipos.",
+ "dynamicTypes": "Tipos dinรกmicos",
+ "dynamicTypesDescription": "Convierte automรกticamente nรบmeros y valores booleanos",
+ "errorParsing": "Error al analizar CSV: {{error}}",
+ "fieldQuote": "Cita de campo (por ejemplo, \")",
+ "inputCsvFormat": "Formato CSV de entrada",
+ "inputTitle": "CSV de entrada",
+ "resultTitle": "Salida JSON",
+ "shortDescription": "Convierte datos CSV al formato JSON.",
+ "skipEmptyLines": "Saltar lรญneas vacรญas",
+ "skipEmptyLinesDescription": "Ignorar lรญneas vacรญas en el CSV de entrada",
+ "title": "Convertir CSV a JSON",
+ "useHeaders": "Usar encabezados",
+ "useHeadersDescription": "Tratar la primera fila como encabezados de columna"
+ },
+ "csvToTsv": {
+ "description": "Sube tu archivo CSV en el formulario a continuaciรณn y se convertirรก automรกticamente a un archivo TSV. En las opciones de la herramienta, puedes personalizar el formato CSV de entrada: especifica el delimitador de campo, las comillas y el sรญmbolo de comentario, omite las lรญneas vacรญas del CSV y elige si deseas conservar los encabezados de columna del CSV.",
+ "longDescription": "Esta herramienta transforma datos de valores separados por comas (CSV) en datos de valores separados por tabulaciones (TSV). Tanto CSV como TSV son formatos de archivo populares para almacenar datos tabulares, pero utilizan diferentes delimitadores para separar los valores: CSV usa comas (",
+ "shortDescription": "Convierte datos CSV al formato TSV.",
+ "title": "Convertir CSV a TSV"
+ },
+ "csvToXml": {
+ "description": "Convierte archivos CSV al formato XML con opciones personalizables.",
+ "shortDescription": "Convertir datos CSV al formato XML.",
+ "title": "Convertir CSV a XML"
+ },
+ "csvToYaml": {
+ "description": "Simplemente cargue su archivo CSV en el formulario a continuaciรณn y se convertirรก automรกticamente a un archivo YAML. En las opciones de la herramienta, puede especificar el carรกcter delimitador de campo, la comilla de campo y el carรกcter de comentario para adaptar la herramienta a formatos CSV personalizados. Ademรกs, puede seleccionar el formato YAML de salida: uno que conserve o excluya los encabezados CSV.",
+ "longDescription": "Esta herramienta transforma datos CSV (valores separados por comas) en datos YAML (un lenguaje de marcado mรกs). CSV es un formato tabular simple que se utiliza para representar tipos de datos matriciales compuestos por filas y columnas. YAML, por otro lado, es un formato mรกs avanzado (en realidad, un superconjunto de JSON), que crea datos mรกs legibles para la serializaciรณn y admite listas, diccionarios y objetos anidados. Este programa admite varios formatos CSV de entrada: los datos de entrada pueden estar separados por comas (predeterminado), punto y coma, barras verticales o usar un delimitador completamente diferente. Puede especificar el delimitador exacto que usan sus datos en las opciones. De igual forma, en las opciones, puede especificar el carรกcter de comillas que se utiliza para encapsular los campos CSV (por defecto, un sรญmbolo de comillas dobles). Tambiรฉn puede omitir lรญneas que comiencen con comentarios especificando los sรญmbolos de comentario en las opciones. Esto le permite mantener sus datos limpios al omitir lรญneas innecesarias. Hay dos maneras de convertir CSV a YAML. El primer mรฉtodo convierte cada fila del CSV en una lista YAML. El segundo mรฉtodo extrae los encabezados de la primera fila del CSV y crea objetos YAML con claves basadas en estos encabezados. Tambiรฉn puedes personalizar el formato YAML de salida especificando el nรบmero de espacios para la sangrรญa de las estructuras YAML. Si necesitas realizar la conversiรณn inversa, es decir, transformar YAML a CSV, puedes usar nuestra herramienta Convertir YAML a CSV. ยกCsv-abroso!",
+ "shortDescription": "Convierte rรกpidamente un archivo CSV en un archivo YAML.",
+ "title": "Convertir CSV a YAML"
+ },
+ "findIncompleteCsvRecords": {
+ "checkingOptions": "Opciones de comprobaciรณn",
+ "commentCharacterDescription": "Introduzca el carรกcter que indica el inicio de una lรญnea de comentario. Las lรญneas que comiencen con este sรญmbolo se omitirรกn.",
+ "csvInputOptions": "Opciones de entrada CSV",
+ "csvSeparatorDescription": "Introduzca el carรกcter utilizado para delimitar columnas en el archivo de entrada CSV.",
+ "deleteLinesWithNoData": "Eliminar lรญneas sin datos",
+ "deleteLinesWithNoDataDescription": "Eliminar lรญneas vacรญas del archivo de entrada CSV.",
+ "description": "Simplemente cargue su archivo CSV en el formulario a continuaciรณn y esta herramienta comprobarรก automรกticamente si ninguna fila o columna tiene valores faltantes. En las opciones de la herramienta, puede ajustar el formato del archivo de entrada (especifique el delimitador, las comillas y el carรกcter de comentario). Ademรกs, puede activar la comprobaciรณn de valores vacรญos, omitir lรญneas vacรญas y limitar el nรบmero de mensajes de error en la salida.",
+ "findEmptyValues": "Encontrar valores vacรญos",
+ "findEmptyValuesDescription": "Mostrar un mensaje sobre los campos CSV que estรกn vacรญos (no son campos faltantes, sino campos que no contienen nada).",
+ "inputTitle": "CSV de entrada",
+ "limitNumberOfMessages": "Limitar el nรบmero de mensajes",
+ "messageLimitDescription": "Establezca el lรญmite del nรบmero de mensajes en la salida.",
+ "quoteCharacterDescription": "Introduzca el carรกcter de comillas utilizado para citar los campos de entrada CSV.",
+ "resultTitle": "Estado CSV",
+ "shortDescription": "Encuentre rรกpidamente filas y columnas en CSV que tengan valores faltantes.",
+ "title": "Encontrar registros CSV incompletos",
+ "toolInfo": {
+ "title": "ยฟQuรฉ es un? {{title}}?"
+ }
+ },
+ "insertCsvColumns": {
+ "appendColumns": "Aรฑadir columnas",
+ "commentCharacterDescription": "Introduzca el carรกcter que indica el inicio de una lรญnea de comentario. Las lรญneas que comiencen con este sรญmbolo se omitirรกn.",
+ "csvOptions": "Opciones CSV",
+ "csvSeparator": "Separador CSV",
+ "csvToInsert": "CSV para insertar",
+ "csvToInsertDescription": "Introduzca una o mรกs columnas que desee insertar en el CSV. El carรกcter utilizado para delimitar las columnas debe ser el mismo que el del archivo CSV de entrada. Nota: Se ignorarรกn las lรญneas en blanco.",
+ "customFillDescription": "Si el archivo CSV de entrada estรก incompleto (valores faltantes), ยฟcรณmo agregar campos vacรญos o sรญmbolos personalizados a los registros para crear un CSV bien formado?",
+ "customFillValueDescription": "Utilice este valor personalizado para completar los campos que faltan. (Solo funciona con el modo \"Valores personalizados\" mencionado anteriormente).",
+ "customPosition": "Posiciรณn personalizada",
+ "customPositionOptionsDescription": "Seleccione el mรฉtodo para insertar las columnas en el archivo CSV.",
+ "description": "Agregar nuevas columnas a los datos CSV en posiciones especรญficas.",
+ "fillWithCustomValues": "Rellenar con valores aduaneros",
+ "fillWithEmptyValues": "Rellenar con valores vacรญos",
+ "headerName": "Nombre del encabezado",
+ "headerNameDescription": "Encabezado de la columna despuรฉs de la cual desea insertar columnas.",
+ "inputTitle": "CSV de entrada",
+ "insertingPositionDescription": "Especifique dรณnde insertar las columnas en el archivo CSV.",
+ "position": "Posiciรณn",
+ "positionOptions": "Opciones de posiciรณn",
+ "prependColumns": "Anteponer columnas",
+ "quoteCharDescription": "Introduzca el carรกcter de comillas utilizado para citar los campos de entrada CSV.",
+ "resultTitle": "CSV de salida",
+ "rowNumberDescription": "Nรบmero de la columna despuรฉs de la cual desea insertar columnas.",
+ "separatorDescription": "Introduzca el carรกcter utilizado para delimitar columnas en el archivo de entrada CSV.",
+ "shortDescription": "Inserte rรกpidamente una o mรกs columnas nuevas en cualquier lugar de un archivo CSV.",
+ "title": "Insertar columnas CSV",
+ "toolInfo": {
+ "description": "Esta herramienta permite insertar nuevas columnas en datos CSV en posiciones especรญficas. Puede anteponer, anexar o insertar columnas en posiciones personalizadas segรบn los nombres de encabezado o los nรบmeros de columna.",
+ "title": "Insertar columnas CSV"
+ }
+ },
+ "swapCsvColumns": {
+ "description": "Simplemente cargue su archivo CSV en el formulario a continuaciรณn, especifique las columnas que desea intercambiar y la herramienta cambiarรก automรกticamente la posiciรณn de dichas columnas en el archivo de salida. En las opciones de la herramienta, puede especificar las posiciones o los nombres de las columnas que desea intercambiar, asรญ como corregir datos incompletos y, opcionalmente, eliminar registros vacรญos y comentados.",
+ "longDescription": "Esta herramienta reorganiza los datos CSV intercambiando la posiciรณn de sus columnas. Intercambiar columnas mejora la legibilidad de un archivo CSV al colocar los datos de uso frecuente juntos o al frente para facilitar la comparaciรณn y ediciรณn. Por ejemplo, puede intercambiar la primera columna con la รบltima o la segunda con la tercera. Para intercambiar columnas segรบn su posiciรณn, seleccione",
+ "shortDescription": "Reordenar columnas CSV.",
+ "title": "Intercambiar columnas CSV"
+ },
+ "transposeCsv": {
+ "description": "Simplemente cargue su archivo CSV en el formulario a continuaciรณn y esta herramienta lo transpondrรก automรกticamente. En las opciones de la herramienta, puede especificar el carรกcter que inicia las lรญneas de comentario en el CSV para eliminarlas. Ademรกs, si el CSV estรก incompleto (valores faltantes), puede reemplazarlos con el carรกcter vacรญo o un carรกcter personalizado.",
+ "longDescription": "Esta herramienta transpone valores separados por comas (CSV). Trata el CSV como una matriz de datos e invierte todos los elementos a lo largo de la diagonal principal. El resultado contiene los mismos datos CSV que la entrada, pero ahora todas las filas se han convertido en columnas y todas las columnas en filas. Tras la transposiciรณn, el archivo CSV tendrรก dimensiones opuestas. Por ejemplo, si el archivo de entrada tiene 4 columnas y 3 filas, el archivo de salida tendrรก 3 columnas y 4 filas. Durante la conversiรณn, el programa tambiรฉn elimina las lรญneas innecesarias y corrige los datos incompletos. En concreto, la herramienta elimina automรกticamente todos los registros vacรญos y los comentarios que empiezan por un carรกcter especรญfico, que se puede configurar en la opciรณn. Ademรกs, si los datos CSV se corrompen o se pierden, la utilidad completa el archivo con campos vacรญos o campos personalizados que se pueden especificar en las opciones. ยกCsv-abuloso!",
+ "shortDescription": "Transponer rรกpidamente un archivo CSV.",
+ "title": "Transponer CSV"
+ }
+}
diff --git a/public/locales/es/image.json b/public/locales/es/image.json
new file mode 100644
index 0000000..2d79bd5
--- /dev/null
+++ b/public/locales/es/image.json
@@ -0,0 +1,98 @@
+{
+ "changeColors": {
+ "description": "Mundo",
+ "shortDescription": "Intercambia colores rรกpidamente en una imagen",
+ "title": "Cambiar colores en la imagen"
+ },
+ "changeOpacity": {
+ "description": "Ajusta fรกcilmente la transparencia de tus imรกgenes. Simplemente sube tu imagen, usa el control deslizante para establecer el nivel de opacidad deseado entre 0 (totalmente transparente) y 1 (totalmente opaco) y descarga la imagen modificada.",
+ "shortDescription": "Ajustar la transparencia de las imรกgenes",
+ "title": "Cambiar la opacidad de la imagen"
+ },
+ "compress": {
+ "description": "Reduce el tamaรฑo del archivo de imagen manteniendo la calidad.",
+ "inputTitle": "Imagen de entrada",
+ "resultTitle": "Imagen comprimida",
+ "shortDescription": "Comprima imรกgenes para reducir el tamaรฑo del archivo manteniendo una calidad razonable.",
+ "title": "Comprimir imagen"
+ },
+ "compressPng": {
+ "description": "Este programa comprime imรกgenes PNG. Al pegar la imagen PNG en el รกrea de entrada, el programa la comprimirรก y mostrarรก el resultado en el รกrea de salida. En las opciones, puede ajustar el nivel de compresiรณn y consultar los tamaรฑos de archivo de las imรกgenes antiguas y nuevas.",
+ "shortDescription": "Comprimir rรกpidamente un PNG",
+ "title": "Comprimir png"
+ },
+ "convertJgpToPng": {
+ "description": "Convierte rรกpidamente tus imรกgenes JPG a PNG. Simplemente importa tu imagen PNG en el editor de la izquierda.",
+ "shortDescription": "Convierte rรกpidamente tus imรกgenes JPG a PNG",
+ "title": "Convertir JPG a PNG"
+ },
+ "convertToJpg": {
+ "description": "Convierte varios formatos de imagen (PNG, GIF, TIF, PSD, SVG, WEBP, HEIC, RAW) a JPG con configuraciones de color de fondo y calidad personalizables.",
+ "shortDescription": "Convierte imรกgenes a JPG con control de calidad",
+ "title": "Convertir imรกgenes a JPG"
+ },
+ "createTransparent": {
+ "description": "Mundo",
+ "shortDescription": "Hacer que una imagen sea transparente rรกpidamente",
+ "title": "Crear PNG transparente"
+ },
+ "crop": {
+ "description": "Recortar imรกgenes para eliminar รกreas no deseadas.",
+ "inputTitle": "Imagen de entrada",
+ "resultTitle": "Imagen recortada",
+ "shortDescription": "Recortar imรกgenes rรกpidamente.",
+ "title": "Recortar imagen"
+ },
+ "editor": {
+ "description": "Editor de imรกgenes avanzado con herramientas para recortar, rotar, anotar, ajustar colores y aรฑadir marcas de agua. Edita tus imรกgenes con herramientas profesionales directamente en tu navegador.",
+ "shortDescription": "Edite imรกgenes con herramientas y funciones avanzadas",
+ "title": "Editor de imรกgenes"
+ },
+ "imageToText": {
+ "description": "Extraer texto de imรกgenes (JPG, PNG) mediante reconocimiento รณptico de caracteres (OCR).",
+ "shortDescription": "Extraer texto de imรกgenes usando OCR.",
+ "title": "Imagen a texto (OCR)"
+ },
+ "qrCode": {
+ "description": "Genere cรณdigos QR para diferentes tipos de datos: URL, texto, correo electrรณnico, telรฉfono, SMS, WiFi, vCard y mรกs.",
+ "shortDescription": "Cree cรณdigos QR personalizados para varios formatos de datos.",
+ "title": "Generador de cรณdigos QR"
+ },
+ "removeBackground": {
+ "description": "Mundo",
+ "shortDescription": "Eliminar automรกticamente los fondos de las imรกgenes",
+ "title": "Quitar el fondo de la imagen"
+ },
+ "resize": {
+ "description": "Cambiar el tamaรฑo de las imรกgenes a diferentes dimensiones.",
+ "dimensionType": "Tipo de dimensiรณn",
+ "heightDescription": "Altura (en pรญxeles)",
+ "inputTitle": "Imagen de entrada",
+ "maintainAspectRatio": "Mantener la relaciรณn de aspecto",
+ "maintainAspectRatioDescription": "Mantener la relaciรณn de aspecto original de la imagen.",
+ "percentage": "Porcentaje",
+ "percentageDescription": "Porcentaje del tamaรฑo original (p. ej., 50 para la mitad del tamaรฑo, 200 para el doble del tamaรฑo)",
+ "resizeByPercentage": "Cambiar el tamaรฑo por porcentaje",
+ "resizeByPercentageDescription": "Cambiar el tamaรฑo especificando un porcentaje del tamaรฑo original.",
+ "resizeByPixels": "Cambiar tamaรฑo por pรญxeles",
+ "resizeByPixelsDescription": "Cambiar el tamaรฑo especificando las dimensiones en pรญxeles.",
+ "resizeMethod": "Mรฉtodo de cambio de tamaรฑo",
+ "resultTitle": "Imagen redimensionada",
+ "setHeight": "Establecer altura",
+ "setHeightDescription": "Especifique la altura en pรญxeles y calcule el ancho segรบn la relaciรณn de aspecto.",
+ "setWidth": "Establecer ancho",
+ "setWidthDescription": "Especifique el ancho en pรญxeles y calcule la altura segรบn la relaciรณn de aspecto.",
+ "shortDescription": "Cambie el tamaรฑo de las imรกgenes fรกcilmente.",
+ "title": "Cambiar el tamaรฑo de la imagen",
+ "toolInfo": {
+ "description": "Esta herramienta permite redimensionar imรกgenes JPG, PNG, SVG o GIF. Puedes redimensionarlas especificando las dimensiones en pรญxeles o por porcentaje, con opciones para mantener la relaciรณn de aspecto original.",
+ "title": "Cambiar el tamaรฑo de la imagen"
+ },
+ "widthDescription": "Ancho (en pรญxeles)"
+ },
+ "rotate": {
+ "description": "Girar una imagen en un รกngulo especรญfico.",
+ "shortDescription": "Girar una imagen fรกcilmente.",
+ "title": "Girar imagen"
+ }
+}
diff --git a/public/locales/es/json.json b/public/locales/es/json.json
new file mode 100644
index 0000000..5ed5251
--- /dev/null
+++ b/public/locales/es/json.json
@@ -0,0 +1,62 @@
+{
+ "escapeJson": {
+ "description": "Escape de caracteres especiales en cadenas JSON. Convierta datos JSON a un formato de escape adecuado para una transmisiรณn o almacenamiento seguros.",
+ "shortDescription": "Escapar caracteres especiales en JSON",
+ "title": "Escapar JSON"
+ },
+ "jsonToXml": {
+ "description": "Convierte datos JSON a formato XML. Transforma objetos JSON estructurados en documentos XML bien formados.",
+ "shortDescription": "Convertir JSON a formato XML",
+ "title": "JSON a XML"
+ },
+ "minify": {
+ "description": "Elimina todos los espacios en blanco innecesarios de JSON.",
+ "inputTitle": "Entrada JSON",
+ "resultTitle": "JSON minimizado",
+ "shortDescription": "Minificar JSON eliminando los espacios en blanco",
+ "title": "Minificar JSON",
+ "toolInfo": {
+ "description": "La minimizaciรณn de JSON consiste en eliminar todos los espacios innecesarios de los datos JSON, manteniendo su validez. Esto incluye la eliminaciรณn de espacios, saltos de lรญnea y sangrรญas innecesarios para el correcto anรกlisis del JSON. La minimizaciรณn reduce el tamaรฑo de los datos JSON, lo que aumenta su eficiencia de almacenamiento y transmisiรณn, manteniendo la misma estructura y valores de datos.",
+ "title": "ยฟQuรฉ es la minificaciรณn de JSON?"
+ }
+ },
+ "prettify": {
+ "description": "Formatee JSON con sangrรญa y espaciado adecuados.",
+ "indentation": "Sangrรญa",
+ "inputTitle": "Entrada JSON",
+ "resultTitle": "JSON embellecido",
+ "shortDescription": "Formatear y embellecer el cรณdigo JSON",
+ "title": "Embellecer JSON",
+ "toolInfo": {
+ "description": "Esta herramienta le permite formatear datos JSON con sangrรญa y espaciado adecuados, haciรฉndolos mรกs legibles y fรกciles de trabajar.",
+ "title": "Embellecer JSON"
+ },
+ "useSpaces": "Utilice espacios",
+ "useSpacesDescription": "Sangrar la salida con espacios",
+ "useTabs": "Usar pestaรฑas",
+ "useTabsDescription": "Sangrar la salida con tabulaciones."
+ },
+ "stringify": {
+ "description": "Convierte objetos JavaScript a formato de cadena JSON. Serializa estructuras de datos en cadenas JSON para su almacenamiento o transmisiรณn.",
+ "shortDescription": "Convertir objetos en cadena JSON",
+ "title": "Convertir JSON en cadenas"
+ },
+ "tsvToJson": {
+ "description": "Convierte datos TSV (Valores Separados por Tabulaciones) a formato JSON. Transforma datos tabulares en objetos JSON estructurados.",
+ "shortDescription": "Convertir TSV a formato JSON",
+ "title": "TSV a JSON"
+ },
+ "validateJson": {
+ "description": "Comprueba si JSON es vรกlido y estรก bien formado.",
+ "inputTitle": "Entrada JSON",
+ "invalidJson": "โ {{error}}",
+ "resultTitle": "Resultado de la validaciรณn",
+ "shortDescription": "Validar el cรณdigo JSON para detectar errores",
+ "title": "Validar JSON",
+ "toolInfo": {
+ "description": "JSON (Notaciรณn de Objetos JavaScript) es un formato ligero de intercambio de datos. La validaciรณn de JSON garantiza que la estructura de los datos cumpla con el estรกndar JSON. Un objeto JSON vรกlido debe tener: - Nombres de propiedad entre comillas dobles. - Llaves {} correctamente equilibradas. - Sin comas finales despuรฉs del รบltimo par clave-valor. - Anidamiento correcto de objetos y matrices. Esta herramienta revisa el JSON de entrada y proporciona informaciรณn para ayudar a identificar y corregir errores comunes.",
+ "title": "ยฟQuรฉ es la validaciรณn JSON?"
+ },
+ "validJson": "โ
JSON vรกlido"
+ }
+}
diff --git a/public/locales/es/list.json b/public/locales/es/list.json
new file mode 100644
index 0000000..80f8191
--- /dev/null
+++ b/public/locales/es/list.json
@@ -0,0 +1,208 @@
+{
+ "duplicate": {
+ "concatenate": "Concatenar",
+ "concatenateDescription": "Concatenar copias (si no estรก marcada, los elementos se entrelazarรกn)",
+ "copyDescription": "Nรบmero de copias (puede ser fraccionario)",
+ "description": "La utilidad basada en navegador mรกs sencilla del mundo para duplicar elementos de listas. Introduce tu lista y especifica los criterios de duplicaciรณn para crear copias de elementos. Perfecta para ampliar datos, realizar pruebas o crear patrones repetidos.",
+ "duplicationOptions": "Opciones de duplicaciรณn",
+ "examples": {
+ "fractional": {
+ "description": "Este ejemplo muestra cรณmo duplicar una lista con un nรบmero fraccionario de copias.",
+ "title": "Duplicaciรณn fraccionaria"
+ },
+ "interweave": {
+ "description": "Este ejemplo muestra cรณmo entrelazar elementos en lugar de concatenarlos.",
+ "title": "Elementos entretejidos"
+ },
+ "reverse": {
+ "description": "Este ejemplo muestra cรณmo duplicar una lista en orden inverso.",
+ "title": "Duplicaciรณn inversa"
+ },
+ "simple": {
+ "description": "Este ejemplo muestra cรณmo duplicar una lista de palabras.",
+ "title": "Duplicaciรณn simple"
+ }
+ },
+ "inputTitle": "Lista de entrada",
+ "joinSeparatorDescription": "Separador para unir la lista duplicada",
+ "resultTitle": "Lista duplicada",
+ "reverse": "Contrarrestar",
+ "reverseDescription": "Revertir los elementos duplicados",
+ "shortDescription": "Elementos de lista duplicados con criterios especรญficos",
+ "splitByRegex": "Dividir por expresiรณn regular",
+ "splitBySymbol": "Dividir por sรญmbolo",
+ "splitOptions": "Opciones divididas",
+ "splitSeparatorDescription": "Separador para dividir la lista",
+ "title": "Duplicado",
+ "toolInfo": {
+ "description": "Esta herramienta permite duplicar elementos en una lista. Se puede especificar el nรบmero de copias (incluidos los valores fraccionarios), controlar si los elementos estรกn concatenados o entrelazados, e incluso invertir la duplicaciรณn. Resulta รบtil para crear patrones repetidos, generar datos de prueba o ampliar listas con contenido predecible.",
+ "title": "Duplicaciรณn de listas"
+ }
+ },
+ "findMostPopular": {
+ "description": "La utilidad de navegador mรกs sencilla del mundo para encontrar los elementos mรกs populares en una lista. Introduce tu lista y obtรฉn al instante los elementos que aparecen con mรกs frecuencia. Perfecta para anรกlisis de datos, identificaciรณn de tendencias o bรบsqueda de elementos comunes.",
+ "shortDescription": "Encuentra los elementos que aparecen con mรกs frecuencia",
+ "title": "Encuentra los mรกs populares"
+ },
+ "findUnique": {
+ "caseSensitiveItems": "Elementos que distinguen entre mayรบsculas y minรบsculas",
+ "caseSensitiveItemsDescription": "Muestra los elementos con mayรบsculas y minรบsculas diferentes como elementos รบnicos en la lista.",
+ "delimiterDescription": "Establezca un sรญmbolo delimitador o una expresiรณn regular.",
+ "description": "La utilidad de navegador mรกs sencilla del mundo para encontrar elementos รบnicos en una lista. Introduce tu lista y obtรฉn al instante todos los valores รบnicos, eliminando los duplicados. Perfecta para la limpieza de datos, la deduplicaciรณn o la bรบsqueda de elementos distintos.",
+ "findAbsolutelyUniqueItems": "Encuentra artรญculos absolutamente รบnicos",
+ "findAbsolutelyUniqueItemsDescription": "Mostrar sรณlo aquellos elementos de la lista que existen en una sola copia.",
+ "inputListDelimiter": "Delimitador de lista de entrada",
+ "inputTitle": "Lista de entrada",
+ "outputListDelimiter": "Delimitador de lista de salida",
+ "resultTitle": "Artรญculos รบnicos",
+ "shortDescription": "Encuentra artรญculos รบnicos en una lista",
+ "skipEmptyItems": "Omitir elementos vacรญos",
+ "skipEmptyItemsDescription": "No incluya los elementos de lista vacรญos en la salida.",
+ "title": "Encuentra algo รบnico",
+ "trimItems": "Elementos de la lista de recortes",
+ "trimItemsDescription": "Elimine los espacios iniciales y finales antes de comparar elementos.",
+ "uniqueItemOptions": "Opciones de artรญculos รบnicos"
+ },
+ "group": {
+ "deleteEmptyItems": "Eliminar elementos vacรญos",
+ "deleteEmptyItemsDescription": "Ignore los elementos vacรญos y no los incluya en los grupos.",
+ "description": "La utilidad basada en navegador mรกs sencilla del mundo para agrupar elementos de listas. Introduce tu lista y especifica los criterios de agrupaciรณn para organizar los elementos en grupos lรณgicos. Perfecta para categorizar datos, organizar informaciรณn o crear listas estructuradas. Admite separadores personalizados y diversas opciones de agrupaciรณn.",
+ "emptyItemsAndPadding": "Elementos vacรญos y relleno",
+ "groupNumberDescription": "Nรบmero de elementos en un grupo",
+ "groupSeparatorDescription": "Carรกcter separador de grupo",
+ "groupSizeAndSeparators": "Tamaรฑo del grupo y separadores",
+ "inputItemSeparator": "Separador de elementos de entrada",
+ "inputTitle": "Lista de entrada",
+ "itemSeparatorDescription": "Carรกcter separador de elementos",
+ "leftWrapDescription": "Sรญmbolo de envoltura izquierda del grupo.",
+ "padNonFullGroups": "Grupos no llenos de Pad",
+ "padNonFullGroupsDescription": "Llene los grupos que no estรฉn completos con un elemento personalizado (ingrรฉselo a continuaciรณn).",
+ "paddingCharDescription": "Utilice este carรกcter o elemento para rellenar grupos que no estรฉn completos.",
+ "resultTitle": "Elementos agrupados",
+ "rightWrapDescription": "Sรญmbolo de envoltura derecha del grupo.",
+ "shortDescription": "Agrupar elementos de la lista por propiedades comunes",
+ "splitOperators": {
+ "regex": {
+ "description": "Delimitar los elementos de la lista de entrada con una expresiรณn regular.",
+ "title": "Utilice una expresiรณn regular para dividir"
+ },
+ "symbol": {
+ "description": "Delimitar los elementos de la lista de entrada con un carรกcter.",
+ "title": "Utilice un sรญmbolo para dividir"
+ }
+ },
+ "splitSeparatorDescription": "Establezca un sรญmbolo delimitador o una expresiรณn regular.",
+ "title": "Grupo"
+ },
+ "reverse": {
+ "description": "Esta sencilla aplicaciรณn basada en navegador imprime todos los elementos de la lista en orden inverso. Los elementos de entrada se pueden separar con cualquier sรญmbolo y tambiรฉn se puede cambiar el separador de los elementos de la lista invertidos.",
+ "inputTitle": "Lista de entrada",
+ "itemSeparator": "Separador de artรญculos",
+ "itemSeparatorDescription": "Establezca un sรญmbolo delimitador o una expresiรณn regular.",
+ "outputListOptions": "Opciones de lista de salida",
+ "outputSeparatorDescription": "Separador de elementos de lista de salida.",
+ "resultTitle": "Lista invertida",
+ "shortDescription": "Invertir una lista rรกpidamente",
+ "splitOperators": {
+ "regex": {
+ "description": "Delimitar los elementos de la lista de entrada con una expresiรณn regular.",
+ "title": "Utilice una expresiรณn regular para dividir"
+ },
+ "symbol": {
+ "description": "Delimitar los elementos de la lista de entrada con un carรกcter.",
+ "title": "Utilice un sรญmbolo para dividir"
+ }
+ },
+ "splitterMode": "Modo divisor",
+ "title": "Contrarrestar",
+ "toolInfo": {
+ "description": "Con esta utilidad, puede invertir el orden de los elementos de una lista. La utilidad primero divide la lista de entrada en elementos individuales y luego los itera desde el รบltimo hasta el primero, imprimiendo cada elemento en la salida durante la iteraciรณn. La lista de entrada puede contener cualquier elemento que pueda representarse como datos textuales, incluyendo dรญgitos, nรบmeros, cadenas, palabras, oraciones, etc. El separador de elementos de entrada tambiรฉn puede ser una expresiรณn regular. Por ejemplo, la expresiรณn regular /[;,]/ le permitirรก usar elementos separados por coma o punto y coma. Los delimitadores de los elementos de las listas de entrada y salida se pueden personalizar en las opciones. Por defecto, tanto las listas de entrada como las de salida estรกn separadas por comas. ยกIncreรญble!",
+ "title": "ยฟQuรฉ es un inversor de listas?"
+ }
+ },
+ "rotate": {
+ "description": "La utilidad basada en navegador mรกs sencilla del mundo para rotar elementos de listas. Introduce tu lista y especifica el grado de rotaciรณn para desplazar los elementos un nรบmero determinado de posiciones. Perfecta para la manipulaciรณn de datos, desplazamientos circulares o reordenamiento de listas.",
+ "shortDescription": "Rotar elementos de la lista segรบn posiciones especรญficas",
+ "title": "Girar"
+ },
+ "shuffle": {
+ "delimiterDescription": "Establezca un sรญmbolo delimitador o una expresiรณn regular.",
+ "description": "La utilidad de navegador mรกs sencilla del mundo para ordenar aleatoriamente los elementos de una lista. Introduce tu lista y obtรฉn al instante una versiรณn aleatoria con elementos en orden aleatorio. Perfecta para crear variedad, comprobar la aleatoriedad o mezclar datos ordenados.",
+ "inputListSeparator": "Separador de lista de entrada",
+ "inputTitle": "Lista de entrada",
+ "joinSeparatorDescription": "Utilice este separador en la lista aleatoria.",
+ "outputLengthDescription": "Generar esta cantidad de elementos aleatorios",
+ "resultTitle": "Lista barajada",
+ "shortDescription": "Aleatorizar el orden de los elementos de la lista",
+ "shuffledListLength": "Longitud de la lista aleatoria",
+ "shuffledListSeparator": "Separador de lista aleatoria",
+ "title": "Barajar"
+ },
+ "sort": {
+ "caseSensitive": "Ordenaciรณn sensible a mayรบsculas y minรบsculas",
+ "caseSensitiveDescription": "Ordena los elementos en mayรบsculas y minรบsculas por separado. Las mayรบsculas preceden a las minรบsculas en una lista ascendente. (Solo funciona en orden alfabรฉtico).",
+ "description": "La utilidad de navegador mรกs sencilla del mundo para ordenar elementos de listas. Introduce tu lista y especifica los criterios de ordenaciรณn para organizar los elementos en orden ascendente o descendente. Perfecta para organizar datos, procesar texto o crear listas ordenadas.",
+ "inputItemSeparator": "Separador de elementos de entrada",
+ "inputTitle": "Lista de entrada",
+ "joinSeparatorDescription": "Utilice este sรญmbolo como conector entre elementos de una lista ordenada.",
+ "orderDescription": "Seleccione un orden de clasificaciรณn.",
+ "orderOptions": {
+ "decreasing": "Orden decreciente",
+ "increasing": "Orden creciente"
+ },
+ "removeDuplicates": "Eliminar duplicados",
+ "removeDuplicatesDescription": "Eliminar elementos de lista duplicados.",
+ "resultTitle": "Lista ordenada",
+ "shortDescription": "Ordenar los elementos de la lista en el orden especificado",
+ "sortMethod": "Mรฉtodo de ordenaciรณn",
+ "sortMethodDescription": "Seleccione un mรฉtodo de clasificaciรณn.",
+ "sortOptions": {
+ "alphabetic": "Ordenar alfabรฉticamente",
+ "length": "Ordenar por longitud",
+ "numeric": "Ordenar numรฉricamente"
+ },
+ "sortedItemProperties": "Propiedades de elementos ordenados",
+ "splitOperators": {
+ "regex": {
+ "description": "Delimitar los elementos de la lista de entrada con una expresiรณn regular.",
+ "title": "Utilice una expresiรณn regular para dividir"
+ },
+ "symbol": {
+ "description": "Delimitar los elementos de la lista de entrada con un carรกcter.",
+ "title": "Utilice un sรญmbolo para dividir"
+ }
+ },
+ "splitSeparatorDescription": "Establezca un sรญmbolo delimitador o una expresiรณn regular.",
+ "title": "Clasificar"
+ },
+ "truncate": {
+ "description": "La utilidad de navegador mรกs sencilla del mundo para truncar listas. Introduce tu lista y especifica el nรบmero mรกximo de elementos que quieres conservar. Perfecta para procesar datos, gestionar listas o limitar la longitud del contenido.",
+ "shortDescription": "Truncar la lista a un nรบmero especificado de elementos",
+ "title": "Truncar"
+ },
+ "unwrap": {
+ "description": "La utilidad basada en navegador mรกs sencilla del mundo para descomprimir elementos de listas. Ingrese su lista descomprimida y especifique los criterios de descompresiรณn para aplanar los elementos organizados. Perfecta para procesar datos, manipular texto o extraer contenido de listas estructuradas.",
+ "shortDescription": "Desplegar elementos de lista del formato estructurado",
+ "title": "Desenvolver"
+ },
+ "wrap": {
+ "description": "Agregue texto antes y despuรฉs de cada elemento de la lista.",
+ "inputTitle": "Lista de entrada",
+ "joinSeparatorDescription": "Separador para unir la lista envuelta",
+ "leftTextDescription": "Texto para agregar antes de cada elemento",
+ "removeEmptyItems": "Eliminar elementos vacรญos",
+ "resultTitle": "Lista envuelta",
+ "rightTextDescription": "Texto para agregar despuรฉs de cada elemento",
+ "shortDescription": "Envolver elementos de la lista con criterios especรญficos",
+ "splitByRegex": "Dividir por expresiรณn regular",
+ "splitBySymbol": "Dividir por sรญmbolo",
+ "splitOptions": "Opciones divididas",
+ "splitSeparatorDescription": "Separador para dividir la lista",
+ "title": "Envoltura",
+ "toolInfo": {
+ "description": "Esta herramienta permite agregar texto antes y despuรฉs de cada elemento de una lista. Puede especificar texto diferente para los lados izquierdo y derecho, y controlar cรณmo se procesa la lista. Es รบtil para agregar comillas, corchetes u otro formato a los elementos de la lista, preparar datos para diferentes formatos o crear texto estructurado.",
+ "title": "Envoltura de listas"
+ },
+ "wrapOptions": "Opciones de envoltura"
+ }
+}
diff --git a/public/locales/es/number.json b/public/locales/es/number.json
new file mode 100644
index 0000000..c450a4b
--- /dev/null
+++ b/public/locales/es/number.json
@@ -0,0 +1,89 @@
+{
+ "arithmeticSequence": {
+ "commonDifferenceDescription": "Diferencia comรบn entre tรฉrminos (d)",
+ "description": "Genere secuencias aritmรฉticas con parรกmetros personalizables.",
+ "firstTermDescription": "Primer tรฉrmino de la secuencia (aโ)",
+ "numberOfTermsDescription": "Nรบmero de tรฉrminos a generar (n)",
+ "outputFormat": "Formato de salida",
+ "resultTitle": "Secuencia generada",
+ "separatorDescription": "Separador entre tรฉrminos",
+ "sequenceParameters": "Parรกmetros de secuencia",
+ "shortDescription": "Generar secuencias aritmรฉticas",
+ "title": "Sucesiรณn aritmรฉtica",
+ "toolInfo": {
+ "description": "Una sucesiรณn aritmรฉtica es una secuencia de nรบmeros donde la diferencia entre cada tรฉrmino consecutivo es constante. Esta diferencia constante se denomina diferencia comรบn. Dados el primer tรฉrmino (aโ) y la diferencia comรบn (d), cada tรฉrmino se puede hallar sumando la diferencia comรบn al tรฉrmino anterior.",
+ "title": "ยฟQuรฉ es una secuencia aritmรฉtica?"
+ }
+ },
+ "generate": {
+ "arithmeticSequenceOption": "Opciรณn de secuencia aritmรฉtica",
+ "description": "Genere una secuencia de nรบmeros con parรกmetros personalizables.",
+ "numberOfElementsDescription": "Nรบmero de elementos en secuencia.",
+ "resultTitle": "Nรบmeros generados",
+ "separator": "Separador",
+ "separatorDescription": "Separa elementos de la secuencia aritmรฉtica mediante este carรกcter.",
+ "shortDescription": "Generar nรบmeros aleatorios en rangos especรญficos",
+ "startSequenceDescription": "Inicie la secuencia desde este nรบmero.",
+ "stepDescription": "Aumente cada elemento en esta cantidad",
+ "title": "Generar",
+ "toolInfo": {
+ "description": "Esta herramienta permite generar una secuencia de nรบmeros con parรกmetros personalizables. Se puede especificar el valor inicial, el tamaรฑo del paso y el nรบmero de elementos.",
+ "title": "Generar nรบmeros"
+ }
+ },
+ "ohmsLaw": {
+ "description": "Calcula voltaje, corriente y resistencia.",
+ "longDescription": "Esta calculadora aplica la Ley de Ohm (V = I ร R) para determinar cualquiera de los tres parรกmetros elรฉctricos cuando se conocen los otros dos. La Ley de Ohm es un principio fundamental en ingenierรญa elรฉctrica que describe la relaciรณn entre el voltaje (V), la corriente (I) y la resistencia (R). Esta herramienta es esencial para aficionados a la electrรณnica, ingenieros elรฉctricos y estudiantes que trabajan con circuitos para resolver rรกpidamente valores desconocidos en sus diseรฑos elรฉctricos.",
+ "shortDescription": "Calcular voltaje, corriente o resistencia en circuitos elรฉctricos utilizando la Ley de Ohm",
+ "title": "Ley de Ohm"
+ },
+ "slackline": {
+ "description": "Calcula la tensiรณn en una slackline",
+ "longDescription": "Esta calculadora asume una carga en el centro de la cuerda.",
+ "shortDescription": "Calcula la tensiรณn aproximada de un slackline o tendedero. No confรญes en esto para tu seguridad.",
+ "title": "Tensiรณn de la slackline"
+ },
+ "sphereArea": {
+ "description": "รrea de una esfera",
+ "longDescription": "Esta calculadora determina el รกrea superficial de una esfera mediante la fรณrmula A = 4ฯrยฒ. Puedes introducir el radio para hallar el รกrea superficial o introducir el รกrea superficial para calcular el radio requerido. Esta herramienta es รบtil para estudiantes de geometrรญa, ingenieros que trabajan con objetos esfรฉricos y cualquier persona que necesite realizar cรกlculos con superficies esfรฉricas.",
+ "shortDescription": "Calcular el รกrea superficial de una esfera en funciรณn de su radio.",
+ "title": "รrea de una esfera"
+ },
+ "sphereVolume": {
+ "description": "Volumen de una esfera",
+ "longDescription": "Esta calculadora calcula el volumen de una esfera mediante la fรณrmula V = (4/3)ฯrยณ. Puede introducir el radio o el diรกmetro para calcular el volumen, o bien introducir el volumen para determinar el radio requerido. Esta herramienta es รบtil para estudiantes, ingenieros y profesionales que trabajan con objetos esfรฉricos en campos como la fรญsica, la ingenierรญa y la fabricaciรณn.",
+ "shortDescription": "Calcular el volumen de una esfera usando el radio o el diรกmetro.",
+ "title": "Volumen de una esfera"
+ },
+ "sum": {
+ "description": "Calcula la suma de una lista de nรบmeros. Introduce los nรบmeros separados por comas o saltos de lรญnea para obtener la suma total.",
+ "extractionTypes": {
+ "delimiter": {
+ "description": "Personaliza aquรญ el separador de nรบmeros (predeterminado: un salto de lรญnea).",
+ "title": "Delimitador de nรบmeros"
+ },
+ "smart": {
+ "description": "Detectar automรกticamente nรบmeros en la entrada.",
+ "title": "Suma inteligente"
+ }
+ },
+ "inputTitle": "Aporte",
+ "numberExtraction": "Extracciรณn de nรบmeros",
+ "printRunningSum": "Imprimir suma continua",
+ "printRunningSumDescription": "Muestra la suma a medida que se calcula paso a paso.",
+ "resultTitle": "Total",
+ "runningSum": "Suma continua",
+ "shortDescription": "Calcular la suma de nรบmeros",
+ "title": "Suma",
+ "toolInfo": {
+ "description": "Esta es una utilidad en lรญnea para calcular la suma de un conjunto de nรบmeros. Puede introducir los nรบmeros separados por coma, espacio o cualquier otro carรกcter, incluido el salto de lรญnea. Tambiรฉn puede pegar un fragmento de texto que contenga valores numรฉricos que desee sumar y la utilidad los extraerรก y calcularรก su suma.",
+ "title": "ยฟQuรฉ es una calculadora de suma de nรบmeros?"
+ }
+ },
+ "voltageDropInWire": {
+ "description": "Calcula el voltaje de ida y vuelta y la pรฉrdida de potencia en un cable de 2 conductores.",
+ "longDescription": "Esta calculadora ayuda a determinar la caรญda de tensiรณn y la pรฉrdida de potencia en un cable elรฉctrico de dos conductores. Considera la longitud del cable, el calibre del cable (รกrea de la secciรณn transversal), la resistividad del material y el flujo de corriente. La herramienta calcula la caรญda de tensiรณn de ida y vuelta, la resistencia total del cable y la potencia disipada en forma de calor. Resulta especialmente รบtil para ingenieros elรฉctricos, electricistas y aficionados al diseรฑar sistemas elรฉctricos para garantizar que los niveles de tensiรณn se mantengan dentro de los lรญmites aceptables en la carga.",
+ "shortDescription": "Calcular la caรญda de tensiรณn y la pรฉrdida de potencia en cables elรฉctricos en funciรณn de la longitud, el material y la corriente.",
+ "title": "Caรญda de tensiรณn de ida y vuelta en el cable"
+ }
+}
diff --git a/public/locales/es/pdf.json b/public/locales/es/pdf.json
new file mode 100644
index 0000000..7cba89a
--- /dev/null
+++ b/public/locales/es/pdf.json
@@ -0,0 +1,113 @@
+{
+ "compressPdf": {
+ "compressedFileSize": "Tamaรฑo de archivo comprimido",
+ "compressingPdf": "Comprimiendo PDF...",
+ "compressionLevel": "Nivel de compresiรณn",
+ "compressionSettings": "Configuraciรณn de compresiรณn",
+ "description": "Reduzca el tamaรฑo de los archivos PDF manteniendo la calidad usando Ghostscript",
+ "errorCompressingPdf": "Error al comprimir el PDF: {{error}}",
+ "errorReadingPdf": "No se pudo leer el archivo PDF. Asegรบrese de que sea vรกlido.",
+ "fileSize": "Tamaรฑo del archivo original",
+ "highCompression": "Alta compresiรณn",
+ "highCompressionDescription": "Reducciรณn mรกxima del tamaรฑo del archivo con cierta pรฉrdida de calidad",
+ "inputTitle": "PDF de entrada",
+ "lowCompression": "Baja compresiรณn",
+ "lowCompressionDescription": "Reduce ligeramente el tamaรฑo del archivo con una pรฉrdida mรญnima de calidad",
+ "mediumCompression": "Compresiรณn media",
+ "mediumCompressionDescription": "Equilibrio entre el tamaรฑo del archivo y la calidad",
+ "pages": "Nรบmero de pรกginas",
+ "resultTitle": "PDF comprimido",
+ "shortDescription": "Comprime archivos PDF de forma segura en tu navegador",
+ "title": "Comprimir PDF"
+ },
+ "editor": {
+ "description": "Editor de PDF avanzado con funciones de anotaciรณn, rellenado de formularios, resaltado y exportaciรณn. Edite sus PDF directamente en el navegador con herramientas profesionales que incluyen inserciรณn de texto, dibujo, resaltado, firma y rellenado de formularios.",
+ "shortDescription": "Edite archivos PDF con herramientas avanzadas de anotaciรณn, firma y ediciรณn",
+ "title": "Editor de PDF"
+ },
+ "merge": {
+ "inputTitle": "PDF de entrada",
+ "loadingText": "Extrayendo pรกginas",
+ "resultTitle": "Salida PDF fusionada",
+ "toolInfo": {
+ "description": "Esta herramienta permite fusionar varios archivos PDF en un solo documento. Para usarla, simplemente cargue los archivos PDF que desea fusionar. La herramienta combinarรก todas las pรกginas de los archivos de entrada en un solo documento PDF.",
+ "title": "ยฟCรณmo utilizar la herramienta Combinar PDF?"
+ }
+ },
+ "mergePdf": {
+ "description": "Combine varios archivos PDF en un solo documento.",
+ "inputTitle": "Entrada de archivos PDF",
+ "mergingPdfs": "Fusionar archivos PDF",
+ "pdfOptions": "Opciones de PDF",
+ "resultTitle": "PDF fusionado",
+ "shortDescription": "Fusionar varios archivos PDF en un solo documento",
+ "sortByFileName": "Ordenar por nombre de archivo",
+ "sortByFileNameDescription": "Ordenar archivos PDF alfabรฉticamente por nombre de archivo",
+ "sortByUploadOrder": "Ordenar por orden de carga",
+ "sortByUploadOrderDescription": "Mantenga los archivos PDF en el orden en que se cargaron",
+ "title": "Fusionar PDF",
+ "toolInfo": {
+ "description": "Esta herramienta permite combinar varios archivos PDF en un solo documento. Puedes elegir cรณmo ordenar los PDF y la herramienta los combinarรก en el orden especificado.",
+ "title": "Fusionar archivos PDF"
+ }
+ },
+ "pdfToEpub": {
+ "description": "Transforme documentos PDF en archivos EPUB para una mejor compatibilidad con los lectores electrรณnicos.', icon: 'material-symbols:import-contacts', component: lazy(() => import('./index')), keywords: ['pdf', 'epub', 'convert', 'ebook'], path: 'pdf-to-epub', i18n: { name: 'pdf:pdfToEpub.title', description: 'pdf:pdfToEpub.description",
+ "shortDescription": "Convertir archivos PDF al formato EPUB",
+ "title": "PDF a EPUB"
+ },
+ "pdfToPng": {
+ "description": "Transforme documentos PDF en paneles PNG.",
+ "longDescription": "Sube un PDF y convierte cada pรกgina en una imagen PNG de alta calidad directamente en tu navegador. Esta herramienta es ideal para extraer contenido visual o compartir pรกginas individuales. No se cargan datos: todo se ejecuta localmente.",
+ "shortDescription": "Convertir PDF a imรกgenes PNG",
+ "title": "PDF a PNG"
+ },
+ "protectPdf": {
+ "description": "Agregue protecciรณn con contraseรฑa a sus archivos PDF de forma segura en su navegador",
+ "shortDescription": "Proteger con contraseรฑa los archivos PDF de forma segura",
+ "title": "Proteger PDF"
+ },
+ "rotatePdf": {
+ "allPagesWillBeRotated": "Todo {{count}} Las pรกginas se rotarรกn",
+ "angleOptions": {
+ "clockwise90": "90ยฐ en sentido horario",
+ "counterClockwise270": "270ยฐ (90ยฐ en sentido antihorario)",
+ "upsideDown180": "180ยฐ (al revรฉs)"
+ },
+ "applyToAllPages": "Aplicar a todas las pรกginas",
+ "description": "Rotar pรกginas en un documento PDF.",
+ "inputTitle": "PDF de entrada",
+ "longDescription": "Cambie la orientaciรณn de las pรกginas PDF girรกndolas 90, 180 o 270 grados. รtil para corregir documentos escaneados incorrectamente o preparar archivos PDF para imprimir.",
+ "pageRangesDescription": "Introduzca nรบmeros de pรกgina o rangos separados por comas (por ejemplo, 1, 3, 5-7)",
+ "pageRangesPlaceholder": "p. ej., 1,5-8",
+ "pagesWillBeRotated": "{{count}} pรกgina{{count !== 1 ? 's' : ''}} se rotarรก",
+ "pdfPageCount": "PDF tiene {{count}} pรกgina{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "PDF rotado",
+ "rotatingPages": "Pรกginas rotatorias",
+ "rotationAngle": "รngulo de rotaciรณn",
+ "rotationSettings": "Configuraciรณn de rotaciรณn",
+ "shortDescription": "Girar pรกginas en un documento PDF",
+ "title": "Girar PDF",
+ "toolInfo": {
+ "description": "Esta herramienta permite rotar pรกginas en un documento PDF. Puede rotar todas las pรกginas o especificar pรกginas individuales. Elija un รกngulo de rotaciรณn: 90ยฐ en sentido horario, 180ยฐ (invertido) o 270ยฐ (90ยฐ en sentido antihorario). Para rotar pรกginas especรญficas, desmarque la opciรณn \"Aplicar a todas las pรกginas\" e introduzca los nรบmeros de pรกgina o intervalos separados por comas (p. ej., 1, 3, 5-7).",
+ "title": "Cรณmo utilizar la herramienta Rotar PDF"
+ }
+ },
+ "splitPdf": {
+ "description": "Extraer pรกginas especรญficas de un documento PDF.",
+ "extractingPages": "Extrayendo pรกginas",
+ "inputTitle": "PDF de entrada",
+ "pageExtractionPreview": "{{count}} pรกgina{{count !== 1 ? 's' : ''}} se extraerรกn",
+ "pageRangesDescription": "Introduzca nรบmeros de pรกgina o rangos separados por comas (por ejemplo, 1, 3, 5-7)",
+ "pageRangesPlaceholder": "p. ej., 1,5-8",
+ "pageSelection": "Selecciรณn de pรกgina",
+ "pdfPageCount": "PDF tiene {{count}} pรกgina{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "PDF extraรญdo",
+ "shortDescription": "Extraer pรกginas especรญficas de un archivo PDF",
+ "title": "PDF dividido",
+ "toolInfo": {
+ "description": "Esta herramienta permite extraer pรกginas especรญficas de un documento PDF. Puede especificar pรกginas individuales o un rango de pรกginas para extraer.",
+ "title": "PDF dividido"
+ }
+ }
+}
diff --git a/public/locales/es/string.json b/public/locales/es/string.json
new file mode 100644
index 0000000..69075f8
--- /dev/null
+++ b/public/locales/es/string.json
@@ -0,0 +1,261 @@
+{
+ "base64": {
+ "decode": "Descodificaciรณn Base64",
+ "description": "Codificar o decodificar texto utilizando la codificaciรณn Base64.",
+ "encode": "Codificaciรณn Base64",
+ "inputTitle": "Datos de entrada",
+ "optionsTitle": "Opciones de Base64",
+ "resultTitle": "Resultado",
+ "shortDescription": "Codificar o decodificar datos utilizando Base64.",
+ "title": "Codificador/decodificador Base64",
+ "toolInfo": {
+ "description": "Base64 es un esquema de codificaciรณn que representa datos en formato de cadena ASCII traduciรฉndolos a una representaciรณn de base 64. Si bien puede usarse para codificar cadenas, se usa comรบnmente para codificar datos binarios para su transmisiรณn a travรฉs de medios diseรฑados para procesar datos textuales.",
+ "title": "ยฟQuรฉ es Base64?"
+ }
+ },
+ "censor": {
+ "description": "Utilidad para censurar palabras en texto. Cargue su texto en el formulario de entrada de la izquierda, especifique todas las palabras incorrectas en las opciones y obtendrรก el texto censurado al instante en el รกrea de salida. longDescription: 'Con esta herramienta en lรญnea, puede censurar ciertas palabras en cualquier texto. Puede especificar una lista de palabras no deseadas (como palabras malsonantes o palabras secretas) y el programa las reemplazarรก con palabras alternativas y crearรก un texto seguro. Las palabras se pueden especificar en un campo de texto de varias lรญneas en las opciones, introduciendo una palabra por lรญnea.', keywords: ['text', 'censor', 'words', 'characters'], component: lazy(() => import('./index')), i18n: { name: 'string:censor.title', description: 'string:censor.description'",
+ "shortDescription": "Enmascare rรกpidamente las malas palabras o reemplรกcelas con palabras alternativas.",
+ "title": "Censor de texto"
+ },
+ "createPalindrome": {
+ "description": "La utilidad de navegador mรกs sencilla del mundo para crear palรญndromos a partir de cualquier texto. Introduce texto y transfรณrmalo al instante en un palรญndromo que se lee igual de derecho a revรฉs. Perfecto para juegos de palabras, crear patrones de texto simรฉtricos o explorar curiosidades lingรผรญsticas.",
+ "shortDescription": "Crea texto que se lea igual hacia adelante y hacia atrรกs",
+ "title": "Crear palรญndromo"
+ },
+ "extractSubstring": {
+ "description": "La utilidad basada en navegador mรกs sencilla del mundo para extraer subcadenas de texto. Introduce el texto y especifica las posiciones inicial y final para extraer la parte deseada. Perfecta para el procesamiento de datos, el anรกlisis de texto o la extracciรณn de contenido especรญfico de bloques de texto mรกs grandes.",
+ "shortDescription": "Extraer una porciรณn de texto entre posiciones especรญficas",
+ "title": "Extraer subcadena"
+ },
+ "join": {
+ "blankLinesAndTrailingSpaces": "Lรญneas en blanco y espacios finales",
+ "deleteBlankDescription": "Eliminar lรญneas que no tengan sรญmbolos de texto.",
+ "deleteBlankTitle": "Eliminar lรญneas en blanco",
+ "deleteTrailingDescription": "Eliminar espacios y tabulaciones al final de las lรญneas.",
+ "deleteTrailingTitle": "Eliminar espacios finales",
+ "description": "Une fragmentos de texto con separadores personalizables.",
+ "inputTitle": "Fragmentos de texto",
+ "joinCharacterDescription": "Sรญmbolo que conecta fragmentos de texto. (Espacio por defecto).",
+ "joinCharacterPlaceholder": "Unirse al personaje",
+ "resultTitle": "Texto unido",
+ "shortDescription": "Unir elementos de texto con un separador especificado",
+ "textMergedOptions": "Opciones de texto fusionado",
+ "title": "Unirse al texto",
+ "toolInfo": {
+ "description": "Con esta herramienta puedes unir partes del texto. Toma una lista de valores de texto, separados por saltos de lรญnea, y los fusiona. Puedes configurar el carรกcter que se colocarรก entre las partes del texto combinado. Tambiรฉn puedes ignorar todas las lรญneas vacรญas y eliminar los espacios y tabulaciones al final de todas las lรญneas. ยกTextabulento!",
+ "title": "ยฟQuรฉ es un ensamblador de texto?"
+ }
+ },
+ "palindrome": {
+ "description": "La utilidad de navegador mรกs sencilla del mundo para comprobar si un texto es un palรญndromo. Comprueba al instante si tu texto se lee igual de adelante hacia atrรกs. Ideal para juegos de palabras, anรกlisis lingรผรญsticos o la validaciรณn de patrones de texto simรฉtricos. Admite varios delimitadores y detecciรณn de palรญndromos de varias palabras.",
+ "shortDescription": "Comprueba si el texto se lee igual hacia adelante y hacia atrรกs",
+ "title": "Palรญndromo"
+ },
+ "passwordGenerator": {
+ "avoidAmbiguous": "Evite caracteres ambiguos (i, I, l, 0, O)",
+ "description": "Genere contraseรฑas aleatorias seguras con longitud y tipos de caracteres personalizables. Elija entre minรบsculas, mayรบsculas, nรบmeros y caracteres especiales. Opciรณn para evitar caracteres ambiguos para una mejor legibilidad.",
+ "includeLowercase": "Incluir letras minรบsculas (a-z)",
+ "includeNumbers": "Incluir nรบmeros (0-9)",
+ "includeSymbols": "Incluir caracteres especiales",
+ "includeUppercase": "Incluir letras mayรบsculas (A-Z)",
+ "lengthDesc": "Longitud de la contraseรฑa",
+ "lengthPlaceholder": "p. ej. 12",
+ "optionsTitle": "Opciones de contraseรฑa",
+ "resultTitle": "Contraseรฑa generada",
+ "shortDescription": "Genere contraseรฑas aleatorias seguras con opciones personalizadas",
+ "title": "Generador de contraseรฑas",
+ "toolInfo": {
+ "description": "Esta herramienta genera contraseรฑas aleatorias seguras segรบn los criterios que selecciones. Puedes personalizar la longitud, incluir o excluir diferentes tipos de caracteres y evitar caracteres ambiguos para una mejor legibilidad. Perfecta para crear contraseรฑas seguras para cuentas, aplicaciones o cualquier necesidad de seguridad.",
+ "title": "Acerca del generador de contraseรฑas"
+ }
+ },
+ "quote": {
+ "allowDoubleQuotation": "Permitir comillas dobles",
+ "description": "Agregue comillas alrededor del texto con opciones personalizables.",
+ "inputTitle": "Texto de entrada",
+ "leftQuoteDescription": "Carรกcter(es) de comillas izquierdas",
+ "processAsMultiLine": "Procesar como texto de varias lรญneas",
+ "quoteEmptyLines": "Citar lรญneas vacรญas",
+ "quoteOptions": "Opciones de cotizaciรณn",
+ "resultTitle": "Texto citado",
+ "rightQuoteDescription": "Carรกcter(es) de comillas derechas",
+ "shortDescription": "Agregue comillas alrededor del texto con varios estilos",
+ "title": "Citador de texto",
+ "toolInfo": {
+ "description": "Esta herramienta permite aรฑadir comillas al texto. Permite elegir diferentes caracteres de comillas, gestionar texto multilรญnea y controlar el procesamiento de lรญneas vacรญas. Resulta รบtil para preparar texto para programaciรณn, formatear datos o crear texto estilizado.",
+ "title": "Citador de texto"
+ }
+ },
+ "randomizeCase": {
+ "description": "La utilidad de navegador mรกs sencilla del mundo para aleatorizar mayรบsculas y minรบsculas. Introduce tu texto y transfรณrmalo al instante con mayรบsculas y minรบsculas aleatorias. Perfecta para crear efectos de texto รบnicos, comprobar la distinciรณn entre mayรบsculas y minรบsculas o generar patrones de texto variados.",
+ "shortDescription": "Aleatorizar el caso de las letras en el texto",
+ "title": "Aleatorizar caso"
+ },
+ "removeDuplicateLines": {
+ "description": "Carga tu texto en el formulario de entrada de la izquierda y obtendrรกs texto al instante sin lรญneas duplicadas en el รกrea de salida. Potente, gratuito y rรกpido. Carga lรญneas de texto: obtรฉn lรญneas de texto รบnicas.",
+ "shortDescription": "Eliminar rรกpidamente todas las lรญneas repetidas del texto",
+ "title": "Eliminar lรญneas duplicadas"
+ },
+ "repeat": {
+ "delimiterDescription": "Delimitador para copias de salida.",
+ "delimiterPlaceholder": "Delimitador",
+ "description": "Repita el texto varias veces con separadores personalizables.",
+ "inputTitle": "Texto de entrada",
+ "numberPlaceholder": "Nรบmero",
+ "repeatAmountDescription": "Nรบmero de repeticiones.",
+ "repetitionsDelimiter": "Delimitador de repeticiones",
+ "resultTitle": "Texto repetido",
+ "shortDescription": "Repetir el texto varias veces",
+ "textRepetitions": "Repeticiones de texto",
+ "title": "Repetir texto",
+ "toolInfo": {
+ "description": "Esta herramienta le permite repetir un texto determinado varias veces con un separador opcional.",
+ "title": "Repetir texto"
+ }
+ },
+ "reverse": {
+ "description": "La utilidad de navegador mรกs sencilla del mundo para invertir texto. Introduce cualquier texto y revรญsalo al instante, carรกcter por carรกcter. Perfecta para crear texto espejo, analizar palรญndromos o experimentar con patrones de texto. Conserva los espacios y caracteres especiales al invertir.",
+ "inputTitle": "Texto para revertir",
+ "processMultiLine": "Procesar texto de varias lรญneas",
+ "processMultiLineDescription": "Cada lรญnea se invertirรก independientemente",
+ "resultTitle": "Texto invertido",
+ "reversalOptions": "Opciones de reversiรณn",
+ "shortDescription": "Invertir cualquier texto carรกcter por carรกcter",
+ "skipEmptyLines": "Saltar lรญneas vacรญas",
+ "skipEmptyLinesDescription": "Las lรญneas vacรญas se eliminarรกn de la salida.",
+ "title": "Contrarrestar",
+ "trimWhitespace": "Recortar espacios en blanco",
+ "trimWhitespaceDescription": "Eliminar los espacios iniciales y finales de cada lรญnea"
+ },
+ "rot13": {
+ "description": "Codificar o decodificar texto utilizando el cifrado ROT13.",
+ "inputTitle": "Texto de entrada",
+ "resultTitle": "Resultado de ROT13",
+ "shortDescription": "Codificar o decodificar texto utilizando el cifrado ROT13.",
+ "title": "Codificador/decodificador ROT13",
+ "toolInfo": {
+ "description": "ROT13 (rotaciรณn de 13 posiciones) es un cifrado simple de sustituciรณn de letras que reemplaza una letra por la decimotercera letra siguiente en el alfabeto. ROT13 es un caso especial del cifrado Cรฉsar, desarrollado en la antigua Roma. Dado que el alfabeto inglรฉs tiene 26 letras, ROT13 es su propio inverso; es decir, para deshacer ROT13, se aplica el mismo algoritmo, por lo que se puede usar la misma acciรณn para codificar y decodificar.",
+ "title": "ยฟQuรฉ es ROT13?"
+ }
+ },
+ "rotate": {
+ "description": "Girar caracteres en el texto en posiciones especรญficas.",
+ "inputTitle": "Texto de entrada",
+ "processAsMultiLine": "Procesar como texto de varias lรญneas (rotar cada lรญnea por separado)",
+ "resultTitle": "Texto rotado",
+ "rotateLeft": "Girar a la izquierda",
+ "rotateRight": "Girar a la derecha",
+ "rotationOptions": "Opciones de rotaciรณn",
+ "shortDescription": "Desplazar caracteres en el texto por posiciรณn.",
+ "stepDescription": "Nรบmero de posiciones a rotar",
+ "title": "Girar texto",
+ "toolInfo": {
+ "description": "Esta herramienta permite rotar caracteres en una cadena un nรบmero especรญfico de posiciones. Puede rotar a la izquierda o a la derecha, y procesar texto de varias lรญneas rotando cada lรญnea por separado. La rotaciรณn de cadenas es รบtil para transformaciones de texto simples, la creaciรณn de patrones o la implementaciรณn de tรฉcnicas bรกsicas de cifrado.",
+ "title": "Rotaciรณn de cuerdas"
+ }
+ },
+ "split": {
+ "charAfterChunkDescription": "Carรกcter despuรฉs de cada fragmento",
+ "charBeforeChunkDescription": "Carรกcter antes de cada fragmento",
+ "chunksDescription": "Nรบmero de fragmentos de igual longitud en la salida.",
+ "chunksTitle": "Utilice varios fragmentos",
+ "description": "La utilidad para navegador mรกs sencilla del mundo para dividir texto. Introduce tu texto y especifica un separador para dividirlo en varias partes. Ideal para procesar datos, manipular texto o extraer contenido especรญfico de bloques de texto mรกs grandes.",
+ "lengthDescription": "Nรบmero de sรญmbolos que se colocarรกn en cada fragmento de salida.",
+ "lengthTitle": "Utilice la longitud para dividir",
+ "outputSeparatorDescription": "Carรกcter que se colocarรก entre los fragmentos divididos. (Por defecto, es el salto de lรญnea \"\\n\").",
+ "outputSeparatorOptions": "Opciones de separador de salida",
+ "regexDescription": "Expresiรณn regular que se usarรก para dividir el texto en partes. (Mรบltiples espacios por defecto).",
+ "regexTitle": "Utilice una expresiรณn regular para dividir",
+ "resultTitle": "Fragmentos de texto",
+ "shortDescription": "Dividir el texto en varias partes usando un separador",
+ "splitSeparatorOptions": "Opciones de separador dividido",
+ "symbolDescription": "Carรกcter que se utilizarรก para dividir el texto en partes. (Espacio por defecto).",
+ "symbolTitle": "Utilice un sรญmbolo para dividir",
+ "title": "Dividir"
+ },
+ "statistic": {
+ "characterFrequencyAnalysis": "Anรกlisis de frecuencia de caracteres",
+ "characterFrequencyAnalysisDescription": "Cuenta con quรฉ frecuencia aparece cada carรกcter en el texto.",
+ "delimitersOptions": "Opciones de delimitadores",
+ "description": "Analizar texto y generar estadรญsticas completas.",
+ "includeEmptyLines": "Incluir lรญneas vacรญas",
+ "includeEmptyLinesDescription": "Incluya lรญneas en blanco al contar lรญneas",
+ "inputTitle": "Texto de entrada",
+ "resultTitle": "Estadรญsticas de texto",
+ "sentenceDelimitersDescription": "Introduzca caracteres personalizados utilizados para delimitar oraciones en su idioma (separados por coma) o dรฉjelo en blanco como valor predeterminado.",
+ "sentenceDelimitersPlaceholder": "p.ej. ., !, ?, ...",
+ "shortDescription": "Obtenga estadรญsticas sobre su texto",
+ "statisticsOptions": "Opciones de estadรญsticas",
+ "title": "Estadรญsticas de texto",
+ "toolInfo": {
+ "description": "Esta herramienta le permite analizar texto y generar estadรญsticas completas que incluyen recuento de caracteres, recuento de palabras, recuento de lรญneas y anรกlisis de frecuencia de caracteres y palabras.",
+ "title": "ยฟQuรฉ es un? {{title}}?"
+ },
+ "wordDelimitersDescription": "Ingrese una expresiรณn regular personalizada para contar palabras o dรฉjela en blanco para el valor predeterminado.",
+ "wordDelimitersPlaceholder": "p. ej. \\s.,;:!?\"ยซยป()โฆ",
+ "wordFrequencyAnalysis": "Anรกlisis de frecuencia de palabras",
+ "wordFrequencyAnalysisDescription": "Cuenta con quรฉ frecuencia aparece cada palabra en el texto."
+ },
+ "textReplacer": {
+ "description": "Reemplazar patrones de texto con contenido nuevo.",
+ "findPatternInText": "Encuentra este patrรณn en el texto",
+ "findPatternUsingRegexp": "Encontrar un patrรณn usando una expresiรณn regular",
+ "inputTitle": "Texto a reemplazar",
+ "newTextPlaceholder": "Nuevo texto",
+ "regexpDescription": "Introduzca la expresiรณn regular que desea reemplazar.",
+ "replacePatternDescription": "Introduzca el patrรณn que se utilizarรก para el reemplazo.",
+ "replaceText": "Reemplazar texto",
+ "resultTitle": "Texto con reemplazos",
+ "searchPatternDescription": "Introduzca el patrรณn de texto que desea reemplazar.",
+ "searchText": "Buscar texto",
+ "shortDescription": "Reemplace rรกpidamente el texto en su contenido",
+ "title": "Reemplazador de texto",
+ "toolInfo": {
+ "description": "Reemplace fรกcilmente texto especรญfico en su contenido con esta sencilla herramienta basada en navegador. Simplemente ingrese el texto, configure el texto que desea reemplazar y el valor de reemplazo, y obtenga la versiรณn actualizada al instante.",
+ "title": "Reemplazador de texto"
+ }
+ },
+ "toMorse": {
+ "dashSymbolDescription": "Sรญmbolo que corresponderรก al guiรณn en cรณdigo Morse.",
+ "description": "Convertir texto a cรณdigo Morse.",
+ "dotSymbolDescription": "Sรญmbolo que corresponderรก al punto en cรณdigo Morse.",
+ "longSignal": "Seรฑal larga",
+ "resultTitle": "Cรณdigo Morse",
+ "shortDescription": "Codifique rรกpidamente texto en morse",
+ "shortSignal": "Seรฑal corta",
+ "title": "Cadena a morse"
+ },
+ "truncate": {
+ "addTruncationIndicator": "Agregar indicador de truncamiento",
+ "charactersPlaceholder": "Personajes",
+ "description": "Acortar el texto a una longitud especรญfica.",
+ "indicatorDescription": "Caracteres que se aรฑaden al final (o al principio) del texto. Nota: Se consideran para la longitud.",
+ "inputTitle": "Texto de entrada",
+ "leftSideDescription": "Eliminar caracteres del inicio del texto.",
+ "leftSideTruncation": "Truncamiento del lado izquierdo",
+ "lengthAndLines": "Longitud y lรญneas",
+ "lineByLineDescription": "Truncar cada lรญnea por separado.",
+ "lineByLineTruncating": "Truncamiento lรญnea por lรญnea",
+ "maxLengthDescription": "Nรบmero de caracteres a dejar en el texto.",
+ "numberPlaceholder": "Nรบmero",
+ "resultTitle": "Texto truncado",
+ "rightSideDescription": "Eliminar caracteres del final del texto.",
+ "rightSideTruncation": "Truncamiento del lado derecho",
+ "shortDescription": "Truncar texto a una longitud especificada",
+ "suffixAndAffix": "Sufijo y afijo",
+ "title": "Truncar texto",
+ "toolInfo": {
+ "description": "Cargue su texto en el formulario de entrada de la izquierda y obtendrรก automรกticamente el texto truncado a la derecha.",
+ "title": "Truncar texto"
+ },
+ "truncationSide": "Lado de truncamiento"
+ },
+ "uppercase": {
+ "description": "Convertir texto a letras mayรบsculas.",
+ "inputTitle": "Texto de entrada",
+ "resultTitle": "Texto en mayรบsculas",
+ "shortDescription": "Convertir texto a mayรบsculas",
+ "title": "Convertir a mayรบsculas"
+ }
+}
diff --git a/public/locales/es/time.json b/public/locales/es/time.json
new file mode 100644
index 0000000..84ac090
--- /dev/null
+++ b/public/locales/es/time.json
@@ -0,0 +1,100 @@
+{
+ "checkLeapYears": {
+ "description": "Compruebe si un aรฑo es bisiesto y obtenga informaciรณn sobre el aรฑo bisiesto.",
+ "inputTitle": "Aรฑo de entrada",
+ "resultTitle": "Resultado del aรฑo bisiesto",
+ "shortDescription": "Comprobar si un aรฑo es bisiesto",
+ "title": "Consultar aรฑos bisiestos",
+ "toolInfo": {
+ "description": "Un aรฑo bisiesto es un aรฑo que contiene un dรญa adicional (29 de febrero) para mantener la sincronizaciรณn del aรฑo calendario con el aรฑo astronรณmico. Los aรฑos bisiestos ocurren cada 4 aรฑos, excepto los aรฑos divisibles por 100, pero no por 400.",
+ "title": "ยฟQuรฉ es un aรฑo bisiesto?"
+ }
+ },
+ "convertDaysToHours": {
+ "addHoursName": "Agregar nombre de horas",
+ "addHoursNameDescription": "Aรฑade la cadena horas a los valores de salida",
+ "description": "Convierta dรญas en horas con opciones personalizables.",
+ "hoursName": "Horas Nombre",
+ "shortDescription": "Convertir dรญas a horas",
+ "title": "Convertir dรญas a horas",
+ "toolInfo": {
+ "description": "Esta herramienta permite convertir dรญas a horas. Puede introducir los dรญas como nรบmeros o con unidades, y la herramienta los convertirรก a horas. Tambiรฉn puede aรฑadir el sufijo \"horas\" a los valores de salida.",
+ "title": "Convertir dรญas a horas"
+ }
+ },
+ "convertHoursToDays": {
+ "addDaysName": "Agregar nombre de dรญas",
+ "addDaysNameDescription": "Aรฑade la cadena dรญas a los valores de salida",
+ "daysName": "Nombre de los dรญas",
+ "description": "Convierte horas en dรญas con opciones personalizables.",
+ "shortDescription": "Convertir horas a dรญas",
+ "title": "Convertir horas a dรญas",
+ "toolInfo": {
+ "description": "Esta herramienta permite convertir horas a dรญas. Puede introducir las horas como nรบmeros o con unidades, y la herramienta las convertirรก a dรญas. Tambiรฉn puede aรฑadir el sufijo \"dรญas\" a los valores de salida.",
+ "title": "Convertir horas a dรญas"
+ }
+ },
+ "convertSecondsToTime": {
+ "addPadding": "Aรฑadir relleno",
+ "addPaddingDescription": "Aรฑade relleno de ceros a las horas, minutos y segundos.",
+ "description": "Convierte los segundos a un formato de hora legible (horas:minutos:segundos). Introduce la cantidad de segundos para obtener la hora formateada.",
+ "shortDescription": "Convertir segundos a formato de hora",
+ "timePadding": "Relleno de tiempo",
+ "title": "Convertir segundos a tiempo",
+ "toolInfo": {
+ "title": "ยฟQuรฉ es un? {{title}}?"
+ }
+ },
+ "convertTimeToSeconds": {
+ "description": "Convierte la hora formateada (HH:MM:SS) a segundos.",
+ "inputTitle": "Hora de entrada",
+ "resultTitle": "Artรญculos de segunda clase",
+ "shortDescription": "Convertir formato de hora a segundos",
+ "title": "Convertir tiempo a segundos",
+ "toolInfo": {
+ "description": "Esta herramienta permite convertir cadenas de tiempo formateadas (HH:MM:SS) a segundos. Resulta รบtil para calcular duraciones e intervalos de tiempo.",
+ "title": "Convertir tiempo a segundos"
+ }
+ },
+ "crontabGuru": {
+ "description": "Generar y comprender expresiones cron. Crear programaciones cron para tareas automatizadas y trabajos del sistema.",
+ "shortDescription": "Generar y comprender expresiones cron",
+ "title": "Gurรบ de Crontab"
+ },
+ "timeBetweenDates": {
+ "description": "Calcula la diferencia horaria entre dos fechas. Obtรฉn la duraciรณn exacta en dรญas, horas, minutos y segundos.",
+ "endDate": "Fecha de finalizaciรณn",
+ "endDateTime": "Fecha y hora de finalizaciรณn",
+ "endTime": "Fin de los tiempos",
+ "endTimezone": "Zona horaria final",
+ "shortDescription": "Calcular el tiempo entre dos fechas",
+ "startDate": "Fecha de inicio",
+ "startDateTime": "Fecha y hora de inicio",
+ "startTime": "Hora de inicio",
+ "startTimezone": "Zona horaria de inicio",
+ "title": "Tiempo entre fechas",
+ "toolInfo": {
+ "description": "Calcula la diferencia horaria exacta entre dos fechas y horas, compatible con diferentes zonas horarias. Esta herramienta proporciona un desglose detallado de la diferencia horaria en varias unidades (aรฑos, meses, dรญas, horas, minutos y segundos).",
+ "title": "Calculadora de tiempo entre fechas"
+ }
+ },
+ "truncateClockTime": {
+ "description": "Trunca la hora del reloj para quitar segundos o minutos. Redondea la hora a la hora, minuto o intervalo personalizado mรกs cercano.",
+ "printDroppedComponents": "Imprimir componentes descartados",
+ "shortDescription": "Truncar el tiempo del reloj a la precisiรณn especificada",
+ "timePadding": "Relleno de tiempo",
+ "title": "Truncar el tiempo del reloj",
+ "toolInfo": {
+ "title": "ยฟQuรฉ es un? {{title}}?"
+ },
+ "truncateMinutesAndSeconds": "Truncar minutos y segundos",
+ "truncateMinutesAndSecondsDescription": "Elimina ambos componentes: los minutos y los segundos de cada hora del reloj.",
+ "truncateOnlySeconds": "Truncar solo segundos",
+ "truncateOnlySecondsDescription": "Elimina el componente de segundos de cada hora del reloj.",
+ "truncationSide": "Lado de truncamiento",
+ "useZeroPadding": "Utilice relleno de ceros",
+ "zeroPaddingDescription": "Haga que todos los componentes de tiempo siempre tengan dos dรญgitos de ancho.",
+ "zeroPrintDescription": "Muestra las partes descartadas como valores cero \"00\".",
+ "zeroPrintTruncatedParts": "Piezas truncadas de impresiรณn cero"
+ }
+}
diff --git a/public/locales/es/translation.json b/public/locales/es/translation.json
new file mode 100644
index 0000000..3bec9ef
--- /dev/null
+++ b/public/locales/es/translation.json
@@ -0,0 +1,250 @@
+{
+ "audio": {
+ "changeSpeed": {
+ "description": "Cambia la velocidad de reproducciรณn de los archivos de audio. Acelera o ralentiza el audio manteniendo el tono.",
+ "name": "Cambiar la velocidad del audio",
+ "shortDescription": "Cambiar la velocidad de los archivos de audio"
+ },
+ "extractAudio": {
+ "description": "Extraiga la pista de audio de un archivo de vรญdeo y guรกrdelo como un archivo de audio separado en el formato elegido (AAC, MP3, WAV).",
+ "name": "Extraer audio",
+ "shortDescription": "Extrae audio de archivos de vรญdeo (MP4, MOV, etc.) a AAC, MP3 o WAV."
+ }
+ },
+ "baseFileInput": {
+ "copyFailed": "No se pudo copiar: {{error}}",
+ "dropFileHere": "Deja tu {{type}} aquรญ",
+ "fileCopied": "Archivo copiado",
+ "selectFileDescription": "Haga clic aquรญ para seleccionar uno {{type}} Desde su dispositivo, presione Ctrl+V para usar un {{type}} desde su portapapeles, o arrastre y suelte un archivo desde el escritorio"
+ },
+ "categories": {
+ "audio": {
+ "description": "Herramientas para trabajar con audio: extraer audio de vรญdeo, ajustar la velocidad del audio, fusionar varios archivos de audio y mucho mรกs.",
+ "title": "Herramientas de audio"
+ },
+ "csv": {
+ "description": "Herramientas para trabajar con archivos CSV: convierta CSV a diferentes formatos, manipule datos CSV, valide la estructura CSV y procese archivos CSV de manera eficiente.",
+ "title": "Herramientas CSV"
+ },
+ "gif": {
+ "description": "Herramientas para trabajar con animaciones GIF: cree GIF transparentes, extraiga marcos GIF, agregue texto a GIF, recorte, rote, invierta GIF y mucho mรกs.",
+ "title": "Herramientas GIF"
+ },
+ "image-generic": {
+ "description": "Herramientas para trabajar con imรกgenes: comprimir, redimensionar, recortar, convertir a JPG, rotar, eliminar fondo y mucho mรกs.",
+ "title": "Herramientas de imagen"
+ },
+ "json": {
+ "description": "Herramientas para trabajar con estructuras de datos JSON: embellecer y minimizar objetos JSON, aplanar matrices JSON, convertir valores JSON en cadenas, analizar datos y mucho mรกs",
+ "title": "Herramientas JSON"
+ },
+ "list": {
+ "description": "Herramientas para trabajar con listas: ordenar, invertir, aleatorizar listas, encontrar elementos de listas รบnicos y duplicados, cambiar separadores de elementos de listas y mucho mรกs.",
+ "title": "Herramientas de lista"
+ },
+ "number": {
+ "description": "Herramientas para trabajar con nรบmeros: generar secuencias numรฉricas, convertir nรบmeros en palabras y palabras en nรบmeros, ordenar, redondear, factorizar nรบmeros y mucho mรกs.",
+ "title": "Herramientas numรฉricas"
+ },
+ "pdf": {
+ "description": "Herramientas para trabajar con archivos PDF: extraer texto de archivos PDF, convertir archivos PDF a otros formatos, manipular archivos PDF y mucho mรกs.",
+ "title": "Herramientas PDF"
+ },
+ "png": {
+ "description": "Herramientas para trabajar con imรกgenes PNG: convierta PNG a JPG, cree PNG transparentes, cambie colores PNG, recorte, rote, cambie el tamaรฑo de PNG y mucho mรกs.",
+ "title": "Herramientas PNG"
+ },
+ "seeAll": "Ver todo {{title}}",
+ "string": {
+ "description": "Herramientas para trabajar con texto: convertir texto en imรกgenes, buscar y reemplazar texto, dividir texto en fragmentos, unir lรญneas de texto, repetir texto y mucho mรกs.",
+ "title": "Herramientas de texto"
+ },
+ "time": {
+ "description": "Herramientas para trabajar con hora y fecha: calcular diferencias horarias, convertir entre zonas horarias, formatear fechas, generar secuencias de fechas y mucho mรกs.",
+ "title": "Herramientas de tiempo"
+ },
+ "try": "Intentar {{title}}",
+ "video": {
+ "description": "Herramientas para trabajar con vรญdeos: extrae fotogramas de vรญdeos, crea GIF a partir de vรญdeos, convierte vรญdeos a diferentes formatos y mucho mรกs.",
+ "title": "Herramientas de vรญdeo"
+ },
+ "xml": {
+ "description": "Herramientas para trabajar con estructuras de datos XML: visor, embellecedor, validador y mucho mรกs",
+ "title": "Herramientas XML"
+ }
+ },
+ "csv": {
+ "findIncompleteCsvRecords": {
+ "description": "Simplemente cargue su archivo CSV en el formulario a continuaciรณn y esta herramienta comprobarรก automรกticamente si ninguna fila o columna tiene valores faltantes. En las opciones de la herramienta, puede ajustar el formato del archivo de entrada (especifique el delimitador, las comillas y el carรกcter de comentario). Ademรกs, puede activar la comprobaciรณn de valores vacรญos, omitir lรญneas vacรญas y limitar el nรบmero de mensajes de error en la salida.",
+ "name": "Encontrar registros CSV incompletos",
+ "shortDescription": "Encuentre rรกpidamente filas y columnas en CSV que tengan valores faltantes."
+ }
+ },
+ "hero": {
+ "brand": "OmniTools",
+ "description": "Aumente su productividad con OmniTools, ยกel kit de herramientas definitivo para agilizar su trabajo! Acceda a miles de utilidades intuitivas para editar imรกgenes, texto, listas y datos, todo directamente desde su navegador.",
+ "examples": {
+ "calculateNumberSum": "Calcular la suma de nรบmeros",
+ "changeGifSpeed": "Cambiar la velocidad del GIF",
+ "compressPng": "Comprimir PNG",
+ "createTransparentImage": "Crear una imagen transparente",
+ "prettifyJson": "Embellecer JSON",
+ "sortList": "Ordenar una lista",
+ "splitPdf": "PDF dividido",
+ "splitText": "Dividir un texto",
+ "trimVideo": "Recortar vรญdeo"
+ },
+ "searchPlaceholder": "Buscar en todas las herramientas",
+ "title": "Haga las cosas rรกpidamente con"
+ },
+ "inputFooter": {
+ "clear": "Claro",
+ "copyToClipboard": "Copiar al portapapeles",
+ "importFromFile": "Importar desde archivo"
+ },
+ "list": {
+ "group": {
+ "description": "La utilidad basada en navegador mรกs sencilla del mundo para agrupar elementos de listas. Introduce tu lista y especifica los criterios de agrupaciรณn para organizar los elementos en grupos lรณgicos. Perfecta para categorizar datos, organizar informaciรณn o crear listas estructuradas. Admite separadores personalizados y diversas opciones de agrupaciรณn.",
+ "name": "Grupo",
+ "shortDescription": "Agrupar elementos de la lista por propiedades comunes"
+ },
+ "reverse": {
+ "description": "Esta sencilla aplicaciรณn basada en navegador imprime todos los elementos de la lista en orden inverso. Los elementos de entrada se pueden separar con cualquier sรญmbolo y tambiรฉn se puede cambiar el separador de los elementos de la lista invertidos.",
+ "name": "Contrarrestar",
+ "shortDescription": "Invertir una lista rรกpidamente"
+ },
+ "sort": {
+ "description": "Esta es una aplicaciรณn sรบper sencilla basada en navegador que ordena los elementos de una lista en orden creciente o decreciente. Puedes ordenar los elementos alfabรฉticamente, numรฉricamente o por longitud. Tambiรฉn puedes eliminar elementos duplicados y vacรญos, asรญ como recortar elementos individuales con espacios en blanco. Puedes usar cualquier carรกcter separador para separar los elementos de la lista de entrada o, alternativamente, usar una expresiรณn regular. Ademรกs, puedes crear un nuevo delimitador para la lista de salida ordenada.",
+ "name": "Clasificar",
+ "shortDescription": "Ordenar rรกpidamente una lista"
+ }
+ },
+ "navbar": {
+ "buyMeACoffee": "Invรญtame a un cafรฉ",
+ "home": "Hogar",
+ "tools": "Herramientas"
+ },
+ "number": {
+ "generate": {
+ "description": "Calcule rรกpidamente una lista de enteros en su navegador. Para obtener la lista, simplemente especifique el primer entero, el valor de cambio y el recuento total en las opciones a continuaciรณn, y esta utilidad generarรก esa cantidad de enteros.",
+ "name": "Generar nรบmeros",
+ "shortDescription": "Calcula rรกpidamente una lista de nรบmeros enteros en tu navegador"
+ },
+ "sum": {
+ "description": "Esta es una aplicaciรณn sรบper sencilla para navegador que suma nรบmeros. Los nรบmeros ingresados se pueden separar con cualquier sรญmbolo y tambiรฉn se puede cambiar el separador de los nรบmeros sumados.",
+ "name": "Sumar nรบmeros",
+ "shortDescription": "Sumar rรกpidamente una lista de nรบmeros"
+ }
+ },
+ "numericInputWithUnit": {
+ "unit": "Unidad"
+ },
+ "pdf": {
+ "compressPdf": {
+ "description": "Reduzca el tamaรฑo de los archivos PDF manteniendo la calidad usando Ghostscript",
+ "name": "Comprimir PDF",
+ "shortDescription": "Comprime archivos PDF de forma segura en tu navegador"
+ },
+ "mergePdf": {
+ "description": "Combine varios archivos PDF en un solo documento.",
+ "name": "Fusionar PDF",
+ "shortDescription": "Fusionar varios archivos PDF en un solo documento"
+ },
+ "pdfToEpub": {
+ "description": "Transforme documentos PDF en archivos EPUB para una mejor compatibilidad con los lectores electrรณnicos.",
+ "name": "PDF a EPUB",
+ "shortDescription": "Convertir archivos PDF al formato EPUB"
+ },
+ "protectPdf": {
+ "description": "Agregue protecciรณn con contraseรฑa a sus archivos PDF de forma segura en su navegador",
+ "name": "Proteger PDF",
+ "shortDescription": "Proteger con contraseรฑa los archivos PDF de forma segura"
+ },
+ "splitPdf": {
+ "description": "Extraer pรกginas especรญficas de un archivo PDF usando nรบmeros de pรกgina o rangos (por ejemplo, 1,5-8)",
+ "name": "PDF dividido",
+ "shortDescription": "Extraer pรกginas especรญficas de un archivo PDF"
+ }
+ },
+ "resultFooter": {
+ "copy": "Copiar al portapapeles",
+ "download": "Descargar"
+ },
+ "string": {
+ "createPalindrome": {
+ "description": "La utilidad de navegador mรกs sencilla del mundo para crear palรญndromos a partir de cualquier texto. Introduce texto y transfรณrmalo al instante en un palรญndromo que se lee igual de derecho a revรฉs. Perfecto para juegos de palabras, crear patrones de texto simรฉtricos o explorar curiosidades lingรผรญsticas.",
+ "name": "Crear palรญndromo",
+ "shortDescription": "Crea texto que se lea igual hacia adelante y hacia atrรกs"
+ },
+ "palindrome": {
+ "description": "La utilidad de navegador mรกs sencilla del mundo para comprobar si un texto es un palรญndromo. Comprueba al instante si tu texto se lee igual de adelante hacia atrรกs. Ideal para juegos de palabras, anรกlisis lingรผรญsticos o la validaciรณn de patrones de texto simรฉtricos. Admite varios delimitadores y detecciรณn de palรญndromos de varias palabras.",
+ "name": "Palรญndromo",
+ "shortDescription": "Comprueba si el texto se lee igual hacia adelante y hacia atrรกs"
+ },
+ "repeat": {
+ "description": "Esta herramienta le permite repetir un texto determinado varias veces con un separador opcional.",
+ "name": "Repetir texto",
+ "shortDescription": "Repetir el texto varias veces"
+ },
+ "reverse": {
+ "description": "La utilidad de navegador mรกs sencilla del mundo para invertir texto. Introduce cualquier texto y revรญsalo al instante, carรกcter por carรกcter. Perfecta para crear texto espejo, analizar palรญndromos o experimentar con patrones de texto. Conserva los espacios y caracteres especiales al invertir.",
+ "name": "Contrarrestar",
+ "shortDescription": "Invertir cualquier texto carรกcter por carรกcter"
+ },
+ "toMorse": {
+ "description": "La utilidad de navegador mรกs sencilla del mundo para convertir texto a cรณdigo Morse. Carga tu texto en el formulario de entrada de la izquierda y obtendrรกs cรณdigo Morse al instante en el รกrea de salida. Potente, gratuito y rรกpido. Carga texto y obtรฉn cรณdigo Morse.",
+ "name": "Cadena a morse",
+ "shortDescription": "Codifique rรกpidamente texto en morse"
+ },
+ "uppercase": {
+ "description": "La utilidad para navegador mรกs sencilla del mundo para convertir texto a mayรบsculas. Simplemente introduce tu texto y se convertirรก automรกticamente a mayรบsculas. Ideal para crear titulares, enfatizar texto o estandarizar su formato. Admite varios formatos de texto y conserva caracteres especiales.",
+ "name": "Mayรบsculas",
+ "shortDescription": "Convertir texto a letras mayรบsculas"
+ }
+ },
+ "toolExamples": {
+ "subtitle": "ยกHaga clic para probar!",
+ "title": "{{title}} Ejemplos"
+ },
+ "toolFileResult": {
+ "copied": "Archivo copiado",
+ "copyFailed": "No se pudo copiar: {{error}}",
+ "loading": "Cargando... Esto puede tardar un momento.",
+ "result": "Resultado"
+ },
+ "toolHeader": {
+ "seeExamples": "Ver ejemplos"
+ },
+ "toolLayout": {
+ "allToolsTitle": "Todo {{type}}"
+ },
+ "toolMultiFileResult": {
+ "copied": "Archivo copiado",
+ "copyFailed": "No se pudo copiar: {{error}}",
+ "loading": "Cargando... Esto puede tardar un momento.",
+ "result": "Resultado"
+ },
+ "toolMultipleAudioInput": {
+ "inputTitle": "Aporte {{type}}",
+ "noFilesSelected": "No hay archivos seleccionados"
+ },
+ "toolMultiplePdfInput": {
+ "inputTitle": "Aporte {{type}}",
+ "noFilesSelected": "No hay archivos seleccionados"
+ },
+ "toolOptions": {
+ "title": "Opciones de herramientas"
+ },
+ "toolTextInput": {
+ "copied": "Texto copiado",
+ "copyFailed": "No se pudo copiar: {{error}}",
+ "input": "Texto de entrada",
+ "placeholder": "Introduzca su texto aquรญ..."
+ },
+ "toolTextResult": {
+ "copied": "Texto copiado",
+ "copyFailed": "No se pudo copiar: {{error}}",
+ "loading": "Cargando... Esto puede tardar un momento.",
+ "result": "Resultado"
+ }
+}
diff --git a/public/locales/es/video.json b/public/locales/es/video.json
new file mode 100644
index 0000000..29d48a8
--- /dev/null
+++ b/public/locales/es/video.json
@@ -0,0 +1,113 @@
+{
+ "changeSpeed": {
+ "defaultMultiplier": "Multiplicador predeterminado: 2 significa 2 veces mรกs rรกpido",
+ "description": "Cambia la velocidad de reproducciรณn de tus archivos de video. Acelera o ralentiza los videos manteniendo la sincronizaciรณn del audio. Compatible con varios multiplicadores de velocidad y formatos de video comunes.",
+ "inputTitle": "Vรญdeo de entrada",
+ "newVideoSpeed": "Nueva velocidad de video",
+ "resultTitle": "Vรญdeo editado",
+ "settingSpeed": "Ajuste de velocidad",
+ "shortDescription": "Cambiar la velocidad de reproducciรณn del vรญdeo",
+ "title": "Cambiar la velocidad del video",
+ "toolInfo": {
+ "title": "ยฟQuรฉ es un? {{title}}?"
+ }
+ },
+ "compress": {
+ "default": "Por defecto",
+ "description": "Comprime videos escalรกndolos a diferentes resoluciones como 240p, 480p, 720p, etc. Esta herramienta ayuda a reducir el tamaรฑo del archivo manteniendo una calidad aceptable. Es compatible con formatos de video comunes como MP4, WebM y OGG.",
+ "inputTitle": "Vรญdeo de entrada",
+ "loadingText": "Comprimiendo video...",
+ "lossless": "Sin pรฉrdida",
+ "quality": "Calidad (CRF)",
+ "resolution": "Resoluciรณn",
+ "resultTitle": "Vรญdeo comprimido",
+ "shortDescription": "Comprimir vรญdeos escalando a diferentes resoluciones",
+ "title": "Comprimir vรญdeo",
+ "worst": "El peor"
+ },
+ "cropVideo": {
+ "cropCoordinates": "Coordenadas de cultivo",
+ "croppingVideo": "Recortar vรญdeo",
+ "description": "Recortar el vรญdeo para eliminar รกreas no deseadas.",
+ "errorBeyondHeight": "El รกrea de recorte se extiende mรกs allรก de la altura del video ({{height}}pรญxeles)",
+ "errorBeyondWidth": "El รกrea de recorte se extiende mรกs allรก del ancho del video ({{width}}pรญxeles)",
+ "errorCroppingVideo": "Error al recortar el vรญdeo. Por favor, revise los parรกmetros y el archivo de vรญdeo.",
+ "errorLoadingDimensions": "No se pudieron cargar las dimensiones del vรญdeo",
+ "errorNonNegativeCoordinates": "Las coordenadas X e Y deben ser no negativas",
+ "errorPositiveDimensions": "El ancho y la altura deben ser positivos",
+ "height": "Altura",
+ "inputTitle": "Vรญdeo de entrada",
+ "loadVideoForDimensions": "Cargar un vรญdeo para ver las dimensiones",
+ "resultTitle": "Vรญdeo recortado",
+ "shortDescription": "Recortar el vรญdeo para eliminar รกreas no deseadas",
+ "title": "Recortar vรญdeo",
+ "toolInfo": {
+ "description": "Esta herramienta permite recortar archivos de vรญdeo para eliminar รกreas no deseadas. Puede especificar el รกrea de recorte configurando las coordenadas X e Y, asรญ como las dimensiones de ancho y alto.",
+ "title": "Recortar vรญdeo"
+ },
+ "videoDimensions": "Dimensiones del vรญdeo: {{width}} ร {{height}} pรญxeles",
+ "videoInformation": "Informaciรณn del vรญdeo",
+ "width": "Ancho",
+ "xCoordinate": "X (izquierda)",
+ "yCoordinate": "Y (arriba)"
+ },
+ "flip": {
+ "description": "Voltee archivos de video horizontal o verticalmente. Refleje videos para efectos especiales o corregir problemas de orientaciรณn.",
+ "flippingVideo": "Vรญdeo invertido",
+ "horizontalLabel": "Horizontal (Espejo)",
+ "inputTitle": "Vรญdeo de entrada",
+ "orientation": "Orientaciรณn",
+ "resultTitle": "Vรญdeo invertido",
+ "shortDescription": "Voltear el vรญdeo horizontal o verticalmente",
+ "title": "Voltear vรญdeo",
+ "verticalLabel": "Vertical (al revรฉs)"
+ },
+ "gif": {
+ "changeSpeed": {
+ "description": "Cambia la velocidad de reproducciรณn de los GIF. Acelera o ralentiza los GIF manteniendo una animaciรณn fluida.",
+ "shortDescription": "Cambiar la velocidad de la animaciรณn GIF",
+ "title": "Cambiar la velocidad del GIF"
+ }
+ },
+ "loop": {
+ "description": "Crea un vรญdeo en bucle repitiendo el vรญdeo original varias veces.",
+ "inputTitle": "Vรญdeo de entrada",
+ "loopingVideo": "Vรญdeo en bucle",
+ "loops": "Bucles",
+ "numberOfLoops": "Nรบmero de bucles",
+ "resultTitle": "Vรญdeo en bucle",
+ "shortDescription": "Crear archivos de vรญdeo en bucle",
+ "title": "Vรญdeo en bucle",
+ "toolInfo": {
+ "description": "Esta herramienta permite crear un vรญdeo en bucle repitiendo el vรญdeo original varias veces. Puedes especificar cuรกntas veces debe repetirse.",
+ "title": "ยฟQuรฉ es un? {{title}}?"
+ }
+ },
+ "rotate": {
+ "180Degrees": "180ยฐ (al revรฉs)",
+ "270Degrees": "270ยฐ (90ยฐ en sentido antihorario)",
+ "90Degrees": "90ยฐ en sentido horario",
+ "description": "Gira archivos de vรญdeo 90, 180 o 270 grados. Corrige la orientaciรณn del vรญdeo o crea efectos especiales con un control de rotaciรณn preciso.",
+ "inputTitle": "Vรญdeo de entrada",
+ "resultTitle": "Vรญdeo rotado",
+ "rotatingVideo": "Vรญdeo giratorio",
+ "rotation": "Rotaciรณn",
+ "shortDescription": "Girar el vรญdeo en grados especรญficos",
+ "title": "Girar vรญdeo"
+ },
+ "trim": {
+ "description": "Recorta archivos de vรญdeo especificando la hora de inicio y la hora de fin. Elimina las secciones no deseadas del principio o del final de los vรญdeos.",
+ "endTime": "Fin de los tiempos",
+ "inputTitle": "Vรญdeo de entrada",
+ "resultTitle": "Vรญdeo recortado",
+ "shortDescription": "Recortar el vรญdeo eliminando las secciones no deseadas",
+ "startTime": "Hora de inicio",
+ "timestamps": "Marcas de tiempo",
+ "title": "Recortar vรญdeo"
+ },
+ "videoToGif": {
+ "description": "Convierte archivos de vรญdeo a formato GIF animado. Extrae intervalos de tiempo especรญficos y crea imรกgenes animadas para compartir.",
+ "shortDescription": "Convertir vรญdeo a GIF animado",
+ "title": "Vรญdeo a GIF"
+ }
+}
diff --git a/public/locales/es/xml.json b/public/locales/es/xml.json
new file mode 100644
index 0000000..2ffd5c4
--- /dev/null
+++ b/public/locales/es/xml.json
@@ -0,0 +1,38 @@
+{
+ "xmlBeautifier": {
+ "description": "Formatear XML con sangrรญa y espaciado adecuados.",
+ "indentation": "Sangrรญa",
+ "inputTitle": "XML de entrada",
+ "resultTitle": "XML embellecido",
+ "shortDescription": "Formatear y embellecer el cรณdigo XML",
+ "title": "Embellecedor XML",
+ "toolInfo": {
+ "description": "Esta herramienta le permite formatear datos XML con sangrรญa y espaciado adecuados, haciรฉndolos mรกs legibles y fรกciles de trabajar.",
+ "title": "Embellecedor XML"
+ },
+ "useSpaces": "Utilice espacios",
+ "useSpacesDescription": "Sangrar la salida con espacios",
+ "useTabs": "Usar pestaรฑas",
+ "useTabsDescription": "Sangrar la salida con tabulaciones."
+ },
+ "xmlValidator": {
+ "description": "Validar la sintaxis y estructura XML.",
+ "placeholder": "Pegue o importe XML aquรญ...",
+ "shortDescription": "Validar el cรณdigo XML para detectar errores",
+ "title": "Validador XML",
+ "toolInfo": {
+ "description": "Esta herramienta permite validar la sintaxis y la estructura del XML. Comprueba si el XML estรก bien formado y proporciona mensajes de error detallados para cualquier problema detectado.",
+ "title": "Validador XML"
+ }
+ },
+ "xmlViewer": {
+ "description": "Ver y explorar la estructura XML en formato de รกrbol.",
+ "inputTitle": "XML de entrada",
+ "resultTitle": "Vista de รกrbol XML",
+ "title": "Visor XML",
+ "toolInfo": {
+ "description": "Esta herramienta le permite ver datos XML en un formato de รกrbol jerรกrquico, lo que facilita la exploraciรณn y la comprensiรณn de la estructura de los documentos XML.",
+ "title": "Visor XML"
+ }
+ }
+}
diff --git a/public/locales/fr/audio.json b/public/locales/fr/audio.json
new file mode 100644
index 0000000..e63bbb2
--- /dev/null
+++ b/public/locales/fr/audio.json
@@ -0,0 +1,42 @@
+{
+ "changeSpeed": {
+ "description": "Modifier la vitesse de lecture des fichiers audio. Accรฉlรฉrer ou ralentir le son tout en conservant la hauteur.",
+ "inputTitle": "Entrรฉe audio",
+ "newAudioSpeed": "Nouvelle vitesse audio",
+ "outputFormat": "Format de sortie",
+ "resultTitle": "Audio รฉditรฉ",
+ "settingSpeed": "Rรฉglage de la vitesse",
+ "shortDescription": "Modifier la vitesse des fichiers audio",
+ "speedDescription": "Multiplicateur par dรฉfautย : 2 signifie 2x plus rapide",
+ "title": "Changer la vitesse audio",
+ "toolInfo": {
+ "title": "Qu'est-ce que {{title}}?"
+ }
+ },
+ "extractAudio": {
+ "description": "Extraire la piste audio des fichiers vidรฉo.",
+ "extractingAudio": "Extraction audio",
+ "inputTitle": "Entrรฉe vidรฉo",
+ "outputFormat": "Format de sortie",
+ "outputFormatDescription": "Sรฉlectionnez le format dans lequel l'audio doit รชtre extrait.",
+ "resultTitle": "Audio extrait",
+ "shortDescription": "Extrayez l'audio des fichiers vidรฉo (MP4, MOV, etc.) vers AAC, MP3 ou WAV.",
+ "title": "Extraire l'audio d'une vidรฉo",
+ "toolInfo": {
+ "description": "Cet outil vous permet d'extraire la piste audio de vos fichiers vidรฉo. Vous pouvez choisir parmi diffรฉrents formats audio, notamment AAC, MP3 et WAV.",
+ "title": "Qu'est-ce que {{title}}?"
+ }
+ },
+ "mergeAudio": {
+ "description": "Combinez plusieurs fichiers audio en un seul fichier audio en les concatรฉnant en sรฉquence.",
+ "longDescription": "Cet outil vous permet de fusionner plusieurs fichiers audio en un seul fichier en les concatรฉnant dans l'ordre de leur mise en ligne. Idรฉal pour combiner des segments de podcast, des morceaux de musique ou tout autre fichier audio ร assembler. Compatible avec diffรฉrents formats audio, dont MP3, AAC et WAV.",
+ "shortDescription": "Fusionnez plusieurs fichiers audio en un seul (MP3, AAC, WAV).",
+ "title": "Fusionner l'audio"
+ },
+ "trim": {
+ "description": "Coupez et rognez des fichiers audio pour extraire des segments spรฉcifiques en spรฉcifiant les heures de dรฉbut et de fin.",
+ "longDescription": "Cet outil vous permet de dรฉcouper des fichiers audio en spรฉcifiant les heures de dรฉbut et de fin. Vous pouvez extraire des segments spรฉcifiques de fichiers audio plus longs, supprimer des parties inutiles ou crรฉer des clips plus courts. Il prend en charge divers formats audio, dont MP3, AAC et WAV. Idรฉal pour le montage de podcasts, la production musicale ou tout autre besoin d'รฉdition audio.",
+ "shortDescription": "Dรฉcoupez des fichiers audio pour extraire des segments de temps spรฉcifiques (MP3, AAC, WAV).",
+ "title": "Couper le son"
+ }
+}
diff --git a/public/locales/fr/csv.json b/public/locales/fr/csv.json
new file mode 100644
index 0000000..fd2278c
--- /dev/null
+++ b/public/locales/fr/csv.json
@@ -0,0 +1,114 @@
+{
+ "changeCsvSeparator": {
+ "description": "Modifiez le dรฉlimiteur/sรฉparateur dans les fichiers CSV. Convertissez vos fichiers entre diffรฉrents formats CSV, comme la virgule, le point-virgule, la tabulation ou des sรฉparateurs personnalisรฉs.",
+ "shortDescription": "Modifier le dรฉlimiteur du fichier CSV",
+ "title": "Changer le sรฉparateur CSV"
+ },
+ "csvRowsToColumns": {
+ "description": "Cet outil convertit les lignes d'un fichier CSV (valeurs sรฉparรฉes par des virgules) en colonnes. Il extrait les lignes horizontales du fichier CSV d'entrรฉe une par une, les fait pivoter de 90 degrรฉs et les affiche sous forme de colonnes verticales, l'une aprรจs l'autre, sรฉparรฉes par des virgules.', longDescription: 'Cet outil convertit les lignes d'un fichier CSV (valeurs sรฉparรฉes par des virgules) en colonnes. Par exemple, si les donnรฉes CSV d'entrรฉe comportent 6 lignes, la sortie comportera 6 colonnes et les รฉlรฉments des lignes seront disposรฉs de haut en bas. Dans un fichier CSV bien formรฉ, le nombre de valeurs par ligne est le mรชme. Cependant, si des lignes contiennent des champs manquants, le programme peut les corriger et vous pouvez choisir parmi les options disponiblesย : remplir les donnรฉes manquantes avec des รฉlรฉments vides ou remplacer les donnรฉes manquantes par des รฉlรฉments personnalisรฉs, tels que ยซย manquantย ยป, ยซย ?ย ยป ou ยซย xย ยป. Pendant le processus de conversion, l'outil nettoie รฉgalement le fichier CSV des informations inutiles, telles que les lignes vides (c'est-ร -dire sans informations visibles) et les commentaires. Pour aider l'outil ร identifier correctement les commentaires, vous pouvez spรฉcifier dans les options le symbole au dรฉbut d'une ligne qui dรฉmarre un commentaire. Ce symbole est gรฉnรฉralement un diรจse ยซย #ย ยป ou une double barre oblique ยซย //ย ยป. C'est incroyableย !",
+ "longDescription": "Cet outil convertit les lignes d'un fichier CSV (valeurs sรฉparรฉes par des virgules) en colonnes. Par exemple, si les donnรฉes CSV d'entrรฉe comportent six lignes, le rรฉsultat comportera six colonnes et les รฉlรฉments des lignes seront disposรฉs de haut en bas. Dans un fichier CSV bien formรฉ, le nombre de valeurs par ligne est identique. Cependant, si des champs manquent dans certaines lignes, le programme peut les corriger et vous pouvez choisir parmi les options disponiblesย : complรฉter les donnรฉes manquantes avec des รฉlรฉments vides ou les remplacer par des รฉlรฉments personnalisรฉs, tels que",
+ "shortDescription": "Convertissez les lignes CSV en colonnes.",
+ "title": "Convertir des lignes CSV en colonnes"
+ },
+ "csvToJson": {
+ "columnSeparator": "Sรฉparateur de colonnes (par exemple, , ; \\t)",
+ "commentSymbol": "Symbole de commentaire (par exemple, #)",
+ "conversionOptions": "Options de conversion",
+ "description": "Convertissez des fichiers CSV au format JSON avec des options personnalisables pour les dรฉlimiteurs, les guillemets et le formatage de sortie. Prise en charge des en-tรชtes, des commentaires et de la conversion de type dynamique.",
+ "dynamicTypes": "Types dynamiques",
+ "dynamicTypesDescription": "Convertir automatiquement les nombres et les boolรฉens",
+ "errorParsing": "Erreur lors de l'analyse du fichier CSVย : {{error}}",
+ "fieldQuote": "Citation de champ (par exemple, \")",
+ "inputCsvFormat": "Format d'entrรฉe CSV",
+ "inputTitle": "Entrรฉe CSV",
+ "resultTitle": "Sortie JSON",
+ "shortDescription": "Convertissez les donnรฉes CSV au format JSON.",
+ "skipEmptyLines": "Sauter les lignes vides",
+ "skipEmptyLinesDescription": "Ignorer les lignes vides dans le fichier CSV d'entrรฉe",
+ "title": "Convertir CSV en JSON",
+ "useHeaders": "Utiliser les en-tรชtes",
+ "useHeadersDescription": "Traiter la premiรจre ligne comme en-tรชte de colonne"
+ },
+ "csvToTsv": {
+ "description": "Tรฉlรฉchargez votre fichier CSV via le formulaire ci-dessous et il sera automatiquement converti en fichier TSV. Dans les options de l'outil, vous pouvez personnaliser le format CSV d'entrรฉeย : spรฉcifiez le dรฉlimiteur de champ, le caractรจre de guillemet et le symbole de commentaire, ignorez les lignes CSV vides et conservez ou non les en-tรชtes de colonnes CSV.",
+ "longDescription": "Cet outil convertit les donnรฉes CSV (valeurs sรฉparรฉes par des virgules) en donnรฉes TSV (valeurs sรฉparรฉes par des tabulations). CSV et TSV sont des formats de fichier courants pour stocker des donnรฉes tabulaires, mais ils utilisent des sรฉparateurs diffรฉrents pour sรฉparer les valeursย : le CSV utilise des virgules (",
+ "shortDescription": "Convertissez les donnรฉes CSV au format TSV.",
+ "title": "Convertir CSV en TSV"
+ },
+ "csvToXml": {
+ "description": "Convertissez des fichiers CSV au format XML avec des options personnalisables.",
+ "shortDescription": "Convertissez les donnรฉes CSV au format XML.",
+ "title": "Convertir CSV en XML"
+ },
+ "csvToYaml": {
+ "description": "Il vous suffit de tรฉlรฉcharger votre fichier CSV via le formulaire ci-dessous et il sera automatiquement converti en fichier YAML. Dans les options de l'outil, vous pouvez spรฉcifier le caractรจre de dรฉlimitation de champ, le caractรจre de guillemet et le caractรจre de commentaire pour adapter l'outil aux formats CSV personnalisรฉs. Vous pouvez รฉgalement sรฉlectionner le format YAML de sortieย : prรฉservant ou excluant les en-tรชtes CSV.",
+ "longDescription": "Cet outil transforme les donnรฉes CSV (Comma Separated Values) en donnรฉes YAML (Yet Another Markup Language). CSV est un format tabulaire simple utilisรฉ pour reprรฉsenter des types de donnรฉes matricielles composรฉs de lignes et de colonnes. YAML, quant ร lui, est un format plus avancรฉ (en fait un sur-ensemble de JSON), qui crรฉe des donnรฉes plus lisibles pour la sรฉrialisation et prend en charge les listes, les dictionnaires et les objets imbriquรฉs. Ce programme prend en charge diffรฉrents formats d'entrรฉe CSVย : les donnรฉes d'entrรฉe peuvent รชtre sรฉparรฉes par des virgules (par dรฉfaut), des points-virgules, des barres verticales ou utiliser un autre dรฉlimiteur. Vous pouvez spรฉcifier le dรฉlimiteur exact utilisรฉ par vos donnรฉes dans les options. De mรชme, dans les options, vous pouvez spรฉcifier le caractรจre guillemet utilisรฉ pour encadrer les champs CSV (par dรฉfaut, un guillemet double). Vous pouvez รฉgalement ignorer les lignes commenรงant par des commentaires en spรฉcifiant les symboles de commentaire dans les options. Cela vous permet de prรฉserver la clartรฉ de vos donnรฉes en ignorant les lignes inutiles. Il existe deux mรฉthodes pour convertir un fichier CSV en YAML. La premiรจre mรฉthode convertit chaque ligne CSV en liste YAML. La seconde mรฉthode extrait les en-tรชtes de la premiรจre ligne CSV et crรฉe des objets YAML avec des clรฉs basรฉes sur ces en-tรชtes. Vous pouvez รฉgalement personnaliser le format YAML de sortie en spรฉcifiant le nombre d'espaces pour l'indentation des structures YAML. Pour effectuer la conversion inverse, c'est-ร -dire convertir un fichier YAML en CSV, vous pouvez utiliser notre outil de conversion YAML en CSV. C'est gรฉnialย !",
+ "shortDescription": "Convertissez rapidement un fichier CSV en fichier YAML.",
+ "title": "Convertir CSV en YAML"
+ },
+ "findIncompleteCsvRecords": {
+ "checkingOptions": "Vรฉrification des options",
+ "commentCharacterDescription": "Saisissez le caractรจre indiquant le dรฉbut d'une ligne de commentaire. Les lignes commenรงant par ce symbole seront ignorรฉes.",
+ "csvInputOptions": "Options de saisie CSV",
+ "csvSeparatorDescription": "Saisissez le caractรจre utilisรฉ pour dรฉlimiter les colonnes dans le fichier d'entrรฉe CSV.",
+ "deleteLinesWithNoData": "Supprimer les lignes sans donnรฉes",
+ "deleteLinesWithNoDataDescription": "Supprimer les lignes vides du fichier d'entrรฉe CSV.",
+ "description": "Il vous suffit de tรฉlรฉcharger votre fichier CSV dans le formulaire ci-dessous et cet outil vรฉrifiera automatiquement qu'aucune ligne ou colonne ne contient de valeur manquante. Dans les options de l'outil, vous pouvez ajuster le format du fichier d'entrรฉe (spรฉcifier le dรฉlimiteur, les guillemets et les commentaires). De plus, vous pouvez activer la vรฉrification des valeurs vides, ignorer les lignes vides et limiter le nombre de messages d'erreur dans la sortie.",
+ "findEmptyValues": "Trouver des valeurs vides",
+ "findEmptyValuesDescription": "Afficher un message concernant les champs CSV vides (il ne s'agit pas de champs manquants mais de champs qui ne contiennent rien).",
+ "inputTitle": "Entrรฉe CSV",
+ "limitNumberOfMessages": "Limiter le nombre de messages",
+ "messageLimitDescription": "Dรฉfinissez la limite du nombre de messages dans la sortie.",
+ "quoteCharacterDescription": "Saisissez le caractรจre de citation utilisรฉ pour citer les champs de saisie CSV.",
+ "resultTitle": "Statut CSV",
+ "shortDescription": "Trouvez rapidement les lignes et les colonnes dans CSV auxquelles il manque des valeurs.",
+ "title": "Rechercher des enregistrements CSV incomplets",
+ "toolInfo": {
+ "title": "Qu'est-ce qu'un {{title}}?"
+ }
+ },
+ "insertCsvColumns": {
+ "appendColumns": "Ajouter des colonnes",
+ "commentCharacterDescription": "Saisissez le caractรจre indiquant le dรฉbut d'une ligne de commentaire. Les lignes commenรงant par ce symbole seront ignorรฉes.",
+ "csvOptions": "Options CSV",
+ "csvSeparator": "Sรฉparateur CSV",
+ "csvToInsert": "CSV ร insรฉrer",
+ "csvToInsertDescription": "Saisissez la ou les colonnes ร insรฉrer dans le fichier CSV. Le caractรจre de dรฉlimitation des colonnes doit รชtre identique ร celui du fichier d'entrรฉe CSV. Remarqueย : les lignes vides seront ignorรฉes.",
+ "customFillDescription": "Si le fichier CSV d'entrรฉe est incomplet (valeurs manquantes), ajoutez-vous des champs vides ou des symboles personnalisรฉs aux enregistrements pour crรฉer un CSV bien formรฉย ?",
+ "customFillValueDescription": "Utilisez cette valeur personnalisรฉe pour remplir les champs manquants. (Fonctionne uniquement avec le mode ยซย Valeurs personnalisรฉesย ยป ci-dessus.)",
+ "customPosition": "Position personnalisรฉe",
+ "customPositionOptionsDescription": "Sรฉlectionnez la mรฉthode pour insรฉrer les colonnes dans le fichier CSV.",
+ "description": "Ajoutez de nouvelles colonnes aux donnรฉes CSV ร des positions spรฉcifiรฉes.",
+ "fillWithCustomValues": "Remplir avec les valeurs douaniรจres",
+ "fillWithEmptyValues": "Remplir avec des valeurs vides",
+ "headerName": "Nom de l'en-tรชte",
+ "headerNameDescription": "En-tรชte de la colonne aprรจs laquelle vous souhaitez insรฉrer des colonnes.",
+ "inputTitle": "Entrรฉe CSV",
+ "insertingPositionDescription": "Spรฉcifiez oรน insรฉrer les colonnes dans le fichier CSV.",
+ "position": "Position",
+ "positionOptions": "Options de position",
+ "prependColumns": "Ajouter des colonnes au dรฉbut",
+ "quoteCharDescription": "Saisissez le caractรจre de citation utilisรฉ pour citer les champs de saisie CSV.",
+ "resultTitle": "Sortie CSV",
+ "rowNumberDescription": "Numรฉro de la colonne aprรจs laquelle vous souhaitez insรฉrer des colonnes.",
+ "separatorDescription": "Saisissez le caractรจre utilisรฉ pour dรฉlimiter les colonnes dans le fichier d'entrรฉe CSV.",
+ "shortDescription": "Insรฉrez rapidement une ou plusieurs nouvelles colonnes n'importe oรน dans un fichier CSV.",
+ "title": "Insรฉrer des colonnes CSV",
+ "toolInfo": {
+ "description": "Cet outil vous permet d'insรฉrer de nouvelles colonnes dans des donnรฉes CSV ร des emplacements spรฉcifiques. Vous pouvez ajouter des colonnes ร des emplacements personnalisรฉs en fonction des noms d'en-tรชte ou des numรฉros de colonne.",
+ "title": "Insรฉrer des colonnes CSV"
+ }
+ },
+ "swapCsvColumns": {
+ "description": "Il vous suffit de tรฉlรฉcharger votre fichier CSV dans le formulaire ci-dessous, de spรฉcifier les colonnes ร permuter et l'outil modifiera automatiquement la position de ces colonnes dans le fichier de sortie. Dans les options de l'outil, vous pouvez spรฉcifier la position ou le nom des colonnes ร permuter, corriger les donnรฉes incomplรจtes et รฉventuellement supprimer les enregistrements vides et commentรฉs.",
+ "longDescription": "Cet outil rรฉorganise les donnรฉes CSV en intervertissant la position de leurs colonnes. L'interversion des colonnes amรฉliore la lisibilitรฉ d'un fichier CSV en regroupant ou en mettant au premier plan les donnรฉes frรฉquemment utilisรฉes, facilitant ainsi leur comparaison et leur modification. Par exemple, vous pouvez intervertir la premiรจre colonne avec la derniรจre, ou la deuxiรจme avec la troisiรจme. Pour intervertir les colonnes en fonction de leur position, sรฉlectionnez l'option",
+ "shortDescription": "Rรฉorganiser les colonnes CSV.",
+ "title": "รchanger les colonnes CSV"
+ },
+ "transposeCsv": {
+ "description": "Il vous suffit de tรฉlรฉcharger votre fichier CSV via le formulaire ci-dessous et cet outil le transposera automatiquement. Dans les options, vous pouvez spรฉcifier le caractรจre de dรฉbut des lignes de commentaire dans le fichier CSV pour les supprimer. De plus, si le fichier CSV est incomplet (valeurs manquantes), vous pouvez remplacer les valeurs manquantes par le caractรจre vide ou un caractรจre personnalisรฉ.",
+ "longDescription": "Cet outil transpose les fichiers CSV (valeurs sรฉparรฉes par des virgules). Il traite le fichier CSV comme une matrice de donnรฉes et inverse tous les รฉlรฉments sur la diagonale principale. Le fichier CSV de sortie contient les mรชmes donnรฉes CSV que le fichier d'entrรฉe, mais toutes les lignes sont dรฉsormais des colonnes, et toutes les colonnes des lignes. Aprรจs la transposition, le fichier CSV aura des dimensions opposรฉes. Par exemple, si le fichier d'entrรฉe comporte 4 colonnes et 3 lignes, le fichier de sortie comportera 3 colonnes et 4 lignes. Lors de la conversion, le programme supprime รฉgalement les lignes inutiles et corrige les donnรฉes incomplรจtes. Plus prรฉcisรฉment, l'outil supprime automatiquement tous les enregistrements vides et les commentaires commenรงant par un caractรจre spรฉcifique, que vous pouvez dรฉfinir dans l'option. De plus, en cas de corruption ou de perte des donnรฉes CSV, l'utilitaire complรจte le fichier avec des champs vides ou personnalisรฉs, que vous pouvez spรฉcifier dans les options. Csv-abulousย !",
+ "shortDescription": "Transposer rapidement un fichier CSV.",
+ "title": "Transposer CSV"
+ }
+}
diff --git a/public/locales/fr/image.json b/public/locales/fr/image.json
new file mode 100644
index 0000000..da859f1
--- /dev/null
+++ b/public/locales/fr/image.json
@@ -0,0 +1,98 @@
+{
+ "changeColors": {
+ "description": "Monde",
+ "shortDescription": "รchanger rapidement les couleurs d'une image",
+ "title": "Changer une couleur dans une image"
+ },
+ "changeOpacity": {
+ "description": "Ajustez facilement la transparence de vos images. Tรฉlรฉchargez simplement votre image, utilisez le curseur pour dรฉfinir le niveau d'opacitรฉ souhaitรฉ entre 0 (transparent) et 1 (opaque), puis tรฉlรฉchargez l'image modifiรฉe.",
+ "shortDescription": "Ajuster la transparence des images",
+ "title": "Modifier l'opacitรฉ de l'image"
+ },
+ "compress": {
+ "description": "Rรฉduisez la taille du fichier image tout en conservant la qualitรฉ.",
+ "inputTitle": "Image d'entrรฉe",
+ "resultTitle": "Image compressรฉe",
+ "shortDescription": "Compresser des images en maintenant une qualitรฉ raisonnable.",
+ "title": "Compresser une image"
+ },
+ "compressPng": {
+ "description": "C'est un programme pour compresser des images PNG. Dรจs que vous collez votre image PNG dans la zone d'entrรฉe, le programme va la compresser et afficher le rรฉsultat dans la zone de sortie. Dans les options, vous pouvez ajuster le niveau de compression et comparer la taille des 2 fichiers.",
+ "shortDescription": "Compresser rapidement un PNG",
+ "title": "Compresser un PNG"
+ },
+ "convertJgpToPng": {
+ "description": "Convertissez rapidement vos images JPG en PNG. Importez simplement votre image PNG dans l'รฉditeur ร gauche.",
+ "shortDescription": "Convertir rapidement vos images JPG en PNG",
+ "title": "Convertir un JPG en PNG"
+ },
+ "convertToJpg": {
+ "description": "Convertissez diffรฉrents formats d'image (PNG, GIF, TIF, PSD, SVG, WEBP, HEIC, RAW) en JPG avec des paramรจtres de qualitรฉ et de couleur d'arriรจre-plan personnalisables.",
+ "shortDescription": "Convertir des images en JPG avec contrรดle de la qualitรฉ",
+ "title": "Convertir des images en JPG"
+ },
+ "createTransparent": {
+ "description": "Monde",
+ "shortDescription": "Rendre rapidement une image transparente",
+ "title": "Crรฉer un PNG transparent"
+ },
+ "crop": {
+ "description": "Recadrez les images pour supprimer les zones indรฉsirables.",
+ "inputTitle": "Image d'entrรฉe",
+ "resultTitle": "Image rognรฉe",
+ "shortDescription": "Rogner des images rapidement.",
+ "title": "Rogner une image"
+ },
+ "editor": {
+ "description": "รditeur d'images avancรฉ avec des outils de recadrage, de rotation, d'annotation, d'ajustement des couleurs et d'ajout de filigranes. Retouchez vos images avec des outils professionnels directement dans votre navigateur.",
+ "shortDescription": "Modifiez des images avec des outils et des fonctionnalitรฉs avancรฉs",
+ "title": "รditeur d'images"
+ },
+ "imageToText": {
+ "description": "Extraire du texte ร partir d'images (JPG, PNG) ร l'aide de la reconnaissance optique de caractรจres (OCR).",
+ "shortDescription": "Extraire du texte ร partir d'images ร l'aide de l'OCR.",
+ "title": "Conversion d'image en texte (OCR)"
+ },
+ "qrCode": {
+ "description": "Gรฉnรฉrez des codes QR pour diffรฉrents types de donnรฉes : URL, texte, e-mail, tรฉlรฉphone, SMS, WiFi, vCard, etc.",
+ "shortDescription": "Crรฉez des codes QR personnalisรฉs pour diffรฉrents formats de donnรฉes.",
+ "title": "Gรฉnรฉrateur de code QR"
+ },
+ "removeBackground": {
+ "description": "Monde",
+ "shortDescription": "Supprimer automatiquement les arriรจre-plans des images",
+ "title": "Supprimer l'arriรจre-plan de l'image"
+ },
+ "resize": {
+ "description": "Redimensionner les images ร diffรฉrentes dimensions.",
+ "dimensionType": "Type de dimension",
+ "heightDescription": "Hauteur (en pixels)",
+ "inputTitle": "Image d'entrรฉe",
+ "maintainAspectRatio": "Maintenir le rapport hauteur/largeur",
+ "maintainAspectRatioDescription": "Conserver le rapport hauteur/largeur d'origine de l'image.",
+ "percentage": "Pourcentage",
+ "percentageDescription": "Pourcentage de la taille d'origine (par exemple, 50 pour la demi-taille, 200 pour la double taille)",
+ "resizeByPercentage": "Redimensionner par pourcentage",
+ "resizeByPercentageDescription": "Redimensionner en spรฉcifiant un pourcentage de la taille d'origine.",
+ "resizeByPixels": "Redimensionner par pixels",
+ "resizeByPixelsDescription": "Redimensionner en spรฉcifiant les dimensions en pixels.",
+ "resizeMethod": "Mรฉthode de redimensionnement",
+ "resultTitle": "Image redimensionnรฉe",
+ "setHeight": "Dรฉfinir la hauteur",
+ "setHeightDescription": "Spรฉcifiez la hauteur en pixels et calculez la largeur en fonction du rapport hauteur/largeur.",
+ "setWidth": "Dรฉfinir la largeur",
+ "setWidthDescription": "Spรฉcifiez la largeur en pixels et calculez la hauteur en fonction du rapport hauteur/largeur.",
+ "shortDescription": "Redimensionnez facilement les images.",
+ "title": "Redimensionner l'image",
+ "toolInfo": {
+ "description": "Cet outil vous permet de redimensionner des images JPG, PNG, SVG ou GIF. Vous pouvez redimensionner en spรฉcifiant les dimensions en pixels ou en pourcentage, avec des options permettant de conserver le rapport hauteur/largeur d'origine.",
+ "title": "Redimensionner l'image"
+ },
+ "widthDescription": "Largeur (en pixels)"
+ },
+ "rotate": {
+ "description": "Faire pivoter une image selon un angle spรฉcifiรฉ.",
+ "shortDescription": "Faites pivoter une image facilement.",
+ "title": "Faire pivoter l'image"
+ }
+}
diff --git a/public/locales/fr/json.json b/public/locales/fr/json.json
new file mode 100644
index 0000000..20bda9a
--- /dev/null
+++ b/public/locales/fr/json.json
@@ -0,0 +1,62 @@
+{
+ "escapeJson": {
+ "description": "รchappez les caractรจres spรฉciaux dans les chaรฎnes JSON. Convertissez les donnรฉes JSON au format correctement รฉchappรฉ pour une transmission ou un stockage sรฉcurisรฉ.",
+ "shortDescription": "รchapper aux caractรจres spรฉciaux dans JSON",
+ "title": "รchapper le JSON"
+ },
+ "jsonToXml": {
+ "description": "Convertissez des donnรฉes JSON au format XML. Transformez des objets JSON structurรฉs en documents XML bien formรฉs.",
+ "shortDescription": "Convertir JSON au format XML",
+ "title": "JSON vers XML"
+ },
+ "minify": {
+ "description": "Supprimez tous les espaces inutiles du JSON.",
+ "inputTitle": "Entrรฉe JSON",
+ "resultTitle": "JSON minifiรฉ",
+ "shortDescription": "Minifier JSON en supprimant les espaces",
+ "title": "Minifier JSON",
+ "toolInfo": {
+ "description": "La minification JSON consiste ร supprimer tous les espaces inutiles des donnรฉes JSON tout en prรฉservant leur validitรฉ. Cela inclut la suppression des espaces, des sauts de ligne et des indentations inutiles ร l'analyse correcte du JSON. La minification rรฉduit la taille des donnรฉes JSON, les rendant plus efficaces pour le stockage et la transmission, tout en conservant la mรชme structure de donnรฉes et les mรชmes valeurs.",
+ "title": "Qu'est-ce que la minification JSONย ?"
+ }
+ },
+ "prettify": {
+ "description": "Formatez JSON avec une indentation et un espacement appropriรฉs.",
+ "indentation": "รchancrure",
+ "inputTitle": "Entrรฉe JSON",
+ "resultTitle": "JSON embelli",
+ "shortDescription": "Formater et embellir le code JSON",
+ "title": "Embellir JSON",
+ "toolInfo": {
+ "description": "Cet outil vous permet de formater les donnรฉes JSON avec une indentation et un espacement appropriรฉs, les rendant plus lisibles et plus faciles ร utiliser.",
+ "title": "Embellir JSON"
+ },
+ "useSpaces": "Utiliser les espaces",
+ "useSpacesDescription": "Indenter la sortie avec des espaces",
+ "useTabs": "Utiliser les onglets",
+ "useTabsDescription": "Indenter la sortie avec des tabulations."
+ },
+ "stringify": {
+ "description": "Convertissez des objets JavaScript au format de chaรฎne JSON. Sรฉrialisez des structures de donnรฉes en chaรฎnes JSON pour le stockage ou la transmission.",
+ "shortDescription": "Convertir des objets en chaรฎne JSON",
+ "title": "Stringify JSON"
+ },
+ "tsvToJson": {
+ "description": "Convertissez les donnรฉes TSV (valeurs sรฉparรฉes par des tabulations) au format JSON. Transformez les donnรฉes tabulaires en objets JSON structurรฉs.",
+ "shortDescription": "Convertir le format TSV au format JSON",
+ "title": "TSV vers JSON"
+ },
+ "validateJson": {
+ "description": "Vรฉrifiez si JSON est valide et bien formรฉ.",
+ "inputTitle": "Entrรฉe JSON",
+ "invalidJson": "โ {{error}}",
+ "resultTitle": "Rรฉsultat de validation",
+ "shortDescription": "Valider le code JSON pour les erreurs",
+ "title": "Valider JSON",
+ "toolInfo": {
+ "description": "JSON (JavaScript Object Notation) est un format d'รฉchange de donnรฉes lรฉger. La validation JSON garantit la conformitรฉ de la structure des donnรฉes ร la norme JSON. Un objet JSON valide doit comporterย : - des noms de propriรฉtรฉs entre guillemetsย ; - des accolades {} correctement รฉquilibrรฉesย ; - aucune virgule aprรจs la derniรจre paire clรฉ-valeurย ; - une imbrication correcte des objets et des tableaux. Cet outil vรฉrifie le JSON d'entrรฉe et fournit des informations pour identifier et corriger les erreurs courantes.",
+ "title": "Qu'est-ce que la validation JSONย ?"
+ },
+ "validJson": "โ
JSON valide"
+ }
+}
diff --git a/public/locales/fr/list.json b/public/locales/fr/list.json
new file mode 100644
index 0000000..3af2b77
--- /dev/null
+++ b/public/locales/fr/list.json
@@ -0,0 +1,208 @@
+{
+ "duplicate": {
+ "concatenate": "Concatener",
+ "concatenateDescription": "Concatรฉner les copies (si cette option n'est pas cochรฉe, les รฉlรฉments seront entrelacรฉs)",
+ "copyDescription": "Nombre de copies (fractionnable)",
+ "description": "L'utilitaire de duplication d'รฉlรฉments de liste le plus simple au monde, accessible depuis un navigateur. Saisissez votre liste et spรฉcifiez des critรจres de duplication pour crรฉer des copies d'รฉlรฉments. Idรฉal pour l'expansion de donnรฉes, les tests ou la crรฉation de modรจles rรฉpรฉtitifs.",
+ "duplicationOptions": "Options de Duplication",
+ "examples": {
+ "fractional": {
+ "description": "Cet exemple montre comment dupliquer une liste avec un nombre fractionnaire de copies.",
+ "title": "duplication fractionnaire"
+ },
+ "interweave": {
+ "description": "Cet exemple montre comment entrelacer des รฉlรฉments au lieu de les concatรฉner.",
+ "title": "รlรฉments entrelacรฉs"
+ },
+ "reverse": {
+ "description": "Cet exemple montre comment dupliquer une liste dans lโordre inverse.",
+ "title": "Duplication inversรฉe"
+ },
+ "simple": {
+ "description": "Cet exemple montre comment dupliquer une liste de mots.",
+ "title": "Duplication simple"
+ }
+ },
+ "inputTitle": "Liste d'entrรฉes",
+ "joinSeparatorDescription": "Sรฉparateur pour joindre la liste dupliquรฉe",
+ "resultTitle": "Liste dupliquรฉe",
+ "reverse": "Inverse",
+ "reverseDescription": "Inverser les รฉlรฉments dupliquรฉs",
+ "shortDescription": "Dupliquer les รฉlรฉments de la liste avec des critรจres spรฉcifiรฉs",
+ "splitByRegex": "Diviser par expression rรฉguliรจre",
+ "splitBySymbol": "Diviser par symbole",
+ "splitOptions": "Options de fractionnement",
+ "splitSeparatorDescription": "Sรฉparateur pour diviser la liste",
+ "title": "Double",
+ "toolInfo": {
+ "description": "Cet outil vous permet de dupliquer des รฉlรฉments d'une liste. Vous pouvez spรฉcifier le nombre de copies (y compris les valeurs fractionnaires), contrรดler si les รฉlรฉments sont concatรฉnรฉs ou entrelacรฉs, et mรชme inverser les รฉlรฉments dupliquรฉs. Il est utile pour crรฉer des motifs rรฉpรฉtรฉs, gรฉnรฉrer des donnรฉes de test ou รฉtendre des listes au contenu prรฉvisible.",
+ "title": "Duplication de liste"
+ }
+ },
+ "findMostPopular": {
+ "description": "L'utilitaire de recherche par navigateur le plus simple au monde pour trouver les รฉlรฉments les plus populaires d'une liste. Saisissez votre liste et obtenez instantanรฉment les รฉlรฉments qui apparaissent le plus frรฉquemment. Idรฉal pour l'analyse de donnรฉes, l'identification de tendances ou la recherche d'รฉlรฉments communs.",
+ "shortDescription": "Trouver les รฉlรฉments les plus frรฉquemment utilisรฉs",
+ "title": "Trouver les plus populaires"
+ },
+ "findUnique": {
+ "caseSensitiveItems": "รlรฉments sensibles ร la casse",
+ "caseSensitiveItemsDescription": "Affichez les รฉlรฉments avec une casse diffรฉrente comme รฉlรฉments uniques dans la liste.",
+ "delimiterDescription": "Dรฉfinissez un symbole de dรฉlimitation ou une expression rรฉguliรจre.",
+ "description": "L'utilitaire de recherche d'รฉlรฉments uniques dans une liste, le plus simple au monde, est disponible sur navigateur. Saisissez votre liste et obtenez instantanรฉment toutes les valeurs uniques, sans doublons. Idรฉal pour le nettoyage des donnรฉes, la dรฉduplication ou la recherche d'รฉlรฉments distincts.",
+ "findAbsolutelyUniqueItems": "Trouvez des articles absolument uniques",
+ "findAbsolutelyUniqueItemsDescription": "Afficher uniquement les รฉlรฉments de la liste qui existent en un seul exemplaire.",
+ "inputListDelimiter": "Dรฉlimiteur de liste d'entrรฉe",
+ "inputTitle": "Liste d'entrรฉes",
+ "outputListDelimiter": "Dรฉlimiteur de liste de sortie",
+ "resultTitle": "Articles uniques",
+ "shortDescription": "Trouver des รฉlรฉments uniques dans une liste",
+ "skipEmptyItems": "Ignorer les รฉlรฉments vides",
+ "skipEmptyItemsDescription": "N'incluez pas les รฉlรฉments de liste vides dans la sortie.",
+ "title": "Trouvez l'unique",
+ "trimItems": "รlรฉments de la liste de finition",
+ "trimItemsDescription": "Supprimez les espaces de dรฉbut et de fin avant de comparer les รฉlรฉments.",
+ "uniqueItemOptions": "Options d'articles uniques"
+ },
+ "group": {
+ "deleteEmptyItems": "Supprimer les รฉlรฉments vides",
+ "deleteEmptyItemsDescription": "Ignorez les รฉlรฉments vides et ne les incluez pas dans les groupes.",
+ "description": "L'utilitaire de regroupement d'รฉlรฉments de liste le plus simple au monde, accessible depuis un navigateur. Saisissez votre liste et spรฉcifiez des critรจres de regroupement pour organiser les รฉlรฉments en groupes logiques. Idรฉal pour catรฉgoriser des donnรฉes, organiser des informations ou crรฉer des listes structurรฉes. Prend en charge les sรฉparateurs personnalisรฉs et diverses options de regroupement.",
+ "emptyItemsAndPadding": "รlรฉments vides et remplissage",
+ "groupNumberDescription": "Nombre d'รฉlรฉments dans un groupe",
+ "groupSeparatorDescription": "Caractรจre sรฉparateur de groupe",
+ "groupSizeAndSeparators": "Taille du groupe et sรฉparateurs",
+ "inputItemSeparator": "Sรฉparateur d'รฉlรฉments d'entrรฉe",
+ "inputTitle": "Liste d'entrรฉe",
+ "itemSeparatorDescription": "Caractรจre sรฉparateur d'รฉlรฉments",
+ "leftWrapDescription": "Symbole d'enroulement gauche du groupe.",
+ "padNonFullGroups": "Groupes non complets de Pad",
+ "padNonFullGroupsDescription": "Remplissez les groupes non complets avec un รฉlรฉment personnalisรฉ (saisissez ci-dessous).",
+ "paddingCharDescription": "Utilisez ce caractรจre ou cet objet pour complรฉter les groupes non complets.",
+ "resultTitle": "Articles groupรฉs",
+ "rightWrapDescription": "Symbole d'enveloppement droit du groupe.",
+ "shortDescription": "Regrouper les รฉlรฉments de la liste par propriรฉtรฉs communes",
+ "splitOperators": {
+ "regex": {
+ "description": "Dรฉlimitez les รฉlรฉments de la liste dโentrรฉe avec une expression rรฉguliรจre.",
+ "title": "Utiliser une expression rรฉguliรจre pour le fractionnement"
+ },
+ "symbol": {
+ "description": "Dรฉlimitez les รฉlรฉments de la liste d'entrรฉe avec un caractรจre.",
+ "title": "Utiliser un symbole pour le fractionnement"
+ }
+ },
+ "splitSeparatorDescription": "Dรฉfinissez un symbole de dรฉlimitation ou une expression rรฉguliรจre.",
+ "title": "Groupe"
+ },
+ "reverse": {
+ "description": "Cette application trรจs simple, basรฉe sur un navigateur, imprime tous les รฉlรฉments d'une liste ร l'envers. Les รฉlรฉments saisis peuvent รชtre sรฉparรฉs par n'importe quel symbole et vous pouvez รฉgalement modifier le sรฉparateur des รฉlรฉments inversรฉs.",
+ "inputTitle": "Liste d'entrรฉe",
+ "itemSeparator": "Sรฉparateur d'รฉlรฉments",
+ "itemSeparatorDescription": "Dรฉfinissez un symbole de dรฉlimitation ou une expression rรฉguliรจre.",
+ "outputListOptions": "Options de la liste de sortie",
+ "outputSeparatorDescription": "Sรฉparateur d'รฉlรฉments de liste de sortie.",
+ "resultTitle": "Liste inversรฉe",
+ "shortDescription": "Inverser rapidement une liste",
+ "splitOperators": {
+ "regex": {
+ "description": "Dรฉlimitez les รฉlรฉments de la liste dโentrรฉe avec une expression rรฉguliรจre.",
+ "title": "Utiliser une expression rรฉguliรจre pour le fractionnement"
+ },
+ "symbol": {
+ "description": "Dรฉlimitez les รฉlรฉments de la liste d'entrรฉe avec un caractรจre.",
+ "title": "Utiliser un symbole pour le fractionnement"
+ }
+ },
+ "splitterMode": "Mode sรฉparateur",
+ "title": "Inverse",
+ "toolInfo": {
+ "description": "Cet utilitaire permet d'inverser l'ordre des รฉlรฉments d'une liste. Il divise d'abord la liste d'entrรฉe en รฉlรฉments individuels, puis les parcourt du dernier au premier, en affichant chaque รฉlรฉment dans la sortie au cours de l'itรฉration. La liste d'entrรฉe peut contenir tout ce qui peut รชtre reprรฉsentรฉ sous forme de donnรฉes textuelles, notamment des chiffres, des nombres, des chaรฎnes de caractรจres, des mots, des phrases, etc. Le sรฉparateur d'รฉlรฉments d'entrรฉe peut รฉgalement รชtre une expression rรฉguliรจre. Par exemple, l'expression rรฉguliรจre /[;,]/ permet d'utiliser des รฉlรฉments sรฉparรฉs par des virgules ou des points-virgules. Les dรฉlimiteurs des รฉlรฉments d'entrรฉe et de sortie sont personnalisables dans les options. Par dรฉfaut, les listes d'entrรฉe et de sortie sont sรฉparรฉes par des virgules. Incroyableย !",
+ "title": "Qu'est-ce qu'un inverseur de liste ?"
+ }
+ },
+ "rotate": {
+ "description": "L'utilitaire de rotation des รฉlรฉments de liste le plus simple au monde, basรฉ sur un navigateur. Saisissez votre liste et spรฉcifiez le degrรฉ de rotation pour dรฉcaler les รฉlรฉments d'un nombre de positions spรฉcifiรฉ. Idรฉal pour la manipulation de donnรฉes, les dรฉcalages circulaires ou la rรฉorganisation des listes.",
+ "shortDescription": "Faire pivoter les รฉlรฉments de la liste selon des positions spรฉcifiรฉes",
+ "title": "Tourner"
+ },
+ "shuffle": {
+ "delimiterDescription": "Dรฉfinissez un symbole de dรฉlimitation ou une expression rรฉguliรจre.",
+ "description": "L'utilitaire de navigation le plus simple au monde pour mรฉlanger les รฉlรฉments d'une liste. Saisissez votre liste et obtenez instantanรฉment une version alรฉatoire avec les รฉlรฉments dans un ordre alรฉatoire. Idรฉal pour varier, tester le caractรจre alรฉatoire ou mรฉlanger des donnรฉes ordonnรฉes.",
+ "inputListSeparator": "Sรฉparateur de liste d'entrรฉe",
+ "inputTitle": "Liste d'entrรฉe",
+ "joinSeparatorDescription": "Utilisez ce sรฉparateur dans la liste alรฉatoire.",
+ "outputLengthDescription": "Afficher autant d'รฉlรฉments alรฉatoires",
+ "resultTitle": "Liste mรฉlangรฉe",
+ "shortDescription": "Randomiser l'ordre des รฉlรฉments de la liste",
+ "shuffledListLength": "Longueur de la liste mรฉlangรฉe",
+ "shuffledListSeparator": "Sรฉparateur de liste mรฉlangรฉe",
+ "title": "Mรฉlanger"
+ },
+ "sort": {
+ "caseSensitive": "Tri sensible ร la casse",
+ "caseSensitiveDescription": "Trier les majuscules et les minuscules sรฉparรฉment. Les majuscules prรฉcรจdent les minuscules dans une liste ascendante. (Fonctionne uniquement en mode de tri alphabรฉtique.)",
+ "description": "L'utilitaire de tri de listes le plus simple au monde, basรฉ sur un navigateur. Saisissez votre liste et spรฉcifiez des critรจres de tri pour organiser les รฉlรฉments par ordre croissant ou dรฉcroissant. Idรฉal pour l'organisation de donnรฉes, le traitement de texte ou la crรฉation de listes ordonnรฉes.",
+ "inputItemSeparator": "Sรฉparateur d'รฉlรฉments d'entrรฉe",
+ "inputTitle": "Liste d'entrรฉe",
+ "joinSeparatorDescription": "Utilisez ce symbole comme jointure entre les รฉlรฉments d'une liste triรฉe.",
+ "orderDescription": "Sรฉlectionnez un ordre de tri.",
+ "orderOptions": {
+ "decreasing": "Ordre dรฉcroissant",
+ "increasing": "Ordre croissant"
+ },
+ "removeDuplicates": "Supprimer les doublons",
+ "removeDuplicatesDescription": "Supprimer les รฉlรฉments de liste en double.",
+ "resultTitle": "Liste triรฉe",
+ "shortDescription": "Trier les รฉlรฉments de la liste dans l'ordre spรฉcifiรฉ",
+ "sortMethod": "Mรฉthode de tri",
+ "sortMethodDescription": "Sรฉlectionnez une mรฉthode de tri.",
+ "sortOptions": {
+ "alphabetic": "Trier par ordre alphabรฉtique",
+ "length": "Trier par longueur",
+ "numeric": "Trier numรฉriquement"
+ },
+ "sortedItemProperties": "Propriรฉtรฉs des รฉlรฉments triรฉs",
+ "splitOperators": {
+ "regex": {
+ "description": "Dรฉlimitez les รฉlรฉments de la liste dโentrรฉe avec une expression rรฉguliรจre.",
+ "title": "Utiliser une expression rรฉguliรจre pour le fractionnement"
+ },
+ "symbol": {
+ "description": "Dรฉlimitez les รฉlรฉments de la liste d'entrรฉe avec un caractรจre.",
+ "title": "Utiliser un symbole pour le fractionnement"
+ }
+ },
+ "splitSeparatorDescription": "Dรฉfinissez un symbole de dรฉlimitation ou une expression rรฉguliรจre.",
+ "title": "Trier"
+ },
+ "truncate": {
+ "description": "L'utilitaire de tronquage de listes le plus simple au monde, accessible depuis un navigateur. Saisissez votre liste et spรฉcifiez le nombre maximal d'รฉlรฉments ร conserver. Idรฉal pour le traitement de donnรฉes, la gestion de listes ou la limitation de la longueur du contenu.",
+ "shortDescription": "Tronquer la liste au nombre spรฉcifiรฉ d'รฉlรฉments",
+ "title": "Tronquer"
+ },
+ "unwrap": {
+ "description": "L'utilitaire de dรฉpliage de listes le plus simple au monde, basรฉ sur un navigateur. Saisissez votre liste dรฉpliรฉe et spรฉcifiez des critรจres de dรฉpliage pour aplatir les รฉlรฉments organisรฉs. Idรฉal pour le traitement de donnรฉes, la manipulation de texte ou l'extraction de contenu de listes structurรฉes.",
+ "shortDescription": "Dรฉcompresser les รฉlรฉments de la liste ร partir du format structurรฉ",
+ "title": "Dรฉballer"
+ },
+ "wrap": {
+ "description": "Ajoutez du texte avant et aprรจs chaque รฉlรฉment de la liste.",
+ "inputTitle": "Liste d'entrรฉes",
+ "joinSeparatorDescription": "Sรฉparateur pour joindre la liste enveloppรฉe",
+ "leftTextDescription": "Texte ร ajouter avant chaque รฉlรฉment",
+ "removeEmptyItems": "Supprimer les รฉlรฉments vides",
+ "resultTitle": "Liste enveloppรฉe",
+ "rightTextDescription": "Texte ร ajouter aprรจs chaque รฉlรฉment",
+ "shortDescription": "Envelopper les รฉlรฉments de la liste avec des critรจres spรฉcifiรฉs",
+ "splitByRegex": "Diviser par expression rรฉguliรจre",
+ "splitBySymbol": "Diviser par symbole",
+ "splitOptions": "Options de fractionnement",
+ "splitSeparatorDescription": "Sรฉparateur pour diviser la liste",
+ "title": "Envelopper",
+ "toolInfo": {
+ "description": "Cet outil vous permet d'ajouter du texte avant et aprรจs chaque รฉlรฉment d'une liste. Vous pouvez spรฉcifier un texte diffรฉrent pour les cรดtรฉs gauche et droit, et contrรดler le traitement de la liste. Il est utile pour ajouter des guillemets, des crochets ou d'autres รฉlรฉments de mise en forme aux รฉlรฉments d'une liste, prรฉparer des donnรฉes pour diffรฉrents formats ou crรฉer du texte structurรฉ.",
+ "title": "Enveloppement de liste"
+ },
+ "wrapOptions": "Options d'enveloppement"
+ }
+}
diff --git a/public/locales/fr/number.json b/public/locales/fr/number.json
new file mode 100644
index 0000000..6f115d7
--- /dev/null
+++ b/public/locales/fr/number.json
@@ -0,0 +1,89 @@
+{
+ "arithmeticSequence": {
+ "commonDifferenceDescription": "Diffรฉrence courante entre les termes (d)",
+ "description": "Gรฉnรฉrez des sรฉquences arithmรฉtiques avec des paramรจtres personnalisables.",
+ "firstTermDescription": "Premier terme de la suite (aโ)",
+ "numberOfTermsDescription": "Nombre de termes ร gรฉnรฉrer (n)",
+ "outputFormat": "Format de sortie",
+ "resultTitle": "Sรฉquence gรฉnรฉrรฉe",
+ "separatorDescription": "Sรฉparateur entre les termes",
+ "sequenceParameters": "Paramรจtres de sรฉquence",
+ "shortDescription": "Gรฉnรฉrer des sรฉquences arithmรฉtiques",
+ "title": "Sรฉquence arithmรฉtique",
+ "toolInfo": {
+ "description": "Une suite arithmรฉtique est une suite de nombres dont la diffรฉrence entre chaque terme consรฉcutif est constante. Cette diffรฉrence constante est appelรฉe diffรฉrence commune. รtant donnรฉ le premier terme (aโ) et la diffรฉrence commune (d), chaque terme peut รชtre trouvรฉ en additionnant la diffรฉrence commune au terme prรฉcรฉdent.",
+ "title": "Qu'est-ce qu'une suite arithmรฉtique ?"
+ }
+ },
+ "generate": {
+ "arithmeticSequenceOption": "Option de sรฉquence arithmรฉtique",
+ "description": "Gรฉnรฉrer une sรฉquence de nombres avec des paramรจtres personnalisables.",
+ "numberOfElementsDescription": "Nombre d'รฉlรฉments dans la sรฉquence.",
+ "resultTitle": "Numรฉros gรฉnรฉrรฉs",
+ "separator": "Sรฉparateur",
+ "separatorDescription": "Sรฉparez les รฉlรฉments de la sรฉquence arithmรฉtique par ce caractรจre.",
+ "shortDescription": "Gรฉnรฉrer des nombres alรฉatoires dans des plages spรฉcifiรฉes",
+ "startSequenceDescription": "Dรฉmarrer la sรฉquence ร partir de ce numรฉro.",
+ "stepDescription": "Augmentez chaque รฉlรฉment de ce montant",
+ "title": "Gรฉnรฉrer",
+ "toolInfo": {
+ "description": "Cet outil vous permet de gรฉnรฉrer une sรฉquence de nombres avec des paramรจtres personnalisables. Vous pouvez spรฉcifier la valeur de dรฉpart, le pas et le nombre d'รฉlรฉments.",
+ "title": "Gรฉnรฉrer des nombres"
+ }
+ },
+ "ohmsLaw": {
+ "description": "Calcule la tension, le courant et la rรฉsistance",
+ "longDescription": "Cette calculatrice applique la loi d'Ohm (V = I ร R) pour dรฉterminer n'importe lequel des trois paramรจtres รฉlectriques lorsque les deux autres sont connus. La loi d'Ohm est un principe fondamental du gรฉnie รฉlectrique qui dรฉcrit la relation entre la tension (V), le courant (I) et la rรฉsistance (R). Cet outil est essentiel pour les รฉlectroniciens amateurs, les ingรฉnieurs รฉlectriciens et les รฉtudiants travaillant sur des circuits afin de rรฉsoudre rapidement les valeurs inconnues de leurs conceptions รฉlectriques.",
+ "shortDescription": "Calculer la tension, le courant ou la rรฉsistance dans les circuits รฉlectriques en utilisant la loi d'Ohm",
+ "title": "loi d'Ohm"
+ },
+ "slackline": {
+ "description": "Calcule la tension dans une slackline",
+ "longDescription": "Cette calculatrice suppose une charge au centre de la corde",
+ "shortDescription": "Calculez la tension approximative d'une slackline ou d'une corde ร linge. Ne vous fiez pas ร cela pour votre sรฉcuritรฉ.",
+ "title": "Tension de la slackline"
+ },
+ "sphereArea": {
+ "description": "Aire d'une sphรจre",
+ "longDescription": "Cette calculatrice dรฉtermine l'aire de surface d'une sphรจre selon la formule A = 4ฯrยฒ. Vous pouvez saisir le rayon pour trouver l'aire de surface ou saisir l'aire de surface pour calculer le rayon requis. Cet outil est utile aux รฉtudiants en gรฉomรฉtrie, aux ingรฉnieurs travaillant avec des objets sphรฉriques et ร toute personne devant effectuer des calculs impliquant des surfaces sphรฉriques.",
+ "shortDescription": "Calculer l'aire de surface d'une sphรจre en fonction de son rayon",
+ "title": "Aire d'une sphรจre"
+ },
+ "sphereVolume": {
+ "description": "Volume d'une sphรจre",
+ "longDescription": "Cette calculatrice calcule le volume d'une sphรจre selon la formule V = (4/3)ฯrยณ. Vous pouvez saisir le rayon ou le diamรจtre pour trouver le volume, ou saisir le volume pour dรฉterminer le rayon requis. Cet outil est prรฉcieux pour les รฉtudiants, les ingรฉnieurs et les professionnels travaillant avec des objets sphรฉriques dans des domaines tels que la physique, l'ingรฉnierie et la fabrication.",
+ "shortDescription": "Calculer le volume d'une sphรจre en utilisant le rayon ou le diamรจtre",
+ "title": "Volume d'une sphรจre"
+ },
+ "sum": {
+ "description": "Calculez la somme d'une liste de nombres. Saisissez les nombres sรฉparรฉs par des virgules ou des sauts de ligne pour obtenir leur somme totale.",
+ "extractionTypes": {
+ "delimiter": {
+ "description": "Personnalisez le sรฉparateur de nombres ici. (Par dรฉfaut, il s'agit d'un saut de ligne.)",
+ "title": "Dรฉlimiteur de nombre"
+ },
+ "smart": {
+ "description": "Dรฉtection automatique des nombres dans l'entrรฉe.",
+ "title": "Somme intelligente"
+ }
+ },
+ "inputTitle": "Entrรฉe",
+ "numberExtraction": "Extraction de nombres",
+ "printRunningSum": "Imprimer le total cumulรฉ",
+ "printRunningSumDescription": "Affichez la somme telle qu'elle est calculรฉe รฉtape par รฉtape.",
+ "resultTitle": "Total",
+ "runningSum": "Somme courante",
+ "shortDescription": "Calculer la somme des nombres",
+ "title": "Somme",
+ "toolInfo": {
+ "description": "Il s'agit d'un utilitaire en ligne, accessible depuis un navigateur, permettant de calculer la somme de plusieurs nombres. Vous pouvez saisir les nombres sรฉparรฉs par une virgule, un espace ou tout autre caractรจre, y compris le saut de ligne. Vous pouvez รฉgalement simplement coller un fragment de donnรฉes textuelles contenant les valeurs numรฉriques ร additionnerย : l'utilitaire les extraira et calculera leur somme.",
+ "title": "Qu'est-ce qu'une calculatrice de somme numรฉrique ?"
+ }
+ },
+ "voltageDropInWire": {
+ "description": "Calcule la tension aller-retour et la perte de puissance dans un cรขble ร 2 conducteurs",
+ "longDescription": "Ce calculateur permet de dรฉterminer la chute de tension et la perte de puissance dans un cรขble รฉlectrique ร deux conducteurs. Il prend en compte la longueur du cรขble, la section du fil, la rรฉsistivitรฉ du matรฉriau et le flux de courant. Il calcule la chute de tension aller-retour, la rรฉsistance totale du cรขble et la puissance dissipรฉe sous forme de chaleur. Cet outil est particuliรจrement utile aux ingรฉnieurs รฉlectriciens, aux รฉlectriciens et aux bricoleurs pour la conception de systรจmes รฉlectriques afin de garantir que les niveaux de tension restent dans des limites acceptables sous charge.",
+ "shortDescription": "Calculer la chute de tension et la perte de puissance dans les cรขbles รฉlectriques en fonction de la longueur, du matรฉriau et du courant",
+ "title": "Chute de tension aller-retour dans le cรขble"
+ }
+}
diff --git a/public/locales/fr/pdf.json b/public/locales/fr/pdf.json
new file mode 100644
index 0000000..81714b2
--- /dev/null
+++ b/public/locales/fr/pdf.json
@@ -0,0 +1,113 @@
+{
+ "compressPdf": {
+ "compressedFileSize": "Taille du fichier compressรฉ",
+ "compressingPdf": "Compression des PDF...",
+ "compressionLevel": "Niveau de compression",
+ "compressionSettings": "Paramรจtres de compression",
+ "description": "Rรฉduire la taille des fichiers PDF tout en maintenant la qualitรฉ grรขce ร Ghostscript",
+ "errorCompressingPdf": "รchec de la compression du PDF : {{error}}",
+ "errorReadingPdf": "รchec de la lecture du fichier PDF. Veuillez vous assurer qu'il s'agit d'un PDF valide.",
+ "fileSize": "Taille du fichier original",
+ "highCompression": "Compression รฉlevรฉe",
+ "highCompressionDescription": "Rรฉduction maximale de la taille du fichier avec une certaine perte de qualitรฉ",
+ "inputTitle": "Entrรฉe PDF",
+ "lowCompression": "Faible compression",
+ "lowCompressionDescription": "Rรฉduisez lรฉgรจrement la taille du fichier avec une perte de qualitรฉ minimale",
+ "mediumCompression": "Compression moyenne",
+ "mediumCompressionDescription": "รquilibre entre la taille et la qualitรฉ des fichiers",
+ "pages": "Nombre de pages",
+ "resultTitle": "PDF compressรฉ",
+ "shortDescription": "Compresser des fichiers PDF en toute sรฉcuritรฉ dans votre navigateur",
+ "title": "Compresser le PDF"
+ },
+ "editor": {
+ "description": "รditeur PDF avancรฉ avec fonctions d'annotation, de remplissage de formulaires, de surlignage et d'export. Modifiez vos PDF directement dans le navigateur avec des outils de qualitรฉ professionnelle, notamment l'insertion de texte, le dessin, le surlignage, la signature et le remplissage de formulaires.",
+ "shortDescription": "Modifier les PDF avec des outils avancรฉs d'annotation, de signature et d'รฉdition",
+ "title": "Editeur de PDF"
+ },
+ "merge": {
+ "inputTitle": "Entrรฉe PDF",
+ "loadingText": "Extraire les pages",
+ "resultTitle": "Sortie du PDF fusionnรฉ",
+ "toolInfo": {
+ "description": "Cet outil vous permet de fusionner plusieurs fichiers PDF en un seul document. Pour utiliser cet outil, il vous suffit de tรฉlรฉcharger les fichiers PDF que vous souhaitez fusionner. L'outil combinera ensuite toutes les pages des fichiers d'entrรฉe en un seul document PDF.",
+ "title": "Comment utiliser lโoutil de fusion de PDFย ?"
+ }
+ },
+ "mergePdf": {
+ "description": "Comment utiliser l'outil Fusionner PDF ?",
+ "inputTitle": "PDF d'entrรฉe",
+ "mergingPdfs": "Fusion de PDF",
+ "pdfOptions": "Options PDF",
+ "resultTitle": "PDF fusionnรฉ",
+ "shortDescription": "Fusionner plusieurs fichiers PDF en un seul document",
+ "sortByFileName": "Trier par nom de fichier",
+ "sortByFileNameDescription": "Trier les PDF par ordre alphabรฉtique par nom de fichier",
+ "sortByUploadOrder": "Trier par ordre de tรฉlรฉchargement",
+ "sortByUploadOrderDescription": "Conserver les fichiers PDF dans l'ordre dans lequel ils ont รฉtรฉ tรฉlรฉchargรฉs",
+ "title": "Fusionner des PDF",
+ "toolInfo": {
+ "description": "Cet outil vous permet de combiner plusieurs fichiers PDF en un seul document. Vous pouvez choisir comment trier les PDF et l'outil les fusionnera dans l'ordre spรฉcifiรฉ.",
+ "title": "Fusionner des fichiers PDF"
+ }
+ },
+ "pdfToEpub": {
+ "description": "Transformez les documents PDF en fichiers EPUB pour une meilleure compatibilitรฉ avec les liseuses.', icon: 'material-symbols:import-contacts', component: lazy(() => import('./index')), keywords: ['pdf', 'epub', 'convert', 'ebook'], path: 'pdf-to-epub', i18n: { name: 'pdf:pdfToEpub.title', description: 'pdf:pdfToEpub.description",
+ "shortDescription": "Convertir des fichiers PDF au format EPUB",
+ "title": "PDF vers EPUB"
+ },
+ "pdfToPng": {
+ "description": "Transformez les documents PDF en panneaux PNG.",
+ "longDescription": "Tรฉlรฉchargez un PDF et convertissez chaque page en image PNG de haute qualitรฉ directement dans votre navigateur. Cet outil est idรฉal pour extraire du contenu visuel ou partager des pages individuelles. Aucune donnรฉe n'est tรฉlรฉchargรฉeย : tout fonctionne en local.",
+ "shortDescription": "Convertir des PDF en images PNG",
+ "title": "PDF en PNG"
+ },
+ "protectPdf": {
+ "description": "Ajoutez une protection par mot de passe ร vos fichiers PDF en toute sรฉcuritรฉ dans votre navigateur",
+ "shortDescription": "Protรฉgez les fichiers PDF en toute sรฉcuritรฉ avec un mot de passe",
+ "title": "Protรฉger le PDF"
+ },
+ "rotatePdf": {
+ "allPagesWillBeRotated": "Les {{count}} pages seront tournรฉes",
+ "angleOptions": {
+ "clockwise90": "90ยฐ dans le sens des aiguilles d'une montre",
+ "counterClockwise270": "270ยฐ (90ยฐ dans le sens inverse des aiguilles d'une montre)",
+ "upsideDown180": "180ยฐ (ร l'envers)"
+ },
+ "applyToAllPages": "Appliquer ร toutes les pages",
+ "description": "Faire pivoter les pages d'un document PDF.",
+ "inputTitle": "Entrรฉe PDF",
+ "longDescription": "Modifiez l'orientation des pages PDF en les faisant pivoter de 90, 180 ou 270 degrรฉs. Utile pour corriger des documents mal numรฉrisรฉs ou prรฉparer des PDF pour l'impression.",
+ "pageRangesDescription": "Saisissez les numรฉros de page ou les plages sรฉparรฉs par des virgules (par exemple, 1, 3, 5-7)",
+ "pageRangesPlaceholder": "par exemple, 1,5-8",
+ "pagesWillBeRotated": "{{count}} page{{count !== 1 ? 's' : ''}} sera tournรฉ",
+ "pdfPageCount": "PDF a {{count}} page{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "PDF pivotรฉ",
+ "rotatingPages": "Rotation des pages",
+ "rotationAngle": "Angle de rotation",
+ "rotationSettings": "Paramรจtres de rotation",
+ "shortDescription": "Faire pivoter les pages d'un document PDF",
+ "title": "Faire pivoter le PDF",
+ "toolInfo": {
+ "description": "Cet outil vous permet de faire pivoter les pages d'un document PDF. Vous pouvez faire pivoter toutes les pages ou spรฉcifier des pages individuelles. Choisissez un angle de rotationย : 90ยฐ dans le sens horaire, 180ยฐ (ร l'envers) ou 270ยฐ (90ยฐ dans le sens antihoraire). Pour faire pivoter des pages spรฉcifiques, dรฉcochez ยซย Appliquer ร toutes les pagesย ยป et saisissez les numรฉros de page ou les plages de numรฉros sรฉparรฉs par des virgules (par exemple, 1, 3, 5-7).",
+ "title": "Comment utiliser l'outil de rotation PDF"
+ }
+ },
+ "splitPdf": {
+ "description": "Extraire des pages spรฉcifiques d'un document PDF.",
+ "extractingPages": "Extraire les pages",
+ "inputTitle": "Entrรฉe PDF",
+ "pageExtractionPreview": "{{count}} page{{count !== 1 ? 's' : ''}} sera(ont) extrait(s)",
+ "pageRangesDescription": "Saisissez les numรฉros de page ou les plages sรฉparรฉs par des virgules (par exemple, 1, 3, 5-7)",
+ "pageRangesPlaceholder": "par exemple, 1,5-8",
+ "pageSelection": "Sรฉlection de page",
+ "pdfPageCount": "PDF a {{count}} page{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "PDF extrait",
+ "shortDescription": "Extraire des pages spรฉcifiques d'un fichier PDF",
+ "title": "Diviser le PDF",
+ "toolInfo": {
+ "description": "Cet outil vous permet d'extraire des pages spรฉcifiques d'un document PDF. Vous pouvez spรฉcifier des pages individuelles ou des plages de pages ร extraire.",
+ "title": "Diviser le PDF"
+ }
+ }
+}
diff --git a/public/locales/fr/string.json b/public/locales/fr/string.json
new file mode 100644
index 0000000..8fbaacc
--- /dev/null
+++ b/public/locales/fr/string.json
@@ -0,0 +1,261 @@
+{
+ "base64": {
+ "decode": "Dรฉcodage Base64",
+ "description": "Encodez ou dรฉcodez du texte ร l'aide de l'encodage Base64.",
+ "encode": "Encodage Base64",
+ "inputTitle": "Donnรฉes d'entrรฉe",
+ "optionsTitle": "Options Base64",
+ "resultTitle": "Rรฉsultat",
+ "shortDescription": "Encoder ou dรฉcoder des donnรฉes ร l'aide de Base64.",
+ "title": "Encodeur/dรฉcodeur Base64",
+ "toolInfo": {
+ "description": "Base64 est un schรฉma de codage qui reprรฉsente les donnรฉes au format chaรฎne ASCII en les convertissant en une reprรฉsentation radix-64. Bien qu'il puisse รชtre utilisรฉ pour encoder des chaรฎnes, il est couramment utilisรฉ pour encoder des donnรฉes binaires destinรฉes ร รชtre transmises sur des supports conรงus pour traiter des donnรฉes textuelles.",
+ "title": "Qu'est-ce que Base64 ?"
+ }
+ },
+ "censor": {
+ "description": "Utilitaire de censure de mots dans un texte. Chargez votre texte dans le formulaire de saisie ร gauche, spรฉcifiez tous les mots interdits dans les options et vous obtiendrez instantanรฉment le texte censurรฉ dans la zone de sortie. ยป, longDescription: ยซ Avec cet outil en ligne, vous pouvez censurer certains mots dans n'importe quel texte. Vous pouvez spรฉcifier une liste de mots indรฉsirables (tels que des jurons ou des mots secrets) et le programme les remplacera par d'autres mots pour crรฉer un texte lisible. Les mots peuvent รชtre spรฉcifiรฉs dans un champ de texte multiligne dans les options, en saisissant un mot par ligne. ยป, keywords: ['text', 'censor', 'words', 'characters'], component: lazy(() => import('./index')), i18n: { name: 'string:censor.title', description: 'string:censor.description",
+ "shortDescription": "Masquez rapidement les gros mots ou remplacez-les par des mots alternatifs.",
+ "title": "Censure de texte"
+ },
+ "createPalindrome": {
+ "description": "L'utilitaire de navigateur le plus simple au monde pour crรฉer des palindromes ร partir de n'importe quel texte. Saisissez du texte et transformez-le instantanรฉment en un palindrome qui se lit de la mรชme maniรจre ร l'endroit comme ร l'envers. Idรฉal pour les jeux de mots, la crรฉation de motifs de texte symรฉtriques ou l'exploration de curiositรฉs linguistiques.",
+ "shortDescription": "Crรฉez un texte qui se lit de la mรชme maniรจre ร l'avant et ร l'arriรจre",
+ "title": "Crรฉer un palindrome"
+ },
+ "extractSubstring": {
+ "description": "L'utilitaire le plus simple au monde, basรฉ sur un navigateur, pour extraire des sous-chaรฎnes de texte. Saisissez votre texte et spรฉcifiez les positions de dรฉbut et de fin pour extraire la portion souhaitรฉe. Idรฉal pour le traitement de donnรฉes, l'analyse de texte ou l'extraction de contenu spรฉcifique ร partir de blocs de texte volumineux.",
+ "shortDescription": "Extraire une partie de texte entre des positions spรฉcifiรฉes",
+ "title": "Extraire la sous-chaรฎne"
+ },
+ "join": {
+ "blankLinesAndTrailingSpaces": "Lignes vides et espaces de fin",
+ "deleteBlankDescription": "Supprimez les lignes qui nโont pas de symboles de texte.",
+ "deleteBlankTitle": "Supprimer les lignes vides",
+ "deleteTrailingDescription": "Supprimez les espaces et les tabulations ร la fin des lignes.",
+ "deleteTrailingTitle": "Supprimer les espaces de fin",
+ "description": "Joignez des morceaux de texte avec des sรฉparateurs personnalisables.",
+ "inputTitle": "Textes",
+ "joinCharacterDescription": "Symbole reliant les fragments de texte. (Espace par dรฉfaut.)",
+ "joinCharacterPlaceholder": "Rejoindre le personnage",
+ "resultTitle": "Texte joint",
+ "shortDescription": "Joindre des รฉlรฉments de texte avec un sรฉparateur spรฉcifiรฉ",
+ "textMergedOptions": "Options de fusion de texte",
+ "title": "Joindre le texte",
+ "toolInfo": {
+ "description": "Cet outil vous permet de fusionner des parties de texte. Il prend une liste de valeurs de texte, sรฉparรฉes par des sauts de ligne, et les fusionne. Vous pouvez dรฉfinir le caractรจre qui sera placรฉ entre les parties du texte combinรฉ. Vous pouvez รฉgalement ignorer les lignes vides et supprimer les espaces et les tabulations ร la fin de chaque ligne. Textabulousย !",
+ "title": "Qu'est-ce qu'un outil de jointure de texte ?"
+ }
+ },
+ "palindrome": {
+ "description": "L'utilitaire le plus simple au monde, basรฉ sur un navigateur, permet de vรฉrifier si un texte est un palindrome. Vรฉrifiez instantanรฉment si votre texte se lit de la mรชme maniรจre ร l'endroit comme ร l'envers. Idรฉal pour les jeux de mots, l'analyse linguistique ou la validation de structures de texte symรฉtriques. Prend en charge divers dรฉlimiteurs et la dรฉtection de palindromes multi-mots.",
+ "shortDescription": "Vรฉrifiez si le texte se lit de la mรชme maniรจre ร l'avant et ร l'arriรจre",
+ "title": "Palindrome"
+ },
+ "passwordGenerator": {
+ "avoidAmbiguous": "รvitez les caractรจres ambigus (i, I, l, 0, O)",
+ "description": "Gรฉnรฉrez des mots de passe alรฉatoires sรฉcurisรฉs avec une longueur et des types de caractรจres personnalisables. Choisissez entre minuscules, majuscules, chiffres et caractรจres spรฉciaux. Option permettant d'รฉviter les caractรจres ambigus pour une meilleure lisibilitรฉ.",
+ "includeLowercase": "Inclure des lettres minuscules (a-z)",
+ "includeNumbers": "Inclure des chiffres (0-9)",
+ "includeSymbols": "Inclure des caractรจres spรฉciaux",
+ "includeUppercase": "Inclure des lettres majuscules (A-Z)",
+ "lengthDesc": "Longueur du mot de passe",
+ "lengthPlaceholder": "par exemple 12",
+ "optionsTitle": "Options de mot de passe",
+ "resultTitle": "Mot de passe gรฉnรฉrรฉ",
+ "shortDescription": "Gรฉnรฉrez des mots de passe alรฉatoires sรฉcurisรฉs avec des options personnalisรฉes",
+ "title": "Gรฉnรฉrateur de mot de passe",
+ "toolInfo": {
+ "description": "Cet outil gรฉnรจre des mots de passe alรฉatoires sรฉcurisรฉs selon vos critรจres. Vous pouvez personnaliser la longueur, inclure ou exclure diffรฉrents types de caractรจres et รฉviter les caractรจres ambigus pour une meilleure lisibilitรฉ. Idรฉal pour crรฉer des mots de passe forts pour vos comptes, applications ou tout autre besoin de sรฉcuritรฉ.",
+ "title": "ร propos du gรฉnรฉrateur de mots de passe"
+ }
+ },
+ "quote": {
+ "allowDoubleQuotation": "Autoriser les guillemets doubles",
+ "description": "Ajoutez des guillemets autour du texte avec des options personnalisables.",
+ "inputTitle": "Texte d'entrรฉe",
+ "leftQuoteDescription": "Caractรจre(s) de citation gauche",
+ "processAsMultiLine": "Traiter comme un texte multiligne",
+ "quoteEmptyLines": "Citer les lignes vides",
+ "quoteOptions": "Options de devis",
+ "resultTitle": "Texte citรฉ",
+ "rightQuoteDescription": "Caractรจre(s) de citation ร droite",
+ "shortDescription": "Ajoutez des guillemets autour du texte avec diffรฉrents styles",
+ "title": "Citation de texte",
+ "toolInfo": {
+ "description": "Cet outil vous permet d'insรฉrer des guillemets autour du texte. Vous pouvez choisir diffรฉrents caractรจres de guillemets, gรฉrer du texte multiligne et contrรดler le traitement des lignes vides. Il est utile pour prรฉparer du texte pour la programmation, formater des donnรฉes ou crรฉer du texte stylisรฉ.",
+ "title": "Citation de texte"
+ }
+ },
+ "randomizeCase": {
+ "description": "L'utilitaire de sรฉlection alรฉatoire de casse de texte le plus simple au monde, basรฉ sur un navigateur. Saisissez votre texte et transformez-le instantanรฉment en ajoutant des majuscules et des minuscules alรฉatoires. Idรฉal pour crรฉer des effets de texte uniques, tester la sensibilitรฉ ร la casse ou gรฉnรฉrer des modรจles de texte variรฉs.",
+ "shortDescription": "Randomiser la casse des lettres dans le texte",
+ "title": "Cas randomisรฉ"
+ },
+ "removeDuplicateLines": {
+ "description": "Chargez votre texte dans le formulaire de saisie ร gauche et obtenez instantanรฉment du texte sans doublons dans la zone de sortie. Puissant, gratuit et rapide. Chargez des lignes de texteย : obtenez des lignes de texte uniques.",
+ "shortDescription": "Supprimez rapidement toutes les lignes rรฉpรฉtรฉes du texte",
+ "title": "Supprimer les lignes en double"
+ },
+ "repeat": {
+ "delimiterDescription": "Dรฉlimiteur pour les copies de sortie.",
+ "delimiterPlaceholder": "Dรฉlimiteur",
+ "description": "Rรฉpรฉtez le texte plusieurs fois avec des sรฉparateurs personnalisables.",
+ "inputTitle": "Texte d'entrรฉe",
+ "numberPlaceholder": "Nombre",
+ "repeatAmountDescription": "Nombre de rรฉpรฉtitions.",
+ "repetitionsDelimiter": "Dรฉlimiteur de rรฉpรฉtitions",
+ "resultTitle": "Texte rรฉpรฉtรฉ",
+ "shortDescription": "Rรฉpรฉter le texte plusieurs fois",
+ "textRepetitions": "Rรฉpรฉtitions de texte",
+ "title": "Rรฉpรฉter le texte",
+ "toolInfo": {
+ "description": "Cet outil vous permet de rรฉpรฉter un texte donnรฉ plusieurs fois avec un sรฉparateur optionnel.",
+ "title": "Rรฉpรฉter le texte"
+ }
+ },
+ "reverse": {
+ "description": "L'utilitaire d'inversion de texte le plus simple au monde, basรฉ sur un navigateur. Saisissez n'importe quel texte et inversez-le instantanรฉment, caractรจre par caractรจre. Idรฉal pour crรฉer du texte miroir, analyser des palindromes ou jouer avec les motifs de texte. Prรฉserve les espaces et les caractรจres spรฉciaux lors de l'inversion.",
+ "inputTitle": "Texte ร inverser",
+ "processMultiLine": "Traiter un texte multiligne",
+ "processMultiLineDescription": "Chaque ligne sera inversรฉe indรฉpendamment",
+ "resultTitle": "Texte inversรฉ",
+ "reversalOptions": "Options d'inversion",
+ "shortDescription": "Inverser n'importe quel texte caractรจre par caractรจre",
+ "skipEmptyLines": "Sauter les lignes vides",
+ "skipEmptyLinesDescription": "Les lignes vides seront supprimรฉes de la sortie",
+ "title": "Inverse",
+ "trimWhitespace": "Couper les espaces blancs",
+ "trimWhitespaceDescription": "Supprimer les espaces de dรฉbut et de fin de chaque ligne"
+ },
+ "rot13": {
+ "description": "Coder ou dรฉcoder du texte ร l'aide du chiffrement ROT13.",
+ "inputTitle": "Texte d'entrรฉe",
+ "resultTitle": "Rรฉsultat ROT13",
+ "shortDescription": "Coder ou dรฉcoder du texte ร l'aide du chiffrement ROT13.",
+ "title": "Encodeur/dรฉcodeur ROT13",
+ "toolInfo": {
+ "description": "ROT13 (rotation de 13 positions) est un chiffrement par substitution de lettres simple qui remplace une lettre par la 13e lettre suivante dans l'alphabet. ROT13 est un cas particulier du chiffrement de Cรฉsar, dรฉveloppรฉ dans la Rome antique. L'alphabet anglais comportant 26 lettres, ROT13 est son propre inverseย ; pour annuler ROT13, le mรชme algorithme est appliquรฉ, permettant ainsi la mรชme opรฉration de codage et de dรฉcodage.",
+ "title": "Qu'est-ce que ROT13 ?"
+ }
+ },
+ "rotate": {
+ "description": "Faire pivoter les caractรจres du texte selon des positions spรฉcifiรฉes.",
+ "inputTitle": "Texte d'entrรฉe",
+ "processAsMultiLine": "Traiter comme un texte multiligne (faire pivoter chaque ligne sรฉparรฉment)",
+ "resultTitle": "Texte pivotรฉ",
+ "rotateLeft": "Tourner ร gauche",
+ "rotateRight": "Tourner ร droite",
+ "rotationOptions": "Options de rotation",
+ "shortDescription": "Dรฉcaler les caractรจres dans le texte par position.",
+ "stepDescription": "Nombre de positions ร faire tourner",
+ "title": "Faire pivoter le texte",
+ "toolInfo": {
+ "description": "Cet outil vous permet de faire pivoter les caractรจres d'une chaรฎne d'un nombre spรฉcifiรฉ de positions. Vous pouvez effectuer une rotation vers la gauche ou la droite, et traiter du texte multiligne en faisant pivoter chaque ligne sรฉparรฉment. La rotation de chaรฎne est utile pour les transformations de texte simples, la crรฉation de motifs ou la mise en ลuvre de techniques de chiffrement de base.",
+ "title": "Rotation des cordes"
+ }
+ },
+ "split": {
+ "charAfterChunkDescription": "Caractรจre aprรจs chaque morceau",
+ "charBeforeChunkDescription": "Caractรจre avant chaque morceau",
+ "chunksDescription": "Nombre de morceaux de longueur รฉgale dans la sortie.",
+ "chunksTitle": "Utiliser un certain nombre de morceaux",
+ "description": "L'utilitaire de dรฉcoupage de texte basรฉ sur navigateur le plus simple au monde. Saisissez votre texte et spรฉcifiez un sรฉparateur pour le diviser en plusieurs parties. Idรฉal pour le traitement de donnรฉes, la manipulation de texte ou l'extraction de contenu spรฉcifique ร partir de blocs de texte volumineux.",
+ "lengthDescription": "Nombre de symboles qui seront placรฉs dans chaque bloc de sortie.",
+ "lengthTitle": "Utiliser la longueur pour le fractionnement",
+ "outputSeparatorDescription": "Caractรจre ร insรฉrer entre les segments sรฉparรฉs. (Par dรฉfaut, il s'agit du saut de ligne ยซย \\nย ยป.)",
+ "outputSeparatorOptions": "Options de sรฉparateur de sortie",
+ "regexDescription": "Expression rรฉguliรจre permettant de diviser le texte en plusieurs parties.\n(Plusieurs espaces par dรฉfaut.)",
+ "regexTitle": "Utiliser une expression rรฉguliรจre pour le fractionnement",
+ "resultTitle": "Textes",
+ "shortDescription": "Diviser le texte en plusieurs parties ร l'aide d'un sรฉparateur",
+ "splitSeparatorOptions": "Options de sรฉparateur fractionnรฉ",
+ "symbolDescription": "Caractรจre permettant de diviser le texte en plusieurs parties.\n(Espace par dรฉfaut.)",
+ "symbolTitle": "Utiliser un symbole pour le fractionnement",
+ "title": "Diviser"
+ },
+ "statistic": {
+ "characterFrequencyAnalysis": "Analyse de la frรฉquence des caractรจres",
+ "characterFrequencyAnalysisDescription": "Comptez la frรฉquence ร laquelle chaque caractรจre apparaรฎt dans le texte",
+ "delimitersOptions": "Options de dรฉlimiteurs",
+ "description": "Analysez le texte et gรฉnรฉrez des statistiques complรจtes.",
+ "includeEmptyLines": "Inclure les lignes vides",
+ "includeEmptyLinesDescription": "Inclure les lignes vides lors du comptage des lignes",
+ "inputTitle": "Texte d'entrรฉe",
+ "resultTitle": "Statistiques textuelles",
+ "sentenceDelimitersDescription": "Saisissez les caractรจres personnalisรฉs utilisรฉs pour dรฉlimiter les phrases dans votre langue (sรฉparรฉs par une virgule) ou laissez-le vide par dรฉfaut.",
+ "sentenceDelimitersPlaceholder": "par exemple ., !, ?, ...",
+ "shortDescription": "Obtenez des statistiques sur votre texte",
+ "statisticsOptions": "Options de statistiques",
+ "title": "Statistiques textuelles",
+ "toolInfo": {
+ "description": "Cet outil vous permet d'analyser du texte et de gรฉnรฉrer des statistiques complรจtes, notamment le nombre de caractรจres, le nombre de mots, le nombre de lignes et l'analyse de frรฉquence des caractรจres et des mots.",
+ "title": "Qu'est-ce qu'un {{title}}?"
+ },
+ "wordDelimitersDescription": "Saisissez une expression rรฉguliรจre personnalisรฉe pour compter les mots ou laissez-la vide par dรฉfaut.",
+ "wordDelimitersPlaceholder": "par exemple \\s.,;:!?\"ยซยป()โฆ",
+ "wordFrequencyAnalysis": "Analyse de frรฉquence des mots",
+ "wordFrequencyAnalysisDescription": "Comptez la frรฉquence ร laquelle chaque mot apparaรฎt dans le texte"
+ },
+ "textReplacer": {
+ "description": "Remplacez les modรจles de texte par un nouveau contenu.",
+ "findPatternInText": "Trouver ce modรจle dans le texte",
+ "findPatternUsingRegexp": "Trouver un modรจle ร l'aide d'une expression rรฉguliรจre",
+ "inputTitle": "Texte ร remplacer",
+ "newTextPlaceholder": "Nouveau texte",
+ "regexpDescription": "Saisissez lโexpression rรฉguliรจre que vous souhaitez remplacer.",
+ "replacePatternDescription": "Saisissez le modรจle ร utiliser pour le remplacement.",
+ "replaceText": "Remplacer le texte",
+ "resultTitle": "Texte avec remplacements",
+ "searchPatternDescription": "Saisissez le modรจle de texte que vous souhaitez remplacer.",
+ "searchText": "Texte de recherche",
+ "shortDescription": "Remplacez rapidement du texte dans votre contenu",
+ "title": "Remplaceur de texte",
+ "toolInfo": {
+ "description": "Remplacez facilement du texte spรฉcifique dans votre contenu grรขce ร cet outil simple et accessible depuis un navigateur. Saisissez simplement votre texte, dรฉfinissez le texte ร remplacer et la valeur de remplacement, et obtenez instantanรฉment la version mise ร jour.",
+ "title": "Remplaceur de texte"
+ }
+ },
+ "toMorse": {
+ "dashSymbolDescription": "Symbole qui correspondra au tiret dans le code Morse.",
+ "description": "Convertir du texte en code Morse.",
+ "dotSymbolDescription": "Symbole qui correspondra au point dans le code Morse.",
+ "longSignal": "Signal long",
+ "resultTitle": "code Morse",
+ "shortDescription": "Encoder rapidement du texte en morse",
+ "shortSignal": "Signal court",
+ "title": "Chaรฎne en morse"
+ },
+ "truncate": {
+ "addTruncationIndicator": "Ajouter un indicateur de troncature",
+ "charactersPlaceholder": "Personnages",
+ "description": "Raccourcir le texte ร une longueur spรฉcifiรฉe.",
+ "indicatorDescription": "Caractรจres ร ajouter ร la fin (ou au dรฉbut) du texte. Remarqueย : ils sont pris en compte dans la longueur.",
+ "inputTitle": "Texte d'entrรฉe",
+ "leftSideDescription": "Supprimer des caractรจres du dรฉbut du texte.",
+ "leftSideTruncation": "Troncature du cรดtรฉ gauche",
+ "lengthAndLines": "Longueur et lignes",
+ "lineByLineDescription": "Tronquez chaque ligne sรฉparรฉment.",
+ "lineByLineTruncating": "Tronquer ligne par ligne",
+ "maxLengthDescription": "Nombre de caractรจres ร laisser dans le texte.",
+ "numberPlaceholder": "Nombre",
+ "resultTitle": "Texte tronquรฉ",
+ "rightSideDescription": "Supprimer les caractรจres de la fin du texte.",
+ "rightSideTruncation": "Troncature du cรดtรฉ droit",
+ "shortDescription": "Tronquer le texte ร une longueur spรฉcifiรฉe",
+ "suffixAndAffix": "Suffixe et affixe",
+ "title": "Tronquer le texte",
+ "toolInfo": {
+ "description": "Chargez votre texte dans le formulaire de saisie ร gauche et vous obtiendrez automatiquement du texte tronquรฉ ร droite.",
+ "title": "Tronquer le texte"
+ },
+ "truncationSide": "Cรดtรฉ troncature"
+ },
+ "uppercase": {
+ "description": "Convertir le texte en lettres majuscules.",
+ "inputTitle": "Texte d'entrรฉe",
+ "resultTitle": "Texte en majuscules",
+ "shortDescription": "Convertir le texte en majuscules",
+ "title": "Convertir en majuscules"
+ }
+}
diff --git a/public/locales/fr/time.json b/public/locales/fr/time.json
new file mode 100644
index 0000000..e242426
--- /dev/null
+++ b/public/locales/fr/time.json
@@ -0,0 +1,100 @@
+{
+ "checkLeapYears": {
+ "description": "Vรฉrifiez si une annรฉe est bissextile et obtenez des informations sur les annรฉes bissextiles.",
+ "inputTitle": "Annรฉe d'entrรฉe",
+ "resultTitle": "Rรฉsultat de l'annรฉe bissextile",
+ "shortDescription": "Vรฉrifiez si une annรฉe est bissextile",
+ "title": "Vรฉrifiez les annรฉes bissextiles",
+ "toolInfo": {
+ "description": "Une annรฉe bissextile est une annรฉe comportant un jour supplรฉmentaire (le 29 fรฉvrier) pour synchroniser l'annรฉe civile avec l'annรฉe astronomique. Les annรฉes bissextiles ont lieu tous les 4 ans, sauf pour les annรฉes divisibles par 100 mais pas par 400.",
+ "title": "Qu'est-ce qu'une annรฉe bissextile ?"
+ }
+ },
+ "convertDaysToHours": {
+ "addHoursName": "Ajouter le nom des heures",
+ "addHoursNameDescription": "Ajoutez la chaรฎne hours aux valeurs de sortie",
+ "description": "Convertissez les jours en heures avec des options personnalisables.",
+ "hoursName": "Nom des heures",
+ "shortDescription": "Convertir des jours en heures",
+ "title": "Convertir des jours en heures",
+ "toolInfo": {
+ "description": "Cet outil vous permet de convertir des jours en heures. Vous pouvez saisir les jours sous forme de nombres ou d'unitรฉs, et l'outil les convertira en heures. Vous pouvez รฉgalement ajouter le suffixe ยซย heuresย ยป aux valeurs de sortie.",
+ "title": "Convertir des jours en heures"
+ }
+ },
+ "convertHoursToDays": {
+ "addDaysName": "Ajouter le nom du jour",
+ "addDaysNameDescription": "Ajoutez la chaรฎne days aux valeurs de sortie",
+ "daysName": "Nom des jours",
+ "description": "Convertissez les heures en jours avec des options personnalisables.",
+ "shortDescription": "Convertir des heures en jours",
+ "title": "Convertir des heures en jours",
+ "toolInfo": {
+ "description": "Cet outil vous permet de convertir des heures en jours. Vous pouvez saisir des heures sous forme de nombres ou d'unitรฉs, et l'outil les convertira en jours. Vous pouvez รฉgalement ajouter le suffixe ยซย joursย ยป aux valeurs de sortie.",
+ "title": "Convertir des heures en jours"
+ }
+ },
+ "convertSecondsToTime": {
+ "addPadding": "Ajouter un rembourrage",
+ "addPaddingDescription": "Ajoutez un remplissage de zรฉro aux heures, minutes et secondes.",
+ "description": "Convertissez les secondes dans un format horaire lisible (heures:minutes:secondes). Saisissez le nombre de secondes pour obtenir l'heure formatรฉe.",
+ "shortDescription": "Convertir les secondes au format horaire",
+ "timePadding": "Remplissage temporel",
+ "title": "Convertir les secondes en temps",
+ "toolInfo": {
+ "title": "Qu'est-ce qu'un {{title}}?"
+ }
+ },
+ "convertTimeToSeconds": {
+ "description": "Convertissez l'heure formatรฉe (HH:MM:SS) en secondes.",
+ "inputTitle": "Heure d'entrรฉe",
+ "resultTitle": "Secondes",
+ "shortDescription": "Convertir le format de l'heure en secondes",
+ "title": "Convertir le temps en secondes",
+ "toolInfo": {
+ "description": "Cet outil permet de convertir des chaรฎnes de temps formatรฉes (HH:MM:SS) en secondes. Il est utile pour calculer des durรฉes et des intervalles de temps.",
+ "title": "Convertir le temps en secondes"
+ }
+ },
+ "crontabGuru": {
+ "description": "Gรฉnรฉrez et comprenez les expressions Cron. Crรฉez des planifications Cron pour les tรขches automatisรฉes et les tรขches systรจme.",
+ "shortDescription": "Gรฉnรฉrer et comprendre les expressions cron",
+ "title": "Crontab Guru"
+ },
+ "timeBetweenDates": {
+ "description": "Calculez le dรฉcalage horaire entre deux dates. Obtenez la durรฉe exacte en jours, heures, minutes et secondes.",
+ "endDate": "Date de fin",
+ "endDateTime": "Date et heure de fin",
+ "endTime": "Fin des temps",
+ "endTimezone": "Fuseau horaire de fin",
+ "shortDescription": "Calculer le temps entre deux dates",
+ "startDate": "Date de dรฉbut",
+ "startDateTime": "Date et heure de dรฉbut",
+ "startTime": "Heure de dรฉbut",
+ "startTimezone": "Fuseau horaire de dรฉpart",
+ "title": "Temps entre les dates",
+ "toolInfo": {
+ "description": "Calculez le dรฉcalage horaire exact entre deux dates et heures, avec la prise en charge de diffรฉrents fuseaux horaires. Cet outil fournit une analyse dรฉtaillรฉe du dรฉcalage horaire en diffรฉrentes unitรฉs (annรฉes, mois, jours, heures, minutes et secondes).",
+ "title": "Calculateur de temps entre les dates"
+ }
+ },
+ "truncateClockTime": {
+ "description": "Tronquez l'heure pour supprimer les secondes ou les minutes. Arrondissez l'heure ร l'heure, ร la minute ou ร l'intervalle personnalisรฉ le plus proche.",
+ "printDroppedComponents": "Imprimer les composants supprimรฉs",
+ "shortDescription": "Tronquer l'heure de l'horloge ร la prรฉcision spรฉcifiรฉe",
+ "timePadding": "Remplissage temporel",
+ "title": "Tronquer l'heure de l'horloge",
+ "toolInfo": {
+ "title": "Qu'est-ce qu'un {{title}}?"
+ },
+ "truncateMinutesAndSeconds": "Tronquer les minutes et les secondes",
+ "truncateMinutesAndSecondsDescription": "Supprimez les deux composants โ les minutes et les secondes โ de chaque heure dโhorloge.",
+ "truncateOnlySeconds": "Tronquer uniquement les secondes",
+ "truncateOnlySecondsDescription": "Supprimez le composant secondes de chaque heure d'horloge.",
+ "truncationSide": "Cรดtรฉ troncature",
+ "useZeroPadding": "Utiliser le remplissage zรฉro",
+ "zeroPaddingDescription": "Faites en sorte que tous les composants de temps aient toujours une largeur de deux chiffres.",
+ "zeroPrintDescription": "Afficher les parties supprimรฉes sous forme de valeurs nulles ยซ 00 ยป.",
+ "zeroPrintTruncatedParts": "Parties tronquรฉes sans impression"
+ }
+}
diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json
new file mode 100644
index 0000000..3257c16
--- /dev/null
+++ b/public/locales/fr/translation.json
@@ -0,0 +1,250 @@
+{
+ "audio": {
+ "changeSpeed": {
+ "description": "Modifier la vitesse de lecture des fichiers audio. Accรฉlรฉrer ou ralentir le son tout en conservant la hauteur.",
+ "name": "Changer la vitesse audio",
+ "shortDescription": "Modifier la vitesse des fichiers audio"
+ },
+ "extractAudio": {
+ "description": "Extrayez la piste audio d'un fichier vidรฉo et enregistrez-la en tant que fichier audio sรฉparรฉ dans le format de votre choix (AAC, MP3, WAV).",
+ "name": "Extraire l'audio",
+ "shortDescription": "Extrayez l'audio des fichiers vidรฉo (MP4, MOV, etc.) vers AAC, MP3 ou WAV."
+ }
+ },
+ "baseFileInput": {
+ "copyFailed": "รchec de la copieย : {{error}}",
+ "dropFileHere": "Dรฉposez votre {{type}} ici",
+ "fileCopied": "Fichier copiรฉ",
+ "selectFileDescription": "Cliquez ici pour sรฉlectionner un {{type}} depuis votre appareil, appuyez sur Ctrl+V pour utiliser un {{type}} depuis votre presse-papiers ou faites glisser et dรฉposez un fichier depuis le bureau"
+ },
+ "categories": {
+ "audio": {
+ "description": "Outils pour travailler avec l'audio : extraire l'audio d'une vidรฉo, ajuster la vitesse de l'audio, fusionner plusieurs fichiers audio et bien plus encore.",
+ "title": "Outils audio"
+ },
+ "csv": {
+ "description": "Outils pour travailler avec des fichiers CSV : convertissez des fichiers CSV en diffรฉrents formats, manipulez les donnรฉes CSV, validez la structure CSV et traitez efficacement les fichiers CSV.",
+ "title": "Outils CSV"
+ },
+ "gif": {
+ "description": "Outils pour travailler avec des animations GIF : crรฉez des GIF transparents, extrayez des cadres GIF, ajoutez du texte au GIF, recadrez, faites pivoter, inversez les GIF et bien plus encore.",
+ "title": "Outils GIF"
+ },
+ "image-generic": {
+ "description": "Outils pour travailler avec des images : compresser, redimensionner, recadrer, convertir en JPG, faire pivoter, supprimer l'arriรจre-plan et bien plus encore.",
+ "title": "Outils d'image"
+ },
+ "json": {
+ "description": "Outils pour travailler avec des structures de donnรฉes JSONย : embellir et minimiser des objets JSON, aplatir des tableaux JSON, transformer des valeurs JSON en chaรฎnes, analyser des donnรฉes et bien plus encore",
+ "title": "Outils JSON"
+ },
+ "list": {
+ "description": "Outils pour travailler avec des listes : trier, inverser, randomiser les listes, trouver des รฉlรฉments de liste uniques et en double, modifier les sรฉparateurs d'รฉlรฉments de liste et bien plus encore.",
+ "title": "Liste des outils"
+ },
+ "number": {
+ "description": "Outils pour travailler avec des nombres : gรฉnรฉrer des sรฉquences de nombres, convertir des nombres en mots et des mots en nombres, trier, arrondir, factoriser des nombres et bien plus encore.",
+ "title": "Outils numรฉriques"
+ },
+ "pdf": {
+ "description": "Outils pour travailler avec des fichiers PDF : extraire du texte ร partir de PDF, convertir des PDF en d'autres formats, manipuler des PDF et bien plus encore.",
+ "title": "Outils PDF"
+ },
+ "png": {
+ "description": "Outils pour travailler avec des images PNG : convertissez des PNG en JPG, crรฉez des PNG transparents, modifiez les couleurs PNG, recadrez, faites pivoter, redimensionnez des PNG et bien plus encore.",
+ "title": "Outils PNG"
+ },
+ "seeAll": "Voir les {{title}}",
+ "string": {
+ "description": "Outils pour travailler avec du texte : convertissez du texte en images, recherchez et remplacez du texte, divisez du texte en fragments, joignez des lignes de texte, rรฉpรฉtez du texte et bien plus encore.",
+ "title": "Outils de texte"
+ },
+ "time": {
+ "description": "Outils pour travailler avec l'heure et la date : calculez les diffรฉrences horaires, convertissez entre les fuseaux horaires, formatez les dates, gรฉnรฉrez des sรฉquences de dates et bien plus encore.",
+ "title": "Outils de temps"
+ },
+ "try": "Essayer {{title}}",
+ "video": {
+ "description": "Outils pour travailler avec des vidรฉos : extraire des images de vidรฉos, crรฉer des GIF ร partir de vidรฉos, convertir des vidรฉos en diffรฉrents formats et bien plus encore.",
+ "title": "Outils vidรฉo"
+ },
+ "xml": {
+ "description": "Outils pour travailler avec des structures de donnรฉes XML - visualiseur, embellisseur, validateur et bien plus encore",
+ "title": "Outils XML"
+ }
+ },
+ "csv": {
+ "findIncompleteCsvRecords": {
+ "description": "Il vous suffit de tรฉlรฉcharger votre fichier CSV dans le formulaire ci-dessous et cet outil vรฉrifiera automatiquement qu'aucune ligne ou colonne ne contient de valeur manquante. Dans les options de l'outil, vous pouvez ajuster le format du fichier d'entrรฉe (spรฉcifier le dรฉlimiteur, les guillemets et les commentaires). De plus, vous pouvez activer la vรฉrification des valeurs vides, ignorer les lignes vides et limiter le nombre de messages d'erreur dans la sortie.",
+ "name": "Rechercher des enregistrements CSV incomplets",
+ "shortDescription": "Trouvez rapidement les lignes et les colonnes dans CSV auxquelles il manque des valeurs."
+ }
+ },
+ "hero": {
+ "brand": "OmniTools",
+ "description": "Boostez votre productivitรฉ avec OmniTools, la boรฎte ร outils ultime pour accรฉlรฉrer vos tรขchesย ! Accรฉdez ร des milliers d'utilitaires conviviaux pour modifier des images, du texte, des listes et des donnรฉes, directement depuis votre navigateur.",
+ "examples": {
+ "calculateNumberSum": "Calculer la somme des nombres",
+ "changeGifSpeed": "Modifier la vitesse du GIF",
+ "compressPng": "Compresser PNG",
+ "createTransparentImage": "Crรฉer une image transparente",
+ "prettifyJson": "Embellir JSON",
+ "sortList": "Trier une liste",
+ "splitPdf": "Diviser le PDF",
+ "splitText": "Diviser un texte",
+ "trimVideo": "Dรฉcouper la vidรฉo"
+ },
+ "searchPlaceholder": "Rechercher tous les outils",
+ "title": "Faites avancer les choses rapidement avec"
+ },
+ "inputFooter": {
+ "clear": "Clair",
+ "copyToClipboard": "Copier dans le presse-papiers",
+ "importFromFile": "Importer ร partir d'un fichier"
+ },
+ "list": {
+ "group": {
+ "description": "L'utilitaire de regroupement d'รฉlรฉments de liste le plus simple au monde, accessible depuis un navigateur. Saisissez votre liste et spรฉcifiez des critรจres de regroupement pour organiser les รฉlรฉments en groupes logiques. Idรฉal pour catรฉgoriser des donnรฉes, organiser des informations ou crรฉer des listes structurรฉes. Prend en charge les sรฉparateurs personnalisรฉs et diverses options de regroupement.",
+ "name": "Groupe",
+ "shortDescription": "Regrouper les รฉlรฉments de la liste par propriรฉtรฉs communes"
+ },
+ "reverse": {
+ "description": "Cette application trรจs simple, basรฉe sur un navigateur, imprime tous les รฉlรฉments d'une liste ร l'envers. Les รฉlรฉments saisis peuvent รชtre sรฉparรฉs par n'importe quel symbole et vous pouvez รฉgalement modifier le sรฉparateur des รฉlรฉments inversรฉs.",
+ "name": "Inverse",
+ "shortDescription": "Inverser rapidement une liste"
+ },
+ "sort": {
+ "description": "Il s'agit d'une application navigateur ultra-simple qui trie les รฉlรฉments d'une liste et les organise par ordre croissant ou dรฉcroissant. Vous pouvez trier les รฉlรฉments par ordre alphabรฉtique, numรฉrique ou par longueur. Vous pouvez รฉgalement supprimer les doublons et les รฉlรฉments vides, ainsi que les รฉlรฉments individuels entourรฉs d'espaces. Vous pouvez utiliser n'importe quel caractรจre sรฉparateur pour sรฉparer les รฉlรฉments de la liste d'entrรฉe ou une expression rรฉguliรจre. De plus, vous pouvez crรฉer un nouveau dรฉlimiteur pour la liste de sortie triรฉe.",
+ "name": "Trier",
+ "shortDescription": "Trier rapidement une liste"
+ }
+ },
+ "navbar": {
+ "buyMeACoffee": "Offre-moi un cafรฉ",
+ "home": "Maison",
+ "tools": "Outils"
+ },
+ "number": {
+ "generate": {
+ "description": "Calculez rapidement une liste d'entiers dans votre navigateur. Pour obtenir votre liste, indiquez simplement le premier entier, modifiez la valeur et le nombre total dans les options ci-dessous, et cet utilitaire gรฉnรฉrera le nombre d'entiers correspondant.",
+ "name": "Gรฉnรฉrer des nombres",
+ "shortDescription": "Calculez rapidement une liste d'entiers dans votre navigateur"
+ },
+ "sum": {
+ "description": "Il s'agit d'une application trรจs simple, accessible depuis un navigateur, qui additionne des nombres. Les nombres saisis peuvent รชtre sรฉparรฉs par n'importe quel symbole et vous pouvez รฉgalement modifier le sรฉparateur des nombres additionnรฉs.",
+ "name": "Somme des nombres",
+ "shortDescription": "Additionner rapidement une liste de nombres"
+ }
+ },
+ "numericInputWithUnit": {
+ "unit": "Unitรฉ"
+ },
+ "pdf": {
+ "compressPdf": {
+ "description": "Rรฉduire la taille des fichiers PDF tout en maintenant la qualitรฉ grรขce ร Ghostscript",
+ "name": "Compresser le PDF",
+ "shortDescription": "Compresser des fichiers PDF en toute sรฉcuritรฉ dans votre navigateur"
+ },
+ "mergePdf": {
+ "description": "Comment utiliser l'outil Fusionner PDF ?",
+ "name": "Fusionner des PDF",
+ "shortDescription": "Fusionner plusieurs fichiers PDF en un seul document"
+ },
+ "pdfToEpub": {
+ "description": "Transformez les documents PDF en fichiers EPUB pour une meilleure compatibilitรฉ avec les liseuses.",
+ "name": "PDF vers EPUB",
+ "shortDescription": "Convertir des fichiers PDF au format EPUB"
+ },
+ "protectPdf": {
+ "description": "Ajoutez une protection par mot de passe ร vos fichiers PDF en toute sรฉcuritรฉ dans votre navigateur",
+ "name": "Protรฉger le PDF",
+ "shortDescription": "Protรฉgez les fichiers PDF en toute sรฉcuritรฉ avec un mot de passe"
+ },
+ "splitPdf": {
+ "description": "Extraire des pages spรฉcifiques d'un fichier PDF ร l'aide de numรฉros de page ou de plages (par exemple, 1, 5-8)",
+ "name": "Diviser le PDF",
+ "shortDescription": "Extraire des pages spรฉcifiques d'un fichier PDF"
+ }
+ },
+ "resultFooter": {
+ "copy": "Copier dans le presse-papiers",
+ "download": "Tรฉlรฉcharger"
+ },
+ "string": {
+ "createPalindrome": {
+ "description": "L'utilitaire de navigateur le plus simple au monde pour crรฉer des palindromes ร partir de n'importe quel texte. Saisissez du texte et transformez-le instantanรฉment en un palindrome qui se lit de la mรชme maniรจre ร l'endroit comme ร l'envers. Idรฉal pour les jeux de mots, la crรฉation de motifs de texte symรฉtriques ou l'exploration de curiositรฉs linguistiques.",
+ "name": "Crรฉer un palindrome",
+ "shortDescription": "Crรฉez un texte qui se lit de la mรชme maniรจre ร l'avant et ร l'arriรจre"
+ },
+ "palindrome": {
+ "description": "L'utilitaire le plus simple au monde, basรฉ sur un navigateur, permet de vรฉrifier si un texte est un palindrome. Vรฉrifiez instantanรฉment si votre texte se lit de la mรชme maniรจre ร l'endroit comme ร l'envers. Idรฉal pour les jeux de mots, l'analyse linguistique ou la validation de structures de texte symรฉtriques. Prend en charge divers dรฉlimiteurs et la dรฉtection de palindromes multi-mots.",
+ "name": "Palindrome",
+ "shortDescription": "Vรฉrifiez si le texte se lit de la mรชme maniรจre ร l'avant et ร l'arriรจre"
+ },
+ "repeat": {
+ "description": "Cet outil vous permet de rรฉpรฉter un texte donnรฉ plusieurs fois avec un sรฉparateur optionnel.",
+ "name": "Rรฉpรฉter le texte",
+ "shortDescription": "Rรฉpรฉter le texte plusieurs fois"
+ },
+ "reverse": {
+ "description": "L'utilitaire d'inversion de texte le plus simple au monde, basรฉ sur un navigateur. Saisissez n'importe quel texte et inversez-le instantanรฉment, caractรจre par caractรจre. Idรฉal pour crรฉer du texte miroir, analyser des palindromes ou jouer avec les motifs de texte. Prรฉserve les espaces et les caractรจres spรฉciaux lors de l'inversion.",
+ "name": "Inverse",
+ "shortDescription": "Inverser n'importe quel texte caractรจre par caractรจre"
+ },
+ "toMorse": {
+ "description": "L'utilitaire de conversion de texte en code Morse le plus simple au monde, accessible depuis un navigateur. Chargez votre texte dans le formulaire de saisie ร gauche et obtenez instantanรฉment le code Morse dans la zone de sortie. Puissant, gratuit et rapide. Chargez du texte et obtenez le code Morse.",
+ "name": "Chaรฎne en morse",
+ "shortDescription": "Encoder rapidement du texte en morse"
+ },
+ "uppercase": {
+ "description": "L'utilitaire de conversion de texte en majuscules le plus simple au monde, accessible depuis un navigateur. Saisissez simplement votre texte et il sera automatiquement converti en majuscules. Idรฉal pour crรฉer des titres, mettre en valeur du texte ou standardiser son format. Prend en charge divers formats de texte et prรฉserve les caractรจres spรฉciaux.",
+ "name": "Majuscule",
+ "shortDescription": "Convertir le texte en lettres majuscules"
+ }
+ },
+ "toolExamples": {
+ "subtitle": "Cliquez pour essayer !",
+ "title": "{{title}} Exemples"
+ },
+ "toolFileResult": {
+ "copied": "Fichier copiรฉ",
+ "copyFailed": "รchec de la copieย : {{error}}",
+ "loading": "Chargement... Cela peut prendre un moment.",
+ "result": "Rรฉsultat"
+ },
+ "toolHeader": {
+ "seeExamples": "Voir des exemples"
+ },
+ "toolLayout": {
+ "allToolsTitle": "Tous les {{type}}"
+ },
+ "toolMultiFileResult": {
+ "copied": "Fichier copiรฉ",
+ "copyFailed": "รchec de la copieย : {{error}}",
+ "loading": "Chargement... Cela peut prendre un moment.",
+ "result": "Rรฉsultat"
+ },
+ "toolMultipleAudioInput": {
+ "inputTitle": "Saisir {{type}}",
+ "noFilesSelected": "Aucun fichier sรฉlectionnรฉ"
+ },
+ "toolMultiplePdfInput": {
+ "inputTitle": "Saisir {{type}}",
+ "noFilesSelected": "Aucun fichier sรฉlectionnรฉ"
+ },
+ "toolOptions": {
+ "title": "Options d'outils"
+ },
+ "toolTextInput": {
+ "copied": "Texte copiรฉ",
+ "copyFailed": "รchec de la copieย : {{error}}",
+ "input": "Texte d'entrรฉe",
+ "placeholder": "Entrez votre texte ici..."
+ },
+ "toolTextResult": {
+ "copied": "Texte copiรฉ",
+ "copyFailed": "รchec de la copieย : {{error}}",
+ "loading": "Chargement... Cela peut prendre un moment.",
+ "result": "Rรฉsultat"
+ }
+}
diff --git a/public/locales/fr/video.json b/public/locales/fr/video.json
new file mode 100644
index 0000000..1bbc576
--- /dev/null
+++ b/public/locales/fr/video.json
@@ -0,0 +1,113 @@
+{
+ "changeSpeed": {
+ "defaultMultiplier": "Multiplicateur par dรฉfautย : 2 signifie 2x plus rapide",
+ "description": "Modifiez la vitesse de lecture des fichiers vidรฉo. Accรฉlรฉrez ou ralentissez les vidรฉos tout en conservant la synchronisation audio. Prise en charge de divers multiplicateurs de vitesse et formats vidรฉo courants.",
+ "inputTitle": "Entrรฉe vidรฉo",
+ "newVideoSpeed": "Nouvelle vitesse vidรฉo",
+ "resultTitle": "Vidรฉo รฉditรฉe",
+ "settingSpeed": "Rรฉglage de la vitesse",
+ "shortDescription": "Modifier la vitesse de lecture vidรฉo",
+ "title": "Modifier la vitesse de la vidรฉo",
+ "toolInfo": {
+ "title": "Qu'est-ce qu'un {{title}}?"
+ }
+ },
+ "compress": {
+ "default": "Dรฉfaut",
+ "description": "Compressez vos vidรฉos en les adaptant ร diffรฉrentes rรฉsolutions (240p, 480p, 720p, etc.). Cet outil permet de rรฉduire la taille des fichiers tout en conservant une qualitรฉ acceptable. Il prend en charge les formats vidรฉo courants comme MP4, WebM et OGG.",
+ "inputTitle": "Entrรฉe vidรฉo",
+ "loadingText": "Compression vidรฉo...",
+ "lossless": "Sans perte",
+ "quality": "Qualitรฉ (CRF)",
+ "resolution": "Rรฉsolution",
+ "resultTitle": "Vidรฉo compressรฉe",
+ "shortDescription": "Compresser des vidรฉos en les mettant ร l'รฉchelle vers diffรฉrentes rรฉsolutions",
+ "title": "Compresser la vidรฉo",
+ "worst": "Pire"
+ },
+ "cropVideo": {
+ "cropCoordinates": "Coordonnรฉes de culture",
+ "croppingVideo": "Recadrage vidรฉo",
+ "description": "Recadrez la vidรฉo pour supprimer les zones indรฉsirables.",
+ "errorBeyondHeight": "La zone de recadrage s'รฉtend au-delร de la hauteur de la vidรฉo ({{height}}px)",
+ "errorBeyondWidth": "La zone de recadrage s'รฉtend au-delร de la largeur de la vidรฉo ({{width}}px)",
+ "errorCroppingVideo": "Erreur lors du recadrage de la vidรฉo. Veuillez vรฉrifier les paramรจtres et le fichier vidรฉo.",
+ "errorLoadingDimensions": "รchec du chargement des dimensions de la vidรฉo",
+ "errorNonNegativeCoordinates": "Les coordonnรฉes X et Y doivent รชtre non nรฉgatives",
+ "errorPositiveDimensions": "La largeur et la hauteur doivent รชtre positives",
+ "height": "Hauteur",
+ "inputTitle": "Entrรฉe vidรฉo",
+ "loadVideoForDimensions": "Chargez une vidรฉo pour voir les dimensions",
+ "resultTitle": "Vidรฉo recadrรฉe",
+ "shortDescription": "Recadrer la vidรฉo pour supprimer les zones indรฉsirables",
+ "title": "Recadrer la vidรฉo",
+ "toolInfo": {
+ "description": "Cet outil vous permet de recadrer des fichiers vidรฉo afin de supprimer les zones indรฉsirables. Vous pouvez spรฉcifier la zone de recadrage en dรฉfinissant les coordonnรฉes X et Y, ainsi que les dimensions de largeur et de hauteur.",
+ "title": "Recadrer la vidรฉo"
+ },
+ "videoDimensions": "Dimensions de la vidรฉo : {{width}} ร {{height}} pixels",
+ "videoInformation": "Informations vidรฉo",
+ "width": "Largeur",
+ "xCoordinate": "X (gauche)",
+ "yCoordinate": "Y (en haut)"
+ },
+ "flip": {
+ "description": "Retournez les fichiers vidรฉo horizontalement ou verticalement. Inversez les vidรฉos pour obtenir des effets spรฉciaux ou corriger les problรจmes d'orientation.",
+ "flippingVideo": "Retournement vidรฉo",
+ "horizontalLabel": "Horizontal (miroir)",
+ "inputTitle": "Entrรฉe vidรฉo",
+ "orientation": "Orientation",
+ "resultTitle": "Vidรฉo inversรฉe",
+ "shortDescription": "Retourner la vidรฉo horizontalement ou verticalement",
+ "title": "Retourner la vidรฉo",
+ "verticalLabel": "Vertical (ร l'envers)"
+ },
+ "gif": {
+ "changeSpeed": {
+ "description": "Modifiez la vitesse de lecture des animations GIF. Accรฉlรฉrez ou ralentissez les GIF tout en conservant une animation fluide.",
+ "shortDescription": "Modifier la vitesse de l'animation GIF",
+ "title": "Modifier la vitesse du GIF"
+ }
+ },
+ "loop": {
+ "description": "Crรฉez une vidรฉo en boucle en rรฉpรฉtant la vidรฉo originale plusieurs fois.",
+ "inputTitle": "Entrรฉe vidรฉo",
+ "loopingVideo": "Vidรฉo en boucle",
+ "loops": "Boucles",
+ "numberOfLoops": "Nombre de boucles",
+ "resultTitle": "Vidรฉo en boucle",
+ "shortDescription": "Crรฉer des fichiers vidรฉo en boucle",
+ "title": "Vidรฉo en boucle",
+ "toolInfo": {
+ "description": "Cet outil vous permet de crรฉer une vidรฉo en boucle en rรฉpรฉtant la vidรฉo originale plusieurs fois. Vous pouvez spรฉcifier le nombre de rรฉpรฉtitions.",
+ "title": "Qu'est-ce qu'un {{title}}?"
+ }
+ },
+ "rotate": {
+ "180Degrees": "180ยฐ (ร l'envers)",
+ "270Degrees": "270ยฐ (90ยฐ dans le sens inverse des aiguilles d'une montre)",
+ "90Degrees": "90ยฐ dans le sens des aiguilles d'une montre",
+ "description": "Faites pivoter vos fichiers vidรฉo de 90, 180 ou 270 degrรฉs. Corrigez l'orientation de vos vidรฉos ou crรฉez des effets spรฉciaux grรขce ร un contrรดle prรฉcis de la rotation.",
+ "inputTitle": "Entrรฉe vidรฉo",
+ "resultTitle": "Vidรฉo tournรฉe",
+ "rotatingVideo": "Vidรฉo rotative",
+ "rotation": "Rotation",
+ "shortDescription": "Faire pivoter la vidรฉo selon les degrรฉs spรฉcifiรฉs",
+ "title": "Faire pivoter la vidรฉo"
+ },
+ "trim": {
+ "description": "Dรฉcoupez vos fichiers vidรฉo en spรฉcifiant les heures de dรฉbut et de fin. Supprimez les sections indรฉsirables au dรฉbut ou ร la fin de vos vidรฉos.",
+ "endTime": "Fin des temps",
+ "inputTitle": "Entrรฉe vidรฉo",
+ "resultTitle": "Vidรฉo coupรฉe",
+ "shortDescription": "Coupez la vidรฉo en supprimant les sections indรฉsirables",
+ "startTime": "Heure de dรฉbut",
+ "timestamps": "Horodatages",
+ "title": "Dรฉcouper la vidรฉo"
+ },
+ "videoToGif": {
+ "description": "Convertissez des fichiers vidรฉo au format GIF animรฉ. Extrayez des plages horaires spรฉcifiques et crรฉez des images animรฉes partageables.",
+ "shortDescription": "Convertir une vidรฉo en GIF animรฉ",
+ "title": "Vidรฉo en GIF"
+ }
+}
diff --git a/public/locales/fr/xml.json b/public/locales/fr/xml.json
new file mode 100644
index 0000000..0bc1a78
--- /dev/null
+++ b/public/locales/fr/xml.json
@@ -0,0 +1,38 @@
+{
+ "xmlBeautifier": {
+ "description": "Formater XML avec une indentation et un espacement appropriรฉs.",
+ "indentation": "Indentation",
+ "inputTitle": "XML d'entrรฉe",
+ "resultTitle": "XML embelli",
+ "shortDescription": "Formater et embellir le code XML",
+ "title": "Embellisseur XML",
+ "toolInfo": {
+ "description": "Cet outil vous permet de formater les donnรฉes XML avec une indentation et un espacement appropriรฉs, les rendant plus lisibles et plus faciles ร utiliser.",
+ "title": "Embellisseur XML"
+ },
+ "useSpaces": "Utiliser les espaces",
+ "useSpacesDescription": "Indenter la sortie avec des espaces",
+ "useTabs": "Utiliser les onglets",
+ "useTabsDescription": "Indenter la sortie avec des tabulations."
+ },
+ "xmlValidator": {
+ "description": "Valider la syntaxe et la structure XML.",
+ "placeholder": "Collez ou importez du XML ici...",
+ "shortDescription": "Valider le code XML pour les erreurs",
+ "title": "Validateur XML",
+ "toolInfo": {
+ "description": "Cet outil vous permet de valider la syntaxe et la structure XML. Il vรฉrifie la bonne formation du XML et fournit des messages d'erreur dรฉtaillรฉs pour tout problรจme dรฉtectรฉ.",
+ "title": "Validateur XML"
+ }
+ },
+ "xmlViewer": {
+ "description": "Afficher et explorer la structure XML dans un format arborescent.",
+ "inputTitle": "XML d'entrรฉe",
+ "resultTitle": "Vue arborescente du XML",
+ "title": "Visionneuse XML",
+ "toolInfo": {
+ "description": "Cet outil vous permet de visualiser les donnรฉes XML dans un format d'arborescence hiรฉrarchique, ce qui facilite l'exploration et la comprรฉhension de la structure des documents XML.",
+ "title": "Visionneuse XML"
+ }
+ }
+}
diff --git a/public/locales/hi/audio.json b/public/locales/hi/audio.json
new file mode 100644
index 0000000..c279909
--- /dev/null
+++ b/public/locales/hi/audio.json
@@ -0,0 +1,83 @@
+{
+ "changeSpeed": {
+ "description": "เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคชเฅเคฒเฅเคฌเฅเค เคเคคเคฟ เคฌเคฆเคฒเฅเคเฅค",
+ "factorPlaceholder": "เคเคพเคฐเค (เคเฅเคธเฅ 0.5, 1.5, 2.0)",
+ "formatAac": "AAC",
+ "formatMp3": "MP3",
+ "formatWav": "WAV",
+ "inputTitle": "เคเคจเคชเฅเค เคเคกเคฟเคฏเฅ",
+ "newAudioSpeed": "เคจเค เคเคกเคฟเคฏเฅ เคเคคเคฟ",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "preservePitch": "เคชเคฟเค เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "resultTitle": "เคเคคเคฟ เคฌเคฆเคฒเฅ เคเค เคเคกเคฟเคฏเฅ",
+ "settingSpeed": "เคเคคเคฟ เคธเฅเค เคเคฐเคจเคพ",
+ "shortDescription": "เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเคคเคฟ เคฌเคฆเคฒเฅเค",
+ "speedDescription": "เคกเคฟเคซเคผเฅเคฒเฅเค เคเฅเคฃเค: 2 เคเคพ เค
เคฐเฅเคฅ เคนเฅ 2x เคคเฅเคเคผ",
+ "speedFactor": "เคเคคเคฟ เคเคพเคฐเค",
+ "speedOptions": "เคเคคเคฟ เคตเคฟเคเคฒเฅเคช",
+ "title": "เคเคกเคฟเคฏเฅ เคเคคเคฟ เคฌเคฆเคฒเฅเค",
+ "toolInfo": {
+ "title": "เคเฅเคฏเคพ เคนเฅ {{title}}?"
+ }
+ },
+ "extractAudio": {
+ "audioFormat": "เคเคกเคฟเคฏเฅ เคชเฅเคฐเคพเคฐเฅเคช",
+ "audioQuality": "เคเคกเคฟเคฏเฅ เคเฅเคฃเคตเคคเฅเคคเคพ",
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒ เคธเฅ เคเคกเคฟเคฏเฅ เคเฅเคฐเฅเค เคจเคฟเคเคพเคฒเฅเคเฅค",
+ "extractAllTracks": "เคธเคญเฅ เคเฅเคฐเฅเค เคจเคฟเคเคพเคฒเฅเค",
+ "extractingAudio": "เคเคกเคฟเคฏเฅ เคจเคฟเคเคพเคฒเคจเคพ",
+ "extractionOptions": "เคจเคฟเคเคพเคฒเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "formatAac": "AAC",
+ "formatMp3": "MP3",
+ "formatWav": "WAV",
+ "inputTitle": "เคเคจเคชเฅเค เคตเฅเคกเคฟเคฏเฅ",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "outputFormatDescription": "เคจเคฟเคเคพเคฒเฅ เคเคพเคจเฅ เคตเคพเคฒเฅ เคเคกเคฟเคฏเฅ เคเฅ เคฒเคฟเค เคชเฅเคฐเคพเคฐเฅเคช เคเคพ เคเคฏเคจ เคเคฐเฅเคเฅค",
+ "qualityHigh": "เคเคเฅเค",
+ "qualityLow": "เคเคฎ",
+ "qualityMedium": "เคฎเคงเฅเคฏเคฎ",
+ "resultTitle": "เคจเคฟเคเคพเคฒเคพ เคเคฏเคพ เคเคกเคฟเคฏเฅ",
+ "shortDescription": "เคตเฅเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค (เคเคฎเคชเฅ4, เคเคฎเคเคตเฅ, เคเคฆเคฟ) เคธเฅ เคเคกเคฟเคฏเฅ เคจเคฟเคเคพเคฒเฅเค เคเคเคธเฅ, เคเคฎเคชเฅ3, เคฏเคพ เคกเคฌเฅเคฒเฅเคฏเฅเคเคตเฅ เคฎเฅเคเฅค",
+ "title": "เคเคกเคฟเคฏเฅ เคจเคฟเคเคพเคฒเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคตเฅเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคธเฅ เคเคกเคฟเคฏเฅ เคเฅเคฐเฅเค เคจเคฟเคเคพเคฒเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช AAC, MP3 เคเคฐ WAV เคธเคนเคฟเคค เคตเคฟเคญเคฟเคจเฅเคจ เคเคกเคฟเคฏเฅ เคซเคผเฅเคฐเฅเคฎเฅเค เคฎเฅเค เคธเฅ เคเฅเคจ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "title": "เคเฅเคฏเคพ เคนเฅ {{title}}?"
+ }
+ },
+ "mergeAudio": {
+ "description": "เคเค เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเค เคฎเฅเค เคเฅเคกเคผเฅเคเฅค",
+ "formatAac": "AAC",
+ "formatMp3": "MP3",
+ "formatWav": "WAV",
+ "inputTitle": "เคเคจเคชเฅเค เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค",
+ "longDescription": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคเค เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เค
เคชเคฒเฅเคก เคเคฐเคจเฅ เคเฅ เคเฅเคฐเคฎ เคฎเฅเค เคเฅเคกเคผเคเคฐ เคเคจเฅเคนเฅเค เคเค เคนเฅ เคซเคผเคพเคเคฒ เคฎเฅเค เคฎเคฐเฅเค เคเคฐเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคชเฅเคกเคเคพเคธเฅเค เคธเฅเคเคฎเฅเคเค, เคฎเฅเคฏเฅเคเคผเคฟเค เคเฅเคฐเฅเค เคฏเคพ เคเคฟเคธเฅ เคญเฅ เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒ เคเฅ เคเค เคธเคพเคฅ เคเฅเคกเคผเคจเฅ เคเฅ เคฒเคฟเค เคฏเคน เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅ เคนเฅเฅค MP3, AAC เคเคฐ WAV เคธเคนเคฟเคค เคตเคฟเคญเคฟเคจเฅเคจ เคเคกเคฟเคฏเฅ เคซเคผเฅเคฐเฅเคฎเฅเค เคเฅ เคธเคชเฅเคฐเฅเค เคเคฐเคคเคพ เคนเฅเฅค",
+ "mergeMethod": "เคฎเคฐเฅเค เคตเคฟเคงเคฟ",
+ "mergeOptions": "เคฎเคฐเฅเค เคตเคฟเคเคฒเฅเคช",
+ "methodConcat": "เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเฅเคกเคผเคจเคพ",
+ "methodMix": "เคฎเคฟเคถเฅเคฐเคฃ",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "resultTitle": "เคฎเคฐเฅเค เคเคฟเคฏเคพ เคเคฏเคพ เคเคกเคฟเคฏเฅ",
+ "shortDescription": "เคเคเคพเคงเคฟเค เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเค เคฎเฅเค เคฎเคฐเฅเค เคเคฐเฅเค (MP3, AAC, WAV)เฅค",
+ "title": "เคเคกเคฟเคฏเฅ เคฎเคฐเฅเค เคเคฐเฅเค"
+ },
+ "trim": {
+ "description": "เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒ เคธเฅ เค
เคจเคพเคตเคถเฅเคฏเค เคญเคพเค เคนเคเคพเคเคเฅค",
+ "endPlaceholder": "เคธเฅเคเคเคก",
+ "endTime": "เค
เคเคคเคฟเคฎ เคธเคฎเคฏ",
+ "fadeIn": "เคซเฅเคก เคเคจ",
+ "fadeInPlaceholder": "เคธเฅเคเคเคก",
+ "fadeOut": "เคซเฅเคก เคเคเค",
+ "fadeOutPlaceholder": "เคธเฅเคเคเคก",
+ "formatMp3": "MP3",
+ "formatWav": "WAV",
+ "inputTitle": "เคเคจเคชเฅเค เคเคกเคฟเคฏเฅ",
+ "longDescription": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคถเฅเคฐเฅ เคเคฐ เคเคคเฅเคฎ เคนเฅเคจเฅ เคเคพ เคธเคฎเคฏ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเคเฅ เคเฅเคฐเคฟเคฎ เคเคฐเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคฒเคเคฌเฅ เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคธเฅ เคตเคฟเคถเคฟเคทเฅเค เคเคเคก เคจเคฟเคเคพเคฒ เคธเคเคคเฅ เคนเฅเค, เค
เคตเคพเคเคเคฟเคค เคนเคฟเคธเฅเคธเฅ เคนเคเคพ เคธเคเคคเฅ เคนเฅเค, เคฏเคพ เคเฅเคเฅ เคเฅเคฒเคฟเคช เคฌเคจเคพ เคธเคเคคเฅ เคนเฅเคเฅค MP3, AAC, เคเคฐ WAV เคธเคนเคฟเคค เคตเคฟเคญเคฟเคจเฅเคจ เคเคกเคฟเคฏเฅ เคซเคผเฅเคฐเฅเคฎเฅเค เคเฅ เคธเคชเฅเคฐเฅเค เคเคฐเคคเคพ เคนเฅเฅค เคชเฅเคกเคเคพเคธเฅเค เคเคกเคฟเคเคฟเคเค, เคฎเฅเคฏเฅเคเคผเคฟเค เคชเฅเคฐเฅเคกเคเฅเคถเคจ, เคฏเคพ เคเคฟเคธเฅ เคญเฅ เคเคกเคฟเคฏเฅ เคเคกเคฟเคเคฟเคเค เคเคผเคฐเฅเคฐเคค เคเฅ เคฒเคฟเค เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅเฅค",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "resultTitle": "เคเฅเคฐเคฟเคฎ เคเคฟเคฏเคพ เคเคฏเคพ เคเคกเคฟเคฏเฅ",
+ "shortDescription": "เคตเคฟเคถเคฟเคทเฅเค เคธเคฎเคฏ เคเคเคกเฅเค (MP3, AAC, WAV) เคเฅ เคจเคฟเคเคพเคฒเคจเฅ เคเฅ เคฒเคฟเค เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเฅเคฐเคฟเคฎ เคเคฐเฅเคเฅค",
+ "startPlaceholder": "เคธเฅเคเคเคก",
+ "startTime": "เคถเฅเคฐเฅเคเคคเฅ เคธเคฎเคฏ",
+ "title": "เคเคกเคฟเคฏเฅ เคเฅเคฐเคฟเคฎ เคเคฐเฅเค",
+ "trimOptions": "เคเฅเคฐเคฟเคฎ เคตเคฟเคเคฒเฅเคช"
+ }
+}
diff --git a/public/locales/hi/csv.json b/public/locales/hi/csv.json
new file mode 100644
index 0000000..6b559ca
--- /dev/null
+++ b/public/locales/hi/csv.json
@@ -0,0 +1,212 @@
+{
+ "changeCsvSeparator": {
+ "description": "CSV เคซเคผเคพเคเคฒเฅเค เคฎเฅเค เคธเฅเคฎเคพเคเคเค/เคตเคฟเคญเคพเคเค เคฌเคฆเคฒเฅเคเฅค เคตเคฟเคญเคฟเคจเฅเคจ CSV เคชเฅเคฐเคพเคฐเฅเคชเฅเค เคเฅเคธเฅ เค
เคฒเฅเคชเคตเคฟเคฐเคพเคฎ, เค
เคฐเฅเคงเคตเคฟเคฐเคพเคฎ, เคเฅเคฌ เคฏเคพ เคเคธเฅเคเคฎ เคตเคฟเคญเคพเคเคเฅเค เคเฅ เคฌเฅเค เคฐเฅเคชเคพเคเคคเคฐเคฃ เคเคฐเฅเคเฅค",
+ "shortDescription": "CSV เคซเคผเคพเคเคฒ เคธเฅเคฎเคพเคเคเค เคฌเคฆเคฒเฅเค",
+ "title": "CSV เคตเคฟเคญเคพเคเค เคฌเคฆเคฒเฅเค"
+ },
+ "changeSeparator": {
+ "comma": "เคเฅเคฎเคพ",
+ "commonSeparators": "เคธเคพเคฎเคพเคจเฅเคฏ เคตเคฟเคญเคพเคเค",
+ "description": "CSV เคซเคผเคพเคเคฒ เคฎเฅเค เคตเคฟเคญเคพเคเค เคตเคฐเฅเคฃ เคฌเคฆเคฒเฅเคเฅค",
+ "inputSeparator": "เคเคจเคชเฅเค เคตเคฟเคญเคพเคเค",
+ "inputSeparatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "outputSeparator": "เคเคเคเคชเฅเค เคตเคฟเคญเคพเคเค",
+ "outputSeparatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "pipe": "เคชเคพเคเคช",
+ "resultTitle": "เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค CSV",
+ "semicolon": "เคธเฅเคฎเฅเคเฅเคฒเคจ",
+ "separatorOptions": "เคตเคฟเคญเคพเคเค เคตเคฟเคเคฒเฅเคช",
+ "tab": "เคเฅเคฌ",
+ "title": "CSV เคตเคฟเคญเคพเคเค เคฌเคฆเคฒเฅเค"
+ },
+ "csvRowsToColumns": {
+ "description": "เคฏเคน เคเฅเคฒ CSV (เคเฅเคฎเคพ เคธเฅเคชเคฐเฅเคเฅเคก เคตเฅเคฒเฅเคฏเฅเคเคผ) เคซเคผเคพเคเคฒ เคเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเฅเคฒเคฎ เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเคคเคพ เคนเฅเฅค เคฏเคน เคเคจเคชเฅเค CSV เคธเฅ เคเฅเคทเฅเคคเคฟเค เคฐเฅเคเคพเคเค เคเฅ เคเค-เคเค เคเคฐเคเฅ เคจเคฟเคเคพเคฒเคคเคพ เคนเฅ, เคเคจเฅเคนเฅเค 90 เคกเคฟเคเฅเคฐเฅ เคเฅเคฎเคพเคคเคพ เคนเฅ, เคเคฐ เคเคจเฅเคนเฅเค เคเฅเคฎเคพ เคฆเฅเคตเคพเคฐเคพ เค
เคฒเค เคเคฟเค เคเค เคเค เคเฅ เคฌเคพเคฆ เคเค เคฒเคเคฌเคตเคค เคเฅเคฒเคฎ เคเฅ เคฐเฅเคช เคฎเฅเค เคเคเคเคชเฅเค เคเคฐเคคเคพ เคนเฅเฅค', longDescription: 'เคฏเคน เคเฅเคฒ CSV (เคเฅเคฎเคพ เคธเฅเคชเคฐเฅเคเฅเคก เคตเฅเคฒเฅเคฏเฅเคเคผ) เคซเคผเคพเคเคฒ เคเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเฅเคฒเคฎ เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเคคเคพ เคนเฅเฅค เคเคฆเคพเคนเคฐเคฃ เคเฅ เคฒเคฟเค, เคฏเคฆเคฟ เคเคจเคชเฅเค CSV เคกเฅเคเคพ เคฎเฅเค 6 เคชเคเคเฅเคคเคฟเคฏเคพเค เคนเฅเค, เคคเฅ เคเคเคเคชเฅเค เคฎเฅเค เคญเฅ 6 เคเฅเคฒเคฎ เคนเฅเคเคเฅ เคเคฐ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคคเคคเฅเคต เคเคชเคฐ เคธเฅ เคจเฅเคเฅ เคเฅ เคเคฐ เคตเฅเคฏเคตเคธเฅเคฅเคฟเคค เคนเฅเคเคเฅเฅค เคเค เคธเฅเคตเฅเคฏเคตเคธเฅเคฅเคฟเคค CSV เคฎเฅเค, เคชเฅเคฐเคคเฅเคฏเฅเค เคชเคเคเฅเคคเคฟ เคฎเฅเค เคฎเคพเคจเฅเค เคเฅ เคธเคเคเฅเคฏเคพ เคธเคฎเคพเคจ เคนเฅเคคเฅ เคนเฅเฅค เคนเคพเคฒเคพเคเคเคฟ, เคฏเคฆเคฟ เคชเคเคเฅเคคเคฟเคฏเฅเค เคฎเฅเค เคซเคผเฅเคฒเฅเคก เคเคพเคฏเคฌ เคนเฅเค, เคคเฅ เคชเฅเคฐเฅเคเฅเคฐเคพเคฎ เคเคจเฅเคนเฅเค เค เฅเค เคเคฐ เคธเคเคคเคพ เคนเฅ เคเคฐ เคเคช เคเคชเคฒเคฌเฅเคง เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค เคธเฅ เคเฅเคจ เคธเคเคคเฅ เคนเฅเค: เคเคพเคฏเคฌ เคกเฅเคเคพ เคเฅ เคเคพเคฒเฅ เคคเคคเฅเคตเฅเค เคธเฅ เคญเคฐเฅเค เคฏเคพ เคเคพเคฏเคฌ เคกเฅเคเคพ เคเฅ เคเคธเฅเคเคฎ เคคเคคเฅเคตเฅเค, เคเฅเคธเฅ \"missing\", \"?\", เคฏเคพ \"x\" เคธเฅ เคฌเคฆเคฒเฅเคเฅค เคฐเฅเคชเคพเคเคคเคฐเคฃ เคชเฅเคฐเคเฅเคฐเคฟเคฏเคพ เคเฅ เคฆเฅเคฐเคพเคจ, เคฏเคน เคเฅเคฒ CSV เคซเคผเคพเคเคฒ เคธเฅ เค
เคจเคพเคตเคถเฅเคฏเค เคเคพเคจเคเคพเคฐเฅ, เคเฅเคธเฅ เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค (เคฏเฅ เคฆเฅเคถเฅเคฏเคฎเคพเคจ เคเคพเคจเคเคพเคฐเฅ เคฐเคนเคฟเคค เคชเคเคเฅเคคเคฟเคฏเคพเค เคนเฅเค) เคเคฐ เคเคฟเคชเฅเคชเคฃเคฟเคฏเคพเค, เคญเฅ เคธเคพเคซเคผ เคเคฐเคคเคพ เคนเฅเฅค เคเฅเคฒ เคเฅ เคเคฟเคชเฅเคชเคฃเคฟเคฏเฅเค เคเฅ เคธเคนเฅ เคชเคนเคเคพเคจ เคเคฐเคจเฅ เคฎเฅเค เคฎเคฆเคฆ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค, เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค, เคเคช เคเคฟเคชเฅเคชเคฃเฅ เคถเฅเคฐเฅ เคเคฐเคจเฅ เคตเคพเคฒเฅ เคชเคเคเฅเคคเคฟ เคเฅ เคถเฅเคฐเฅเคเคค เคฎเฅเค เคชเฅเคฐเคคเฅเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคฏเคน เคชเฅเคฐเคคเฅเค เคเคฎเคคเฅเคฐ เคชเคฐ เคเค เคนเฅเคถ \"#\" เคฏเคพ เคกเคฌเคฒ เคธเฅเคฒเฅเคถ \"//\" เคนเฅเคคเคพ เคนเฅเฅค Csv-abulous!.",
+ "longDescription": "เคฏเคน เคเฅเคฒ CSV (เคเฅเคฎเคพ เคธเฅเคชเคฐเฅเคเฅเคก เคตเฅเคฒเฅเคฏเฅเคเคผ) เคซเคผเคพเคเคฒ เคเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเฅเคฒเคฎ เคฎเฅเค เคฌเคฆเคฒเคคเคพ เคนเฅเฅค เคเคฆเคพเคนเคฐเคฃ เคเฅ เคฒเคฟเค, เคฏเคฆเคฟ เคเคจเคชเฅเค CSV เคกเฅเคเคพ เคฎเฅเค 6 เคชเคเคเฅเคคเคฟเคฏเคพเค เคนเฅเค, เคคเฅ เคเคเคเคชเฅเค เคฎเฅเค เคญเฅ 6 เคเฅเคฒเคฎ เคนเฅเคเคเฅ เคเคฐ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคคเคคเฅเคต เคเคชเคฐ เคธเฅ เคจเฅเคเฅ เคเฅ เคเคฐ เคตเฅเคฏเคตเคธเฅเคฅเคฟเคค เคนเฅเคเคเฅเฅค เคเค เคธเฅเคตเฅเคฏเคตเคธเฅเคฅเคฟเคค CSV เคฎเฅเค, เคชเฅเคฐเคคเฅเคฏเฅเค เคชเคเคเฅเคคเคฟ เคฎเฅเค เคฎเคพเคจเฅเค เคเฅ เคธเคเคเฅเคฏเคพ เคธเคฎเคพเคจ เคนเฅเคคเฅ เคนเฅเฅค เคนเคพเคฒเคพเคเคเคฟ, เคเคฌ เคชเคเคเฅเคคเคฟเคฏเฅเค เคฎเฅเค เคซเคผเฅเคฒเฅเคก เคเคพเคฏเคฌ เคนเฅเค, เคคเฅ เคชเฅเคฐเฅเคเฅเคฐเคพเคฎ เคเคจเฅเคนเฅเค เค เฅเค เคเคฐ เคธเคเคคเคพ เคนเฅ เคเคฐ เคเคช เคเคชเคฒเคฌเฅเคง เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค เคธเฅ เคเฅเคจ เคธเคเคคเฅ เคนเฅเค: เคเคพเคฒเฅ เคคเคคเฅเคตเฅเค เคธเฅ เคเคพเคฏเคฌ เคกเฅเคเคพ เคญเคฐเฅเค เคฏเคพ เคเคธเฅเคเคฎ เคคเคคเฅเคตเฅเค เคธเฅ เคเคพเคฏเคฌ เคกเฅเคเคพ เคเฅ เคฌเคฆเคฒเฅเค, เคเฅเคธเฅ",
+ "shortDescription": "CSV เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคธเฅเคคเคเคญเฅเค เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค.",
+ "title": "CSV เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคธเฅเคคเคเคญเฅเค เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค"
+ },
+ "csvToJson": {
+ "arrayFormat": "เคธเคฐเคฃเฅ เคชเฅเคฐเคพเคฐเฅเคช",
+ "columnSeparator": "เคธเฅเคคเคเคญ เคตเคฟเคญเคพเคเค (เคเคฆเคพเคนเคฐเคฃเคพเคฐเฅเคฅ, , ; \\t)",
+ "commentSymbol": "เคเคฟเคชเฅเคชเคฃเฅ เคชเฅเคฐเคคเฅเค (เคเคฆเคพเคนเคฐเคฃเคพเคฐเฅเคฅ, #)",
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "CSV เคกเฅเคเคพ เคเฅ JSON เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "dynamicTypes": "เคเคคเคฟเคถเฅเคฒ เคชเฅเคฐเคเคพเคฐ",
+ "dynamicTypesDescription": "เคธเคเคเฅเคฏเคพเคเค เคเคฐ เคฌเฅเคฒเคฟเคฏเคจ เคเฅ เคธเฅเคตเคเคพเคฒเคฟเคค เคฐเฅเคช เคธเฅ เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค",
+ "errorParsing": "CSV เคชเคพเคฐเฅเคธ เคเคฐเคจเฅ เคฎเฅเค เคคเฅเคฐเฅเคเคฟ: {{error}}",
+ "fieldQuote": "เคซเคผเฅเคฒเฅเคก เคเคฆเฅเคงเคฐเคฃ (เคเคฆเคพเคนเคฐเคฃเคพเคฐเฅเคฅ, \")",
+ "firstRowAsHeaders": "เคชเคนเคฒเฅ เคชเคเคเฅเคคเคฟ เคถเฅเคฐเฅเคทเค เคเฅ เคฐเฅเคช เคฎเฅเค",
+ "includeHeaders": "เคถเฅเคฐเฅเคทเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "inputCsvFormat": "เคเคจเคชเฅเค CSV เคชเฅเคฐเคพเคฐเฅเคช",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "objectFormat": "เคเคฌเฅเคเฅเคเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "resultTitle": "JSON เคชเคฐเคฟเคฃเคพเคฎ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "CSV เคกเฅเคเคพ เคเฅ JSON เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค.",
+ "skipEmptyLines": "เคเคพเคฒเฅ เคฒเคพเคเคจเฅเค เคเฅเคกเคผเฅเค",
+ "skipEmptyLinesDescription": "เคเคจเคชเฅเค CSV เคฎเฅเค เคฐเคฟเคเฅเคค เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เค
เคจเคฆเฅเคเคพ เคเคฐเฅเค",
+ "title": "CSV เคธเฅ JSON",
+ "useHeaders": "เคนเฅเคกเคฐ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
+ "useHeadersDescription": "เคชเคนเคฒเฅ เคชเคเคเฅเคคเคฟ เคเฅ เคธเฅเคคเคเคญ เคถเฅเคฐเฅเคทเค เคเฅ เคฐเฅเคช เคฎเฅเค เคฎเคพเคจเฅเค"
+ },
+ "csvToTsv": {
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "CSV เคซเคผเคพเคเคฒ เคเฅ TSV เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "inputSeparator": "เคเคจเคชเฅเค เคตเคฟเคญเคพเคเค",
+ "inputSeparatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "longDescription": "เคฏเคน เคเฅเคฒ เคเฅเคฎเคพ เคธเฅเคชเคฐเฅเคเฅเคก เคตเฅเคฒเฅเคฏเฅเคเคผ (CSV) เคกเฅเคเคพ เคเฅ เคเฅเคฌ เคธเฅเคชเคฐเฅเคเฅเคก เคตเฅเคฒเฅเคฏเฅเคเคผ (TSV) เคกเฅเคเคพ เคฎเฅเค เคฌเคฆเคฒ เคฆเฅเคคเคพ เคนเฅเฅค CSV เคเคฐ TSV เคฆเฅเคจเฅเค เคนเฅ เคธเคพเคฐเคฃเฅเคฌเคฆเฅเคง เคกเฅเคเคพ เคธเคเคเฅเคฐเคนเฅเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคฒเฅเคเคชเฅเคฐเคฟเคฏ เคซเคผเคพเคเคฒ เคธเฅเคตเคฐเฅเคช เคนเฅเค, เคฒเฅเคเคฟเคจ เคตเฅ เคฎเคพเคจเฅเค เคเฅ เค
เคฒเค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เค
เคฒเค-เค
เคฒเค เคกเคฟเคฒเฅเคฎเฅเคเคฐ เคเคพ เคเคชเคฏเฅเค เคเคฐเคคเฅ เคนเฅเค - CSV เคเฅเคฎเคพ (",
+ "preserveHeaders": "เคถเฅเคฐเฅเคทเค เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "resultTitle": "TSV เคชเคฐเคฟเคฃเคพเคฎ",
+ "shortDescription": "CSV เคกเฅเคเคพ เคเฅ TSV เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค.",
+ "title": "CSV เคธเฅ TSV"
+ },
+ "csvToXml": {
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "CSV เคกเฅเคเคพ เคเฅ XML เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "firstRowAsHeaders": "เคชเคนเคฒเฅ เคชเคเคเฅเคคเคฟ เคถเฅเคฐเฅเคทเค เคเฅ เคฐเฅเคช เคฎเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "resultTitle": "XML เคชเคฐเคฟเคฃเคพเคฎ",
+ "rootElement": "เคฎเฅเคฒ เคคเคคเฅเคต",
+ "rootPlaceholder": "เคคเคคเฅเคต เคจเคพเคฎ",
+ "rowElement": "เคชเคเคเฅเคคเคฟ เคคเคคเฅเคต",
+ "rowPlaceholder": "เคคเคคเฅเคต เคจเคพเคฎ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "CSV เคกเฅเคเคพ เคเฅ XML เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค.",
+ "title": "CSV เคธเฅ XML"
+ },
+ "csvToYaml": {
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "CSV เคกเฅเคเคพ เคเฅ YAML เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "firstRowAsHeaders": "เคชเคนเคฒเฅ เคชเคเคเฅเคคเคฟ เคถเฅเคฐเฅเคทเค เคเฅ เคฐเฅเคช เคฎเฅเค",
+ "includeHeaders": "เคถเฅเคฐเฅเคทเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "indentSize": "เคเคเคกเฅเคเค เคเคเคพเคฐ",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "longDescription": "เคฏเคน เคเฅเคฒ CSV (เคเฅเคฎเคพ เคธเฅเคชเคฐเฅเคเฅเคก เคตเฅเคฒเฅเคฏเฅเคเคผ) เคกเฅเคเคพ เคเฅ YAML (เคฏเฅเค เค
เคจเคฆเคฐ เคฎเคพเคฐเฅเคเค
เคช เคฒเฅเคเคเฅเคตเฅเค) เคกเฅเคเคพ เคฎเฅเค เคฌเคฆเคฒ เคฆเฅเคคเคพ เคนเฅเฅค CSV เคเค เคธเคฐเคฒ, เคธเคพเคฐเคฃเฅเคฌเคฆเฅเคง เคซเคผเฅเคฐเฅเคฎเฅเค เคนเฅ เคเคฟเคธเคเคพ เคเคชเคฏเฅเค เคชเคเคเฅเคคเคฟเคฏเฅเค เคเคฐ เคธเฅเคคเคเคญเฅเค เคตเคพเคฒเฅ เคฎเฅเคเฅเคฐเคฟเคเฅเคธ เคเฅเคธเฅ เคกเฅเคเคพ เคชเฅเคฐเคเคพเคฐเฅเค เคเฅ เคฆเคฐเฅเคถเคพเคจเฅ เคเฅ เคฒเคฟเค เคเคฟเคฏเคพ เคเคพเคคเคพ เคนเฅเฅค เคฆเฅเคธเคฐเฅ เคเคฐ, YAML เคเค เค
เคงเคฟเค เคเคจเฅเคจเคค เคซเคผเฅเคฐเฅเคฎเฅเค (เคตเคพเคธเฅเคคเคต เคฎเฅเค JSON เคเคพ เคเค เคธเฅเคชเคฐเคธเฅเค) เคนเฅ, เคเฅ เคเฅเคฐเคฎเคพเคเคเคจ เคเฅ เคฒเคฟเค เค
เคงเคฟเค เคฎเคพเคจเคต-เคชเค เคจเฅเคฏ เคกเฅเคเคพ เคฌเคจเคพเคคเคพ เคนเฅ, เคเคฐ เคฏเคน เคธเฅเคเคฟเคฏเฅเค, เคถเคฌเฅเคฆเคเฅเคถเฅเค เคเคฐ เคจเฅเคธเฅเคเฅเคก เคเคฌเฅเคเฅเคเฅเคเฅเคธ เคเคพ เคธเคฎเคฐเฅเคฅเคจ เคเคฐเคคเคพ เคนเฅเฅค เคฏเคน เคชเฅเคฐเฅเคเฅเคฐเคพเคฎ เคตเคฟเคญเคฟเคจเฅเคจ เคเคจเคชเฅเค CSV เคซเคผเฅเคฐเฅเคฎเฅเค เคเคพ เคธเคฎเคฐเฅเคฅเคจ เคเคฐเคคเคพ เคนเฅ - เคเคจเคชเฅเค เคกเฅเคเคพ เคเฅเคฎเคพ เคธเฅเคชเคฐเฅเคเฅเคก (เคกเคฟเคซเคผเฅเคฒเฅเค), เคธเฅเคฎเฅเคเฅเคฒเคจ เคธเฅเคชเคฐเฅเคเฅเคก, เคชเคพเคเคช เคธเฅเคชเคฐเฅเคเฅเคก เคนเฅ เคธเคเคคเคพ เคนเฅ, เคฏเคพ เคเคฟเคธเฅ เค
เคจเฅเคฏ เคชเฅเคฐเฅ เคคเคฐเคน เคธเฅ เค
เคฒเค เคกเคฟเคฒเฅเคฎเฅเคเคฐ เคเคพ เคเคชเคฏเฅเค เคเคฐ เคธเคเคคเคพ เคนเฅเฅค เคเคช เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค เค
เคชเคจเฅ เคกเฅเคเคพ เคฆเฅเคตเคพเคฐเคพ เคเคชเคฏเฅเค เคเคฟเค เคเคพเคจเฅ เคตเคพเคฒเฅ เคธเคเฅเค เคกเคฟเคฒเฅเคฎเฅเคเคฐ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคเคธเฅ เคชเฅเคฐเคเคพเคฐ, เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค, เคเคช CSV เคซเคผเฅเคฒเฅเคก เคเฅ เคฐเฅเคช เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเค เคเคฟเค เคเคพเคจเฅ เคตเคพเคฒเฅ เคเคฆเฅเคงเคฐเคฃ เคเคฟเคนเฅเคจ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค (เคกเคฟเคซเคผเฅเคฒเฅเค เคฐเฅเคช เคธเฅ เคเค เคกเคฌเคฒ-เคเฅเค เคชเฅเคฐเคคเฅเค)เฅค เคเคช เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค เคเคฟเคชเฅเคชเคฃเฅ เคเคฟเคนเฅเคจ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเคเฅ เคเคฟเคชเฅเคชเคฃเคฟเคฏเฅเค เคธเฅ เคถเฅเคฐเฅ เคนเฅเคจเฅ เคตเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคญเฅ เคเฅเคกเคผ เคธเคเคคเฅ เคนเฅเคเฅค เคเคธเคธเฅ เคเคช เค
เคจเคพเคตเคถเฅเคฏเค เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเฅเคกเคผเคเคฐ เค
เคชเคจเฅ เคกเฅเคเคพ เคเฅ เคธเคพเคซเคผ เคฐเค เคธเคเคคเฅ เคนเฅเคเฅค CSV เคเฅ YAML เคฎเฅเค เคฌเคฆเคฒเคจเฅ เคเฅ เคฆเฅ เคคเคฐเฅเคเฅ เคนเฅเคเฅค เคชเคนเคฒเฅ เคตเคฟเคงเคฟ เคชเฅเคฐเคคเฅเคฏเฅเค CSV เคชเคเคเฅเคคเคฟ เคเฅ เคเค YAML เคธเฅเคเฅ เคฎเฅเค เคฌเคฆเคฒ เคฆเฅเคคเฅ เคนเฅเฅค เคฆเฅเคธเคฐเฅ เคตเคฟเคงเคฟ เคชเคนเคฒเฅ CSV เคชเคเคเฅเคคเคฟ เคธเฅ เคนเฅเคกเคฐ เคจเคฟเคเคพเคฒเคคเฅ เคนเฅ เคเคฐ เคเคจ เคนเฅเคกเคฐ เคชเคฐ เคเคงเคพเคฐเคฟเคค เคเฅเคเคเคฟเคฏเฅเค เคตเคพเคฒเฅ YAML เคเคฌเฅเคเฅเคเฅเค เคฌเคจเคพเคคเฅ เคนเฅเฅค เคเคช YAML เคธเคเคฐเคเคจเคพเคเค เคเฅ เคเคเคกเฅเคเค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ เคเฅ เคธเคเคเฅเคฏเคพ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเคเฅ เคเคเคเคชเฅเค YAML เคชเฅเคฐเคพเคฐเฅเคช เคเฅ เคญเฅ เค
เคจเฅเคเฅเคฒเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคฏเคฆเคฟ เคเคชเคเฅ เคฐเคฟเคตเคฐเฅเคธ เคฐเฅเคชเคพเคเคคเคฐเคฃ, เคฏเคพเคจเฅ YAML เคเฅ CSV เคฎเฅเค เคฌเคฆเคฒเคจเฅ เคเฅ เคเคตเคถเฅเคฏเคเคคเคพ เคนเฅ, เคคเฅ เคเคช เคนเคฎเคพเคฐเฅ YAML เคเฅ CSV เคฎเฅเค เคฌเคฆเคฒเคจเฅ เคตเคพเคฒเฅ เคเฅเคฒ เคเคพ เคเคชเคฏเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค Csv-abulous!",
+ "resultTitle": "YAML เคชเคฐเคฟเคฃเคพเคฎ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคเคฟเคธเฅ CSV เคซเคผเคพเคเคฒ เคเฅ เคถเฅเคเฅเคฐเคคเคพ เคธเฅ YAML เคซเคผเคพเคเคฒ เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเคเฅค",
+ "sizePlaceholder": "เคเคเคพเคฐ",
+ "title": "CSV เคธเฅ YAML"
+ },
+ "findIncompleteCsvRecords": {
+ "checkingOptions": "เคตเคฟเคเคฒเฅเคชเฅเค เคเฅ เคเคพเคเค",
+ "commentCharacterDescription": "เคเคฟเคชเฅเคชเคฃเฅ เคชเคเคเฅเคคเคฟ เคเฅ เคถเฅเคฐเฅเคเคค เคฆเคฐเฅเคถเคพเคจเฅ เคตเคพเคฒเคพ เคตเคฐเฅเคฃ เคฆเคฐเฅเค เคเคฐเฅเคเฅค เคเคธ เคเคฟเคนเฅเคจ เคธเฅ เคถเฅเคฐเฅ เคนเฅเคจเฅ เคตเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคเฅเคกเคผ เคฆเฅ เคเคพเคเคเคเฅเฅค",
+ "csvInputOptions": "CSV เคเคจเคชเฅเค เคตเคฟเคเคฒเฅเคช",
+ "csvSeparatorDescription": "CSV เคเคจเคชเฅเค เคซเคผเคพเคเคฒ เคฎเฅเค เคเฅเคฒเคฎ เคเฅ เคธเฅเคฎเคพเคเคเคฟเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคชเฅเคฐเคฏเฅเคเฅเคค เคตเคฐเฅเคฃ เคฆเคฐเฅเค เคเคฐเฅเค.",
+ "deleteLinesWithNoData": "เคฌเคฟเคจเคพ เคกเฅเคเคพ เคตเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคนเคเคพเคเค",
+ "deleteLinesWithNoDataDescription": "CSV เคเคจเคชเฅเค เคซเคผเคพเคเคฒ เคธเฅ เคฐเคฟเคเฅเคค เคชเคเคเฅเคคเคฟเคฏเคพเค เคนเคเคพเคเค.",
+ "description": "เคฌเคธ เคจเฅเคเฅ เคซเฅเคฐเฅเคฎ เคฎเฅเค เค
เคชเคจเฅ เคธเฅเคเคธเคตเฅ เคซเคผเคพเคเคฒ เค
เคชเคฒเฅเคก เคเคฐเฅเค เคเคฐ เคฏเคน เคเฅเคฒ เคธเฅเคตเคเคพเคฒเคฟเคค เคฐเฅเคช เคธเฅ เคเคพเคเค เคเคฐเฅเคเคพ เคเคฟ เคเฅเคฏเคพ เคเฅเค เคชเคเคเฅเคคเคฟ เคฏเคพ เคธเฅเคคเคเคญ เคฎเฅเคฒเฅเคฏ เคจเคนเฅเค เคเฅ เคฐเคนเฅ เคนเฅเคเฅค เคเฅเคฒ เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค, เคเคช เคเคจเคชเฅเค เคซเคผเคพเคเคฒ เคชเฅเคฐเคพเคฐเฅเคช เคเฅ เคธเคฎเคพเคฏเฅเคเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเค (เคตเคฟเคญเคพเคเค, เคเคฆเฅเคงเคฐเคฃ เคตเคฐเฅเคฃ, เคเคฐ เคเคฟเคชเฅเคชเคฃเฅ เคตเคฐเฅเคฃ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเฅเค)เฅค เคเคธเคเฅ เค
เคคเคฟเคฐเคฟเคเฅเคค, เคเคช เคเคพเคฒเฅ เคฎเฅเคฒเฅเคฏเฅเค เคเฅ เคเคพเคเค เคธเคเฅเคทเคฎ เคเคฐ เคธเคเคคเฅ เคนเฅเค, เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเฅเคกเคผ เคธเคเคคเฅ เคนเฅเค, เคเคฐ เคเคเคเคชเฅเค เคฎเฅเค เคคเฅเคฐเฅเคเคฟ เคธเคเคฆเฅเคถเฅเค เคเฅ เคธเคเคเฅเคฏเคพ เคชเคฐ เคธเฅเคฎเคพ เคจเคฟเคฐเฅเคงเคพเคฐเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "findEmptyValues": "เคฐเคฟเคเฅเคค เคฎเคพเคจ เคเฅเคเฅเค",
+ "findEmptyValuesDescription": "เคฐเคฟเคเฅเคค CSV เคซเคผเฅเคฒเฅเคก เคเฅ เคฌเคพเคฐเฅ เคฎเฅเค เคธเคเคฆเฅเคถ เคชเฅเคฐเคฆเคฐเฅเคถเคฟเคค เคเคฐเฅเค (เคฏเฅ เคฐเคฟเคเฅเคค เคซเคผเฅเคฒเฅเคก เคจเคนเฅเค เคนเฅเค, เคฌเคฒเฅเคเคฟ เคตเฅ เคซเคผเฅเคฒเฅเคก เคนเฅเค เคเคฟเคจเคฎเฅเค เคเฅเค เคญเฅ เคจเคนเฅเค เคนเฅ)เฅค",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "limitNumberOfMessages": "เคธเคเคฆเฅเคถเฅเค เคเฅ เคธเคเคเฅเคฏเคพ เคธเฅเคฎเคฟเคค เคเคฐเฅเค",
+ "messageLimitDescription": "เคเคเคเคชเฅเค เคฎเฅเค เคธเคเคฆเฅเคถเฅเค เคเฅ เคธเคเคเฅเคฏเคพ เคเฅ เคธเฅเคฎเคพ เคจเคฟเคฐเฅเคงเคพเคฐเคฟเคค เคเคฐเฅเค.",
+ "quoteCharacterDescription": "CSV เคเคจเคชเฅเค เคซเคผเฅเคฒเฅเคก เคเฅ เคเคฆเฅเคงเฅเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคชเฅเคฐเคฏเฅเคเฅเคค เคเคฆเฅเคงเคฐเคฃ เคตเคฐเฅเคฃ เคฆเคฐเฅเค เคเคฐเฅเค.",
+ "resultTitle": "เคธเฅเคเคธเคตเฅ เคธเฅเคฅเคฟเคคเคฟ",
+ "shortDescription": "เคธเฅเคเคธเคตเฅ เคฎเฅเค เคเคฒเฅเคฆเฅ เคธเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคเคฐ เคธเฅเคคเคเคญ เคเฅเคเฅเค เคเฅ เคฎเฅเคฒเฅเคฏ เคเฅ เคฐเคนเฅ เคนเฅเคเฅค",
+ "title": "เค
เคงเฅเคฐเฅ เคธเฅเคเคธเคตเฅ เคฐเคฟเคเฅเคฐเฅเคก เคเฅเคเฅเค",
+ "toolInfo": {
+ "title": "{{title}} เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "findIncompleteRecords": {
+ "checkEmptyValues": "เคเคพเคฒเฅ เคฎเฅเคฒเฅเคฏ เคเคพเคเคเฅเค",
+ "description": "CSV เคซเคผเคพเคเคฒ เคฎเฅเค เค
เคงเฅเคฐเฅ เคฐเคฟเคเฅเคฐเฅเคก เคเฅเคเฅเคเฅค",
+ "errorLimit": "เคคเฅเคฐเฅเคเคฟ เคธเฅเคฎเคพ",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "limitPlaceholder": "เคธเฅเคฎเคพ",
+ "resultTitle": "เค
เคงเฅเคฐเฅ เคฐเคฟเคเฅเคฐเฅเคก",
+ "searchOptions": "เคเฅเค เคตเคฟเคเคฒเฅเคช",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "skipEmptyLines": "เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคเฅเคกเคผเฅเค",
+ "title": "เค
เคงเฅเคฐเฅ CSV เคฐเคฟเคเฅเคฐเฅเคก เคเฅเคเฅเค"
+ },
+ "insertColumns": {
+ "columnNames": "เคธเฅเคคเคเคญ เคจเคพเคฎ",
+ "defaultValues": "เคกเคฟเคซเคผเฅเคฒเฅเค เคฎเฅเคฒเฅเคฏ",
+ "description": "CSV เคซเคผเคพเคเคฒ เคฎเฅเค เคจเค เคธเฅเคคเคเคญ เคกเคพเคฒเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "insertPosition": "เคกเคพเคฒเคจเฅ เคเฅ เคธเฅเคฅเคฟเคคเคฟ",
+ "insertionOptions": "เคกเคพเคฒเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "namesPlaceholder": "เคจเคพเคฎ (เคเฅเคฎเคพ เคธเฅ เค
เคฒเค)",
+ "positionPlaceholder": "เคธเฅเคฅเคฟเคคเคฟ",
+ "resultTitle": "เคธเคเคถเฅเคงเคฟเคค CSV",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "title": "CSV เคธเฅเคคเคเคญ เคกเคพเคฒเฅเค",
+ "valuesPlaceholder": "เคฎเฅเคฒเฅเคฏ (เคเฅเคฎเคพ เคธเฅ เค
เคฒเค)"
+ },
+ "insertCsvColumns": {
+ "appendColumns": "เคเฅเคฒเคฎ เคเฅเคกเคผเฅเค",
+ "commentCharacterDescription": "เคเคฟเคชเฅเคชเคฃเฅ เคชเคเคเฅเคคเคฟ เคเฅ เคถเฅเคฐเฅเคเคค เคฆเคฐเฅเคถเคพเคจเฅ เคตเคพเคฒเคพ เคตเคฐเฅเคฃ เคฆเคฐเฅเค เคเคฐเฅเคเฅค เคเคธ เคเคฟเคนเฅเคจ เคธเฅ เคถเฅเคฐเฅ เคนเฅเคจเฅ เคตเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคเฅเคกเคผ เคฆเฅ เคเคพเคเคเคเฅเฅค",
+ "csvOptions": "CSV เคตเคฟเคเคฒเฅเคช",
+ "csvSeparator": "CSV เคตเคฟเคญเคพเคเค",
+ "csvToInsert": "เคธเคฎเฅเคฎเคฟเคฒเคฟเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค CSV",
+ "csvToInsertDescription": "CSV เคฎเฅเค เคกเคพเคฒเคจเฅ เคเฅ เคฒเคฟเค เคเค เคฏเคพ เคเค เคธเฅ เคเคผเฅเคฏเคพเคฆเคพ เคเฅเคฒเคฎ เคกเคพเคฒเฅเคเฅค เคเฅเคฒเคฎ เคเฅ เคธเฅเคฎเคพเคเคเคฟเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคธเฅเคคเฅเคฎเคพเคฒ เคเคฟเคฏเคพ เคเคฏเคพ เคตเคฐเฅเคฃ CSV เคเคจเคชเฅเค เคซเคผเคพเคเคฒ เคฎเฅเค เคฎเฅเคเฅเคฆ เคตเคฐเฅเคฃ เคเฅ เคธเคฎเคพเคจ เคนเฅเคจเคพ เคเคพเคนเคฟเคเฅค Ps: เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เค
เคจเคฆเฅเคเคพ เคเคฐ เคฆเคฟเคฏเคพ เคเคพเคเคเคพเฅค",
+ "customFillDescription": "เคฏเคฆเคฟ เคเคจเคชเฅเค CSV เคซเคผเคพเคเคฒ เค
เคชเฅเคฐเฅเคฃ เคนเฅ (เคฎเคพเคจ เคเคพเคฏเคฌ เคนเฅเค), เคคเฅ เคเค เคธเฅเคตเฅเคฏเคตเคธเฅเคฅเคฟเคค CSV เคฌเคจเคพเคจเฅ เคเฅ เคฒเคฟเค เคฐเคฟเคเฅเคฐเฅเคก เคฎเฅเค เคฐเคฟเคเฅเคค เคซเคผเฅเคฒเฅเคก เคฏเคพ เคเคธเฅเคเคฎ เคชเฅเคฐเคคเฅเค เคเฅเคกเคผเฅเค?",
+ "customFillValueDescription": "เคฐเคฟเคเฅเคค เคซเคผเฅเคฒเฅเคก เคญเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคธ เคเคธเฅเคเคฎ เคฎเคพเคจ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเคเฅค (เคฏเคน เคเฅเคตเคฒ เคเคชเคฐ เคฆเคฟเค เคเค \"เคเคธเฅเคเคฎ เคฎเคพเคจ\" เคฎเฅเคก เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคคเคพ เคนเฅเฅค)",
+ "customPosition": "เคเคธเฅเคเคฎ เคธเฅเคฅเคฟเคคเคฟ",
+ "customPositionOptionsDescription": "CSV เคซเคผเคพเคเคฒ เคฎเฅเค เคเฅเคฒเคฎ เคธเคฎเฅเคฎเคฟเคฒเคฟเคค เคเคฐเคจเฅ เคเฅ เคตเคฟเคงเคฟ เคเคพ เคเคฏเคจ เคเคฐเฅเค.",
+ "description": "เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคธเฅเคฅเคพเคจเฅเค เคชเคฐ CSV เคกเฅเคเคพ เคฎเฅเค เคจเค เคเฅเคฒเคฎ เคเฅเคกเคผเฅเค.",
+ "fillWithCustomValues": "เคธเฅเคฎเคพ เคถเฅเคฒเฅเค เคฎเฅเคฒเฅเคฏเฅเค เคธเฅ เคญเคฐเฅเค",
+ "fillWithEmptyValues": "เคฐเคฟเคเฅเคค เคฎเคพเคจเฅเค เคธเฅ เคญเคฐเฅเค",
+ "headerName": "เคนเฅเคกเคฐ เคเคพ เคจเคพเคฎ",
+ "headerNameDescription": "เคเคธ เคเฅเคฒเคฎ เคเคพ เคถเฅเคฐเฅเคทเคฒเฅเค เคเคฟเคธเคเฅ เคฌเคพเคฆ เคเคช เคเฅเคฒเคฎ เคธเคฎเฅเคฎเคฟเคฒเคฟเคค เคเคฐเคจเคพ เคเคพเคนเคคเฅ เคนเฅเค.",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "insertingPositionDescription": "เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเฅเค เคเคฟ CSV เคซเคผเคพเคเคฒ เคฎเฅเค เคเฅเคฒเคฎ เคเคนเคพเค เคธเคฎเฅเคฎเคฟเคฒเคฟเคค เคเคฐเคจเคพ เคนเฅ.",
+ "position": "เคชเคฆ",
+ "positionOptions": "เคธเฅเคฅเคฟเคคเคฟ เคตเคฟเคเคฒเฅเคช",
+ "prependColumns": "เคเฅเคฒเคฎ เคเฅเคกเคผเฅเค",
+ "quoteCharDescription": "CSV เคเคจเคชเฅเค เคซเคผเฅเคฒเฅเคก เคเฅ เคเคฆเฅเคงเฅเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคชเฅเคฐเคฏเฅเคเฅเคค เคเคฆเฅเคงเคฐเคฃ เคตเคฐเฅเคฃ เคฆเคฐเฅเค เคเคฐเฅเค.",
+ "resultTitle": "เคเคเคเคชเฅเค CSV",
+ "rowNumberDescription": "เคเคธ เคเฅเคฒเคฎ เคเฅ เคธเคเคเฅเคฏเคพ เคเคฟเคธเคเฅ เคฌเคพเคฆ เคเคช เคเฅเคฒเคฎ เคธเคฎเฅเคฎเคฟเคฒเคฟเคค เคเคฐเคจเคพ เคเคพเคนเคคเฅ เคนเฅเค.",
+ "separatorDescription": "CSV เคเคจเคชเฅเค เคซเคผเคพเคเคฒ เคฎเฅเค เคเฅเคฒเคฎ เคเฅ เคธเฅเคฎเคพเคเคเคฟเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคชเฅเคฐเคฏเฅเคเฅเคค เคตเคฐเฅเคฃ เคฆเคฐเฅเค เคเคฐเฅเค.",
+ "shortDescription": "CSV เคซเคผเคพเคเคฒ เคฎเฅเค เคเคนเฅเค เคญเฅ เคเค เคฏเคพ เค
เคงเคฟเค เคจเค เคเฅเคฒเคฎ เคถเฅเคเฅเคฐเคคเคพ เคธเฅ เคกเคพเคฒเฅเค.",
+ "title": "CSV เคเฅเคฒเคฎ เคกเคพเคฒเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ CSV เคกเฅเคเคพ เคฎเฅเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคธเฅเคฅเคพเคจเฅเค เคชเคฐ เคจเค เคเฅเคฒเคฎ เคกเคพเคฒเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคนเฅเคกเคฐ เคจเคพเคฎเฅเค เคฏเคพ เคเฅเคฒเคฎ เคธเคเคเฅเคฏเคพเคเค เคเฅ เคเคงเคพเคฐ เคชเคฐ เคเคธเฅเคเคฎ เคธเฅเคฅเคพเคจเฅเค เคชเคฐ เคเฅเคฒเคฎ เคเฅเคกเคผ, เคเฅเคกเคผ เคฏเคพ เคกเคพเคฒ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "title": "CSV เคเฅเคฒเคฎ เคกเคพเคฒเฅเค"
+ }
+ },
+ "rowsToColumns": {
+ "description": "CSV เคกเฅเคเคพ เคเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคธเฅ เคธเฅเคคเคเคญเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "includeHeaders": "เคถเฅเคฐเฅเคทเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "resultTitle": "เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค CSV",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "title": "CSV เคชเคเคเฅเคคเคฟเคฏเคพเค เคธเฅ เคธเฅเคคเคเคญ",
+ "transformationOptions": "เคชเคฐเคฟเคตเคฐเฅเคคเคจ เคตเคฟเคเคฒเฅเคช",
+ "transposeData": "เคกเฅเคเคพ เคเฅเคฐเคพเคเคธเคชเฅเคเคผ เคเคฐเฅเค"
+ },
+ "swapColumns": {
+ "description": "CSV เคซเคผเคพเคเคฒ เคฎเฅเค เคธเฅเคคเคเคญเฅเค เคเฅ เคธเฅเคฅเคฟเคคเคฟ เคฌเคฆเคฒเฅเคเฅค",
+ "firstColumn": "เคชเคนเคฒเคพ เคธเฅเคคเคเคญ",
+ "firstColumnPlaceholder": "เคธเฅเคคเคเคญ เคธเคเคเฅเคฏเคพ",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "resultTitle": "เคธเคเคถเฅเคงเคฟเคค CSV",
+ "secondColumn": "เคฆเฅเคธเคฐเคพ เคธเฅเคคเคเคญ",
+ "secondColumnPlaceholder": "เคธเฅเคคเคเคญ เคธเคเคเฅเคฏเคพ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "swapOptions": "เคฌเคฆเคฒเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "title": "CSV เคธเฅเคคเคเคญ เคฌเคฆเคฒเฅเค"
+ },
+ "swapCsvColumns": {
+ "description": "เคฌเคธ เคจเฅเคเฅ เคฆเคฟเค เคเค เคซเคผเฅเคฐเฅเคฎ เคฎเฅเค เค
เคชเคจเฅ CSV เคซเคผเคพเคเคฒ เค
เคชเคฒเฅเคก เคเคฐเฅเค, เคธเฅเคตเฅเคช เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเคฎ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเฅเค, เคเคฐ เคเฅเคฒ เคธเฅเคตเคเคพเคฒเคฟเคค เคฐเฅเคช เคธเฅ เคเคเคเคชเฅเค เคซเคผเคพเคเคฒ เคฎเฅเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเฅเคฒเคฎ เคเฅ เคธเฅเคฅเคฟเคคเคฟ เคฌเคฆเคฒ เคฆเฅเคเคพเฅค เคเฅเคฒ เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค, เคเคช เคเคจ เคเฅเคฒเคฎ เคเฅ เคธเฅเคฅเคฟเคคเคฟ เคฏเคพ เคจเคพเคฎ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค เคเคฟเคจเฅเคนเฅเค เคเคช เคธเฅเคตเฅเคช เคเคฐเคจเคพ เคเคพเคนเคคเฅ เคนเฅเค, เคธเคพเคฅ เคนเฅ เค
เคงเฅเคฐเฅ เคกเฅเคเคพ เคเฅ เค เฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค เคเคฐ เคตเฅเคเคฒเฅเคชเคฟเค เคฐเฅเคช เคธเฅ เคเคพเคฒเฅ เคฐเคฟเคเฅเคฐเฅเคก เคเคฐ เคเคฟเคชเฅเคชเคฃเฅ เคเคฟเค เคเค เคฐเคฟเคเฅเคฐเฅเคก เคนเคเคพ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "longDescription": "เคฏเคน เคเฅเคฒ CSV เคกเฅเคเคพ เคเฅ เคเฅเคฒเคฎ เคเฅ เคธเฅเคฅเคฟเคคเคฟ เคฌเคฆเคฒเคเคฐ เคเคธเฅ เคชเฅเคจเคฐเฅเคตเฅเคฏเคตเคธเฅเคฅเคฟเคค เคเคฐเคคเคพ เคนเฅเฅค เคเฅเคฒเคฎ เคฌเคฆเคฒเคจเฅ เคธเฅ เค
เคเฅเคธเคฐ เคเคธเฅเคคเฅเคฎเคพเคฒ เคนเฅเคจเฅ เคตเคพเคฒเฅ เคกเฅเคเคพ เคเฅ เคเค เคธเคพเคฅ เคฏเคพ เคเคเฅ เคฐเคเคเคฐ CSV เคซเคผเคพเคเคฒ เคเฅ เคชเค เคจเฅเคฏเคคเคพ เคฌเคขเคผเคพเค เคเคพ เคธเคเคคเฅ เคนเฅ, เคเคฟเคธเคธเฅ เคกเฅเคเคพ เคเฅ เคคเฅเคฒเคจเคพ เคเคฐ เคธเคเคชเคพเคฆเคจ เคเคธเคพเคจ เคนเฅ เคเคพเคคเคพ เคนเฅเฅค เคเคฆเคพเคนเคฐเคฃ เคเฅ เคฒเคฟเค, เคเคช เคชเคนเคฒเฅ เคเฅเคฒเคฎ เคเฅ เคเคเคฟเคฐเฅ เคเฅเคฒเคฎ เคธเฅ เคฏเคพ เคฆเฅเคธเคฐเฅ เคเฅเคฒเคฎ เคเฅ เคคเฅเคธเคฐเฅ เคเฅเคฒเคฎ เคธเฅ เคฌเคฆเคฒ เคธเคเคคเฅ เคนเฅเคเฅค เคเฅเคฒเคฎ เคเฅ เคธเฅเคฅเคฟเคคเคฟ เคเฅ เคเคงเคพเคฐ เคชเคฐ เคเคจเฅเคนเฅเค เคฌเคฆเคฒเคจเฅ เคเฅ เคฒเคฟเค, เคเฅเคจเฅเค",
+ "shortDescription": "CSV เคเฅเคฒเคฎ เคชเฅเคจเคเคเฅเคฐเคฎเคฟเคค เคเคฐเฅเค.",
+ "title": "CSV เคเฅเคฒเคฎ เคธเฅเคตเฅเคช เคเคฐเฅเค"
+ },
+ "transposeCsv": {
+ "description": "CSV เคกเฅเคเคพ เคเฅ เคเฅเคฐเคพเคเคธเคชเฅเคเคผ เคเคฐเฅเค (เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคธเฅเคคเคเคญเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค)เฅค",
+ "includeHeaders": "เคถเฅเคฐเฅเคทเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค CSV",
+ "longDescription": "เคฏเคน เคเฅเคฒ เคเฅเคฎเคพ เคธเฅเคชเคฐเฅเคเฅเคก เคตเฅเคฒเฅเคฏเฅเคเคผ (CSV) เคเฅ เคเฅเคฐเคพเคเคธเคชเฅเคเคผ เคเคฐเคคเคพ เคนเฅเฅค เคฏเคน CSV เคเฅ เคกเฅเคเคพ เคเฅ เคเค เคฎเฅเคเฅเคฐเคฟเคเฅเคธ เคเฅ เคคเคฐเคน เคฎเคพเคจเคคเคพ เคนเฅ เคเคฐ เคธเคญเฅ เคคเคคเฅเคตเฅเค เคเฅ เคฎเฅเคเฅเคฏ เคตเคฟเคเคฐเฅเคฃ เคชเคฐ เคชเคฒเค เคฆเฅเคคเคพ เคนเฅเฅค เคเคเคเคชเฅเค เคฎเฅเค เคเคจเคชเฅเค เคเฅ เคธเคฎเคพเคจ เคนเฅ CSV เคกเฅเคเคพ เคนเฅเคคเคพ เคนเฅ, เคฒเฅเคเคฟเคจ เค
เคฌ เคธเคญเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคเฅเคฒเคฎ เคฎเฅเค เคฌเคฆเคฒ เคเค เคนเฅเค, เคเคฐ เคธเคญเฅ เคเฅเคฒเคฎ เคชเคเคเฅเคคเคฟเคฏเคพเค เคฎเฅเค เคฌเคฆเคฒ เคเค เคนเฅเคเฅค เคเฅเคฐเคพเคเคธเคชเฅเคเคผเคฟเคถเคจ เคเฅ เคฌเคพเคฆ, CSV เคซเคผเคพเคเคฒ เคเฅ เคเคฏเคพเคฎ เคตเคฟเคชเคฐเฅเคค เคนเฅเคเคเฅเฅค เคเคฆเคพเคนเคฐเคฃ เคเฅ เคฒเคฟเค, เคฏเคฆเคฟ เคเคจเคชเฅเค เคซเคผเคพเคเคฒ เคฎเฅเค 4 เคเฅเคฒเคฎ เคเคฐ 3 เคชเคเคเฅเคคเคฟเคฏเคพเค เคนเฅเค, เคคเฅ เคเคเคเคชเฅเค เคซเคผเคพเคเคฒ เคฎเฅเค 3 เคเฅเคฒเคฎ เคเคฐ 4 เคชเคเคเฅเคคเคฟเคฏเคพเค เคนเฅเคเคเฅเฅค เคฐเฅเคชเคพเคเคคเคฐเคฃ เคเฅ เคฆเฅเคฐเคพเคจ, เคชเฅเคฐเฅเคเฅเคฐเคพเคฎ เค
เคจเคพเคตเคถเฅเคฏเค เคชเคเคเฅเคคเคฟเคฏเฅเค เคธเฅ เคกเฅเคเคพ เคญเฅ เคธเคพเคซเคผ เคเคฐเคคเคพ เคนเฅ เคเคฐ เค
เคงเฅเคฐเฅ เคกเฅเคเคพ เคเฅ เคธเคนเฅ เคเคฐเคคเคพ เคนเฅเฅค เคตเคฟเคถเฅเคท เคฐเฅเคช เคธเฅ, เคฏเคน เคเฅเคฒ เคเคฟเคธเฅ เคตเคฟเคถเคฟเคทเฅเค เคตเคฐเฅเคฃ เคธเฅ เคถเฅเคฐเฅ เคนเฅเคจเฅ เคตเคพเคฒเฅ เคธเคญเฅ เคฐเคฟเคเฅเคค เคฐเคฟเคเฅเคฐเฅเคก เคเคฐ เคเคฟเคชเฅเคชเคฃเคฟเคฏเฅเค เคเฅ เคธเฅเคตเคเคพเคฒเคฟเคค เคฐเฅเคช เคธเฅ เคนเคเคพ เคฆเฅเคคเคพ เคนเฅ, เคเคฟเคธเฅ เคเคช เคตเคฟเคเคฒเฅเคช เคฎเฅเค เคธเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคเคธเคเฅ เค
เคคเคฟเคฐเคฟเคเฅเคค, เคเคธเฅ เคฎเคพเคฎเคฒเฅเค เคฎเฅเค เคเคนเคพเค CSV เคกเฅเคเคพ เคฆเฅเคทเคฟเคค เคฏเคพ เคเฅ เคเคฏเคพ เคนเฅ, เคเคชเคฏเฅเคเคฟเคคเคพ เคซเคผเคพเคเคฒ เคเฅ เคฐเคฟเคเฅเคค เคซเคผเฅเคฒเฅเคก เคฏเคพ เคเคธเฅเคเคฎ เคซเคผเฅเคฒเฅเคก เคธเฅ เคญเคฐ เคฆเฅเคคเฅ เคนเฅ เคเคฟเคจเฅเคนเฅเค เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฟเคฏเคพ เคเคพ เคธเคเคคเคพ เคนเฅเฅค Csv-abulous!",
+ "resultTitle": "เคเฅเคฐเคพเคเคธเคชเฅเคเคผ เคเคฟเคฏเคพ เคเคฏเคพ CSV",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "CSV เคซเคผเคพเคเคฒ เคเฅ เคถเฅเคเฅเคฐเคคเคพ เคธเฅ เคเฅเคฐเคพเคเคธเคชเฅเคเคผ เคเคฐเฅเค.",
+ "title": "CSV เคเฅเคฐเคพเคเคธเคชเฅเคเคผ เคเคฐเฅเค",
+ "transposeOptions": "เคเฅเคฐเคพเคเคธเคชเฅเคเคผ เคตเคฟเคเคฒเฅเคช"
+ }
+}
diff --git a/public/locales/hi/image.json b/public/locales/hi/image.json
new file mode 100644
index 0000000..67122dd
--- /dev/null
+++ b/public/locales/hi/image.json
@@ -0,0 +1,224 @@
+{
+ "changeColors": {
+ "description": "เคฆเฅเคจเคฟเคฏเคพ",
+ "shortDescription": "เคเคฟเคธเฅ เคเคตเคฟ เคฎเฅเค เคฐเคเคเฅเค เคเฅ เคถเฅเคเฅเคฐเคคเคพ เคธเฅ เคฌเคฆเคฒเฅเค",
+ "title": "เคเคตเคฟ เคฎเฅเค เคฐเคเค เคฌเคฆเคฒเฅเค"
+ },
+ "changeOpacity": {
+ "description": "เค
เคชเคจเฅ เคเคตเคฟเคฏเฅเค เคเฅ เคชเคพเคฐเคฆเคฐเฅเคถเคฟเคคเคพ เคเฅ เคเคธเคพเคจเฅ เคธเฅ เคธเคฎเคพเคฏเฅเคเคฟเคค เคเคฐเฅเคเฅค เคฌเคธ เค
เคชเคจเฅ เคเคตเคฟ เค
เคชเคฒเฅเคก เคเคฐเฅเค, เคธเฅเคฒเคพเคเคกเคฐ เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคตเคพเคเคเคฟเคค เค
เคชเคพเคฐเคฆเคฐเฅเคถเคฟเคคเคพ เคธเฅเคคเคฐ 0 (เคชเฅเคฐเฅ เคคเคฐเคน เคธเฅ เคชเคพเคฐเคฆเคฐเฅเคถเฅ) เคเคฐ 1 (เคชเฅเคฐเฅ เคคเคฐเคน เคธเฅ เค
เคชเคพเคฐเคฆเคฐเฅเคถเฅ) เคเฅ เคฌเฅเค เคธเฅเค เคเคฐเฅเค, เคเคฐ เคธเคเคถเฅเคงเคฟเคค เคเคตเคฟ เคกเคพเคเคจเคฒเฅเคก เคเคฐเฅเคเฅค",
+ "shortDescription": "เคเคตเคฟเคฏเฅเค เคเฅ เคชเคพเคฐเคฆเคฐเฅเคถเคฟเคคเคพ เคธเคฎเคพเคฏเฅเคเคฟเคค เคเคฐเฅเค",
+ "title": "เคเคตเคฟ เค
เคชเคพเคฐเคฆเคฐเฅเคถเคฟเคคเคพ เคฌเคฆเคฒเฅเค"
+ },
+ "compress": {
+ "compressionOptions": "เคธเคเคชเฅเคกเคผเคจ เคตเคฟเคเคฒเฅเคช",
+ "description": "เคเคตเคฟ เคซเคผเคพเคเคฒ เคเคเคพเคฐ เคเคฎ เคเคฐเฅเคเฅค",
+ "formatJpeg": "JPEG",
+ "formatPng": "PNG",
+ "formatWebp": "WebP",
+ "imageQuality": "เคเคตเคฟ เคเฅเคฃเคตเคคเฅเคคเคพ",
+ "inputTitle": "เคเคจเคชเฅเค เคเคตเคฟ",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "progressiveJpeg": "เคชเฅเคฐเคเคคเคฟเคถเฅเคฒ JPEG",
+ "qualityPlaceholder": "เคเฅเคฃเคตเคคเฅเคคเคพ (1-100)",
+ "removeMetadata": "เคฎเฅเคเคพเคกเฅเคเคพ เคนเคเคพเคเค",
+ "resultTitle": "เคธเคเคชเฅเคกเคผเคฟเคค เคเคตเคฟ",
+ "shortDescription": "เคเคเคฟเคค เคเฅเคฃเคตเคคเฅเคคเคพ เคฌเคจเคพเค เคฐเคเคคเฅ เคนเฅเค เคซเคผเคพเคเคฒ เคเคเคพเคฐ เคเฅ เคเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคตเคฟเคฏเฅเค เคเฅ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเคเฅค",
+ "title": "เคเคตเคฟ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค"
+ },
+ "compressPng": {
+ "description": "เคฏเคน เคเค เคเคธเคพ เคชเฅเคฐเฅเคเฅเคฐเคพเคฎ เคนเฅ เคเฅ PNG เคเคฟเคคเฅเคฐเฅเค เคเฅ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเคคเคพ เคนเฅเฅค เคเฅเคธเฅ เคนเฅ เคเคช เค
เคชเคจเฅ PNG เคคเคธเฅเคตเฅเคฐ เคเฅ เคเคจเคชเฅเค เคเฅเคทเฅเคคเฅเคฐ เคฎเฅเค เคชเฅเคธเฅเค เคเคฐเฅเคเคเฅ, เคชเฅเคฐเฅเคเฅเคฐเคพเคฎ เคเคธเฅ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐ เคฆเฅเคเคพ เคเคฐ เคชเคฐเคฟเคฃเคพเคฎ เคเคเคเคชเฅเค เคเฅเคทเฅเคคเฅเคฐ เคฎเฅเค เคฆเคฟเคเคพเคเคเคพเฅค เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค, เคเคช เคธเคเคชเฅเคกเคผเคจ เคธเฅเคคเคฐ เคเฅ เคธเคฎเคพเคฏเฅเคเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเค, เคธเคพเคฅ เคนเฅ เคชเฅเคฐเคพเคจเฅ เคเคฐ เคจเค เคคเคธเฅเคตเฅเคฐ เคซเคผเคพเคเคฒ เคเคพ เคเคเคพเคฐ เคญเฅ เคฆเฅเค เคธเคเคคเฅ เคนเฅเคเฅค",
+ "shortDescription": "PNG เคเฅ เคถเฅเคเฅเคฐเคคเคพ เคธเฅ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค",
+ "title": "png เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค"
+ },
+ "convert": {
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "เคเคตเคฟ เคเฅ เคเค เคชเฅเคฐเคพเคฐเฅเคช เคธเฅ เคฆเฅเคธเคฐเฅ เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "formatBmp": "BMP",
+ "formatGif": "GIF",
+ "formatJpeg": "JPEG",
+ "formatPng": "PNG",
+ "formatTiff": "TIFF",
+ "formatWebp": "WebP",
+ "imageQuality": "เคเคตเคฟ เคเฅเคฃเคตเคคเฅเคคเคพ",
+ "inputTitle": "เคเคจเคชเฅเค เคเคตเคฟ",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "preserveTransparency": "เคชเคพเคฐเคฆเคฐเฅเคถเคฟเคคเคพ เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "qualityPlaceholder": "เคเฅเคฃเคตเคคเฅเคคเคพ (1-100)",
+ "resultTitle": "เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคตเคฟ",
+ "title": "เคเคตเคฟ เคชเฅเคฐเคพเคฐเฅเคช เคฌเคฆเคฒเฅเค"
+ },
+ "convertJgpToPng": {
+ "description": "เค
เคชเคจเฅ JPG เคเคฎเฅเค เคเฅ เคเคเคชเค PNG เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค เคฌเคธ เค
เคชเคจเฅ PNG เคเคฎเฅเค เคเฅ เคฌเคพเคเค เคเคฐ เคฆเคฟเค เคเค เคเคกเคฟเคเคฐ เคฎเฅเค เคเคฎเฅเคชเฅเคฐเฅเค เคเคฐเฅเคเฅค",
+ "shortDescription": "เค
เคชเคจเฅ JPG เคเคตเคฟเคฏเฅเค เคเฅ เคถเฅเคเฅเคฐเคคเคพ เคธเฅ PNG เคฎเฅเค เคฌเคฆเคฒเฅเค",
+ "title": "JPG เคเฅ PNG เคฎเฅเค เคฌเคฆเคฒเฅเค"
+ },
+ "convertToJpg": {
+ "description": "เค
เคจเฅเคเฅเคฒเคจ เคฏเฅเคเฅเคฏ เคเฅเคฃเคตเคคเฅเคคเคพ เคเคฐ เคชเฅเคทเฅเค เคญเฅเคฎเคฟ เคฐเคเค เคธเฅเคเคฟเคเคเฅเคธ เคเฅ เคธเคพเคฅ เคตเคฟเคญเคฟเคจเฅเคจ เคเคตเคฟ เคชเฅเคฐเคพเคฐเฅเคชเฅเค (PNG, GIF, TIF, PSD, SVG, WEBP, HEIC, RAW) เคเฅ JPG เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเคเฅค",
+ "shortDescription": "เคเฅเคฃเคตเคคเฅเคคเคพ เคจเคฟเคฏเคเคคเฅเคฐเคฃ เคเฅ เคธเคพเคฅ เคเคตเคฟเคฏเฅเค เคเฅ JPG เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค",
+ "title": "เคเคตเคฟเคฏเฅเค เคเฅ JPG เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค"
+ },
+ "createTransparent": {
+ "description": "เคฆเฅเคจเคฟเคฏเคพ",
+ "shortDescription": "เคเคฟเคธเฅ เคเคตเคฟ เคเฅ เคถเฅเคเฅเคฐเคคเคพ เคธเฅ เคชเคพเคฐเคฆเคฐเฅเคถเฅ เคฌเคจเคพเคเค",
+ "title": "เคชเคพเคฐเคฆเคฐเฅเคถเฅ PNG เคฌเคจเคพเคเค"
+ },
+ "crop": {
+ "aspectRatio": "เคเคเคพเคฐ เค
เคจเฅเคชเคพเคค",
+ "cropArea": "เคเฅเคฐเฅเคช เคเฅเคทเฅเคคเฅเคฐ",
+ "cropMethod": "เคเฅเคฐเฅเคช เคตเคฟเคงเคฟ",
+ "cropOptions": "เคเฅเคฐเฅเคช เคตเคฟเคเคฒเฅเคช",
+ "description": "เคเคตเคฟ เคธเฅ เค
เคจเคพเคตเคถเฅเคฏเค เคญเคพเค เคนเคเคพเคเคเฅค",
+ "height": "เคเคเคเคพเค",
+ "heightPlaceholder": "เคชเคฟเคเฅเคธเฅเคฒ",
+ "inputTitle": "เคเคจเคชเฅเค เคเคตเคฟ",
+ "methodAspectRatio": "เคเคเคพเคฐ เค
เคจเฅเคชเคพเคค",
+ "methodManual": "เคฎเฅเคจเฅเค
เคฒ",
+ "ratio16x9": "16:9",
+ "ratio1x1": "1:1",
+ "ratio3x2": "3:2",
+ "ratio4x3": "4:3",
+ "resultTitle": "เคเฅเคฐเฅเคช เคเฅ เคเค เคเคตเคฟ",
+ "shortDescription": "เคเคตเคฟเคฏเฅเค เคเฅ เคถเฅเคเฅเคฐเคคเคพ เคธเฅ เคเคพเคเฅเค.",
+ "title": "เคเคตเคฟ เคเฅเคฐเฅเคช เคเคฐเฅเค",
+ "width": "เคเฅเคกเคผเคพเค",
+ "widthPlaceholder": "เคชเคฟเคเฅเคธเฅเคฒ",
+ "xPlaceholder": "เคชเคฟเคเฅเคธเฅเคฒ",
+ "xPosition": "X เคธเฅเคฅเคฟเคคเคฟ",
+ "yPlaceholder": "เคชเคฟเคเฅเคธเฅเคฒ",
+ "yPosition": "Y เคธเฅเคฅเคฟเคคเคฟ"
+ },
+ "editor": {
+ "description": "เคเฅเคฐเฅเคช เคเคฐเคจเฅ, เคเฅเคฎเคพเคจเฅ, เคเคจเฅเคเฅเค เคเคฐเคจเฅ, เคฐเคเค เคธเคฎเคพเคฏเฅเคเคฟเคค เคเคฐเคจเฅ เคเคฐ เคตเฅเคเคฐเคฎเคพเคฐเฅเค เคเฅเคกเคผเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคเคฐเคฃเฅเค เคเฅ เคธเคพเคฅ เคเคจเฅเคจเคค เคเคตเคฟ เคธเคเคชเคพเคฆเคเฅค เค
เคชเคจเฅ เคฌเฅเคฐเคพเคเคเคผเคฐ เคฎเฅเค เคธเฅเคงเฅ เคชเฅเคถเฅเคตเคฐ-เคธเฅเคคเคฐเฅเคฏ เคเคชเคเคฐเคฃเฅเค เคธเฅ เค
เคชเคจเฅ เคเคตเคฟเคฏเฅเค เคเฅ เคธเคเคชเคพเคฆเคฟเคค เคเคฐเฅเคเฅค",
+ "shortDescription": "เคเคจเฅเคจเคค เคเฅเคฒ เคเคฐ เคธเฅเคตเคฟเคงเคพเคเค เคเฅ เคธเคพเคฅ เคเคตเคฟเคฏเฅเค เคเฅ เคธเคเคชเคพเคฆเคฟเคค เคเคฐเฅเค",
+ "title": "เคเคตเคฟ เคธเคเคชเคพเคฆเค"
+ },
+ "filter": {
+ "description": "เคเคตเคฟ เคชเคฐ เคตเคฟเคญเคฟเคจเฅเคจ เคซเคผเคฟเคฒเฅเคเคฐ เคฒเคพเคเฅ เคเคฐเฅเคเฅค",
+ "filterIntensity": "เคซเคผเคฟเคฒเฅเคเคฐ เคคเฅเคตเฅเคฐเคคเคพ",
+ "filterOptions": "เคซเคผเคฟเคฒเฅเคเคฐ เคตเคฟเคเคฒเฅเคช",
+ "filterType": "เคซเคผเคฟเคฒเฅเคเคฐ เคชเฅเคฐเคเคพเคฐ",
+ "inputTitle": "เคเคจเคชเฅเค เคเคตเคฟ",
+ "intensityPlaceholder": "เคฎเคพเคจ (0-100)",
+ "resultTitle": "เคซเคผเคฟเคฒเฅเคเคฐ เคเฅ เคเค เคเคตเคฟ",
+ "title": "เคเคตเคฟ เคซเคผเคฟเคฒเฅเคเคฐ",
+ "typeBlur": "เคงเฅเคเคงเคฒเคพ",
+ "typeBrightness": "เคเคฎเค",
+ "typeContrast": "เคเคเคเฅเคฐเคพเคธเฅเค",
+ "typeGrayscale": "เคเฅเคฐเฅเคธเฅเคเฅเคฒ",
+ "typeInvert": "เคเคฒเคเคพ",
+ "typeSaturation": "เคธเคเคคเฅเคชเฅเคคเคฟ",
+ "typeSepia": "เคธเฅเคชเคฟเคฏเคพ",
+ "typeSharpen": "เคคเฅเคเคผ"
+ },
+ "flip": {
+ "description": "เคเคตเคฟ เคเฅ เคเฅเคทเฅเคคเคฟเค เคฏเคพ เคฒเคเคฌเคตเคค เคฐเฅเคช เคธเฅ เคซเฅเคฒเคฟเคช เคเคฐเฅเคเฅค",
+ "directionBoth": "เคฆเฅเคจเฅเค",
+ "directionHorizontal": "เคเฅเคทเฅเคคเคฟเค",
+ "directionVertical": "เคฒเคเคฌเคตเคค",
+ "flipDirection": "เคซเฅเคฒเคฟเคช เคฆเคฟเคถเคพ",
+ "flipOptions": "เคซเฅเคฒเคฟเคช เคตเคฟเคเคฒเฅเคช",
+ "inputTitle": "เคเคจเคชเฅเค เคเคตเคฟ",
+ "resultTitle": "เคซเฅเคฒเคฟเคช เคเฅ เคเค เคเคตเคฟ",
+ "title": "เคเคตเคฟ เคซเฅเคฒเคฟเคช เคเคฐเฅเค"
+ },
+ "imageToText": {
+ "description": "เคเคชเฅเคเคฟเคเคฒ เคเฅเคฐเฅเคเฅเคเคฐ เคฐเคฟเคเฅเคเฅเคจเคฟเคถเคจ (OCR) เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคเคตเคฟเคฏเฅเค (JPG, PNG) เคธเฅ เคชเคพเค เคจเคฟเคเคพเคฒเฅเคเฅค",
+ "shortDescription": "OCR เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคเคตเคฟเคฏเฅเค เคธเฅ เคชเคพเค เคจเคฟเคเคพเคฒเฅเคเฅค",
+ "title": "เคเคตเคฟ เคธเฅ เคชเคพเค (เคเคธเฅเคเคฐ)"
+ },
+ "qrCode": {
+ "description": "เคตเคฟเคญเคฟเคจเฅเคจ เคกเฅเคเคพ เคชเฅเคฐเคเคพเคฐเฅเค เคเฅ เคฒเคฟเค เคเฅเคฏเฅเคเคฐ เคเฅเคก เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค: เคฏเฅเคเคฐเคเคฒ, เคเฅเคเฅเคธเฅเค, เคเคฎเฅเคฒ, เคซเฅเคจ, เคเคธเคเคฎเคเคธ, เคตเคพเคเคซเคพเค, เคตเฅเคเคพเคฐเฅเคก, เคเคฐ เค
เคงเคฟเคเฅค",
+ "shortDescription": "เคตเคฟเคญเคฟเคจเฅเคจ เคกเฅเคเคพ เคชเฅเคฐเคพเคฐเฅเคชเฅเค เคเฅ เคฒเคฟเค เค
เคจเฅเคเฅเคฒเคฟเคค เคเฅเคฏเฅเคเคฐ เคเฅเคก เคฌเคจเคพเคเคเฅค",
+ "title": "เคเฅเคฏเฅเคเคฐ เคเฅเคก เคเคจเคฐเฅเคเคฐ"
+ },
+ "removeBackground": {
+ "description": "เคฆเฅเคจเคฟเคฏเคพ",
+ "shortDescription": "เคเคตเคฟเคฏเฅเค เคธเฅ เคชเฅเคทเฅเค เคญเฅเคฎเคฟ เคธเฅเคตเคเคพเคฒเคฟเคค เคฐเฅเคช เคธเฅ เคนเคเคพเคเค",
+ "title": "เคเคตเคฟ เคธเฅ เคชเฅเคทเฅเค เคญเฅเคฎเคฟ เคนเคเคพเคเค"
+ },
+ "resize": {
+ "description": "เคเคตเคฟ เคเคพ เคเคเคพเคฐ เคฌเคฆเคฒเฅเคเฅค",
+ "dimensionType": "เคเคฏเคพเคฎ เคชเฅเคฐเคเคพเคฐ",
+ "height": "เคเคเคเคพเค",
+ "heightDescription": "เคเคเคเคพเค (เคชเคฟเคเฅเคธเฅเคฒ เคฎเฅเค)",
+ "heightPlaceholder": "เคฎเคพเคจ",
+ "inputTitle": "เคเคจเคชเฅเค เคเคตเคฟ",
+ "interpolationMethod": "เคเคเคเคฐเคชเฅเคฒเฅเคถเคจ เคตเคฟเคงเคฟ",
+ "maintainAspectRatio": "เคเคเคพเคฐ เค
เคจเฅเคชเคพเคค เคฌเคจเคพเค เคฐเคเฅเค",
+ "maintainAspectRatioDescription": "เคเคตเคฟ เคเคพ เคฎเฅเคฒ เคชเคนเคฒเฅ เค
เคจเฅเคชเคพเคค เคฌเคจเคพเค เคฐเคเฅเค.",
+ "methodAspectRatio": "เคเคเคพเคฐ เค
เคจเฅเคชเคพเคค",
+ "methodBicubic": "เคฆเฅเคตเคฟเคเคจ",
+ "methodBilinear": "เคฆเฅเคตเคฟเคฐเฅเคเฅเคฏ",
+ "methodNearest": "เคจเคฟเคเคเคคเคฎ",
+ "methodPercentage": "เคชเฅเคฐเคคเคฟเคถเคค",
+ "methodPixels": "เคชเคฟเคเฅเคธเฅเคฒ",
+ "percentage": "เคเฅ PERCENTAGE",
+ "percentageDescription": "เคฎเฅเคฒ เคเคเคพเคฐ เคเคพ เคชเฅเคฐเคคเคฟเคถเคค (เคเคฆเคพเคนเคฐเคฃ เคเฅ เคฒเคฟเค, เคเคงเฅ เคเคเคพเคฐ เคเฅ เคฒเคฟเค 50, เคฆเฅเคนเคฐเฅ เคเคเคพเคฐ เคเฅ เคฒเคฟเค 200)",
+ "resizeByPercentage": "เคชเฅเคฐเคคเคฟเคถเคค เคเฅ เค
เคจเฅเคธเคพเคฐ เคเคเคพเคฐ เคฌเคฆเคฒเฅเค",
+ "resizeByPercentageDescription": "เคฎเฅเคฒ เคเคเคพเคฐ เคเคพ เคชเฅเคฐเคคเคฟเคถเคค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเคเฅ เคเคเคพเคฐ เคฌเคฆเคฒเฅเคเฅค",
+ "resizeByPixels": "เคชเคฟเคเฅเคธเฅเคฒ เคฆเฅเคตเคพเคฐเคพ เคเคเคพเคฐ เคฌเคฆเคฒเฅเค",
+ "resizeByPixelsDescription": "เคชเคฟเคเฅเคธเฅเคฒ เคฎเฅเค เคเคฏเคพเคฎ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเคเฅ เคเคเคพเคฐ เคฌเคฆเคฒเฅเค.",
+ "resizeMethod": "เคเคเคพเคฐ เคฌเคฆเคฒเคจเฅ เคเฅ เคตเคฟเคงเคฟ",
+ "resizeOptions": "เคเคเคพเคฐ เคฌเคฆเคฒเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "resultTitle": "เคเคเคพเคฐ เคฌเคฆเคฒเฅ เคเค เคเคตเคฟ",
+ "setHeight": "เคเคเคเคพเค เคจเคฟเคฐเฅเคงเคพเคฐเคฟเคค เคเคฐเฅเค",
+ "setHeightDescription": "เคชเคฟเคเฅเคธเฅเคฒ เคฎเฅเค เคเคเคเคพเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเฅเค เคเคฐ เคชเคนเคฒเฅ เค
เคจเฅเคชเคพเคค เคเฅ เคเคงเคพเคฐ เคชเคฐ เคเฅเคกเคผเคพเค เคเฅ เคเคฃเคจเคพ เคเคฐเฅเคเฅค",
+ "setWidth": "เคเฅเคกเคผเคพเค เคธเฅเค เคเคฐเฅเค",
+ "setWidthDescription": "เคชเคฟเคเฅเคธเฅเคฒ เคฎเฅเค เคเฅเคกเคผเคพเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเฅเค เคเคฐ เคชเคนเคฒเฅ เค
เคจเฅเคชเคพเคค เคเฅ เคเคงเคพเคฐ เคชเคฐ เคเคเคเคพเค เคเฅ เคเคฃเคจเคพ เคเคฐเฅเคเฅค",
+ "shortDescription": "เคเคตเคฟเคฏเฅเค เคเคพ เคเคเคพเคฐ เคเคธเคพเคจเฅ เคธเฅ เคฌเคฆเคฒเฅเค.",
+ "title": "เคเคตเคฟ เคเคเคพเคฐ เคฌเคฆเคฒเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ JPG, PNG, SVG, เคฏเคพ GIF เคเคฎเฅเค เคเคพ เคเคเคพเคฐ เคฌเคฆเคฒเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคชเคฟเคเฅเคธเฅเคฒ เคฏเคพ เคชเฅเคฐเคคเคฟเคถเคค เคฎเฅเค เคเคฏเคพเคฎ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเคเฅ เคเคเคพเคฐ เคฌเคฆเคฒ เคธเคเคคเฅ เคนเฅเค, เคธเคพเคฅ เคนเฅ เคฎเฅเคฒ เคชเคนเคฒเฅ เค
เคจเฅเคชเคพเคค เคฌเคจเคพเค เคฐเคเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช เคญเฅ เคเคชเคฒเคฌเฅเคง เคนเฅเคเฅค",
+ "title": "เคเคตเคฟ เคเคเคพเคฐ เคฌเคฆเคฒเฅเค"
+ },
+ "width": "เคเฅเคกเคผเคพเค",
+ "widthDescription": "เคเฅเคกเคผเคพเค (เคชเคฟเคเฅเคธเฅเคฒ เคฎเฅเค)",
+ "widthPlaceholder": "เคฎเคพเคจ"
+ },
+ "rotate": {
+ "angle180": "180 เคกเคฟเคเฅเคฐเฅ",
+ "angle270": "270 เคกเคฟเคเฅเคฐเฅ",
+ "angle90": "90 เคกเคฟเคเฅเคฐเฅ",
+ "backgroundColor": "เคชเฅเคทเฅเค เคญเฅเคฎเคฟ เคฐเคเค",
+ "colorBlack": "เคเคพเคฒเคพ",
+ "colorCustom": "เคเคธเฅเคเคฎ",
+ "colorTransparent": "เคชเคพเคฐเคฆเคฐเฅเคถเฅ",
+ "colorWhite": "เคธเคซเฅเคฆ",
+ "customAngle": "เคเคธเฅเคเคฎ เคเฅเคฃ",
+ "customAnglePlaceholder": "เคกเคฟเคเฅเคฐเฅ",
+ "customColorPlaceholder": "#RRGGBB",
+ "description": "เคเคตเคฟ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเฅเคฃ เคธเฅ เคเฅเคฎเคพเคเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคเคตเคฟ",
+ "resultTitle": "เคเฅเคฎเคพเค เคเค เคเคตเคฟ",
+ "rotationAngle": "เคเฅเคฎเคพเคจเฅ เคเคพ เคเฅเคฃ",
+ "rotationOptions": "เคเฅเคฎเคพเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "shortDescription": "เคเคฟเคธเฅ เคเคตเคฟ เคเฅ เคเคธเคพเคจเฅ เคธเฅ เคเฅเคฎเคพเคเค.",
+ "title": "เคเคตเคฟ เคเฅเคฎเคพเคเค"
+ },
+ "watermark": {
+ "colorPlaceholder": "#RRGGBB",
+ "description": "เคเคตเคฟ เคชเคฐ เคเฅเคเฅเคธเฅเค เคฏเคพ เคเคตเคฟ เคตเฅเคเคฐเคฎเคพเคฐเฅเค เคเฅเคกเคผเฅเคเฅค",
+ "fontColor": "เคซเคผเฅเคจเฅเค เคฐเคเค",
+ "fontSize": "เคซเคผเฅเคจเฅเค เคเคเคพเคฐ",
+ "fontSizePlaceholder": "เคเคเคพเคฐ",
+ "imagePlaceholder": "เคเคตเคฟ เคซเคผเคพเคเคฒ",
+ "inputTitle": "เคเคจเคชเฅเค เคเคตเคฟ",
+ "opacity": "เคชเคพเคฐเคฆเคฐเฅเคถเคฟเคคเคพ",
+ "opacityPlaceholder": "เคชเฅเคฐเคคเคฟเคถเคค (1-100)",
+ "position": "เคธเฅเคฅเคฟเคคเคฟ",
+ "positionBottomLeft": "เคจเฅเคเฅ เคฌเคพเคเค",
+ "positionBottomRight": "เคจเฅเคเฅ เคฆเคพเคเค",
+ "positionCenter": "เคเฅเคเคฆเฅเคฐ",
+ "positionTopLeft": "เคเคชเคฐ เคฌเคพเคเค",
+ "positionTopRight": "เคเคชเคฐ เคฆเคพเคเค",
+ "resultTitle": "เคตเฅเคเคฐเคฎเคพเคฐเฅเค เคตเคพเคฒเฅ เคเคตเคฟ",
+ "textPlaceholder": "เคเฅเคเฅเคธเฅเค",
+ "title": "เคเคตเคฟ เคชเคฐ เคตเฅเคเคฐเคฎเคพเคฐเฅเค",
+ "typeImage": "เคเคตเคฟ",
+ "typeText": "เคเฅเคเฅเคธเฅเค",
+ "watermarkImage": "เคตเฅเคเคฐเคฎเคพเคฐเฅเค เคเคตเคฟ",
+ "watermarkOptions": "เคตเฅเคเคฐเคฎเคพเคฐเฅเค เคตเคฟเคเคฒเฅเคช",
+ "watermarkText": "เคตเฅเคเคฐเคฎเคพเคฐเฅเค เคเฅเคเฅเคธเฅเค",
+ "watermarkType": "เคตเฅเคเคฐเคฎเคพเคฐเฅเค เคชเฅเคฐเคเคพเคฐ"
+ }
+}
diff --git a/public/locales/hi/json.json b/public/locales/hi/json.json
new file mode 100644
index 0000000..b7e8ec4
--- /dev/null
+++ b/public/locales/hi/json.json
@@ -0,0 +1,115 @@
+{
+ "comparison": {
+ "description": "เคฆเฅ JSON เคตเคธเฅเคคเฅเคเค เคเฅ เคธเคเคฐเคเคจเคพ เคเคฐ เคฎเฅเคฒเฅเคฏเฅเค เคฎเฅเค เค
เคเคคเคฐ เคเฅ เคชเคนเคเคพเคจ เคเคฐเฅเคเฅค",
+ "shortDescription": "เคฆเฅ JSON เคตเคธเฅเคคเฅเคเค เคเฅ เคฌเฅเค เค
เคเคคเคฐ เคขเฅเคเคขเฅเค",
+ "title": "JSON เคคเฅเคฒเคจเคพ เคเคฐเฅเค"
+ },
+ "escape": {
+ "description": "JSON เคธเฅเคเฅเคฐเคฟเคเค เคฎเฅเค เคตเคฟเคถเฅเคท เคตเคฐเฅเคฃเฅเค เคเฅ เคเคธเฅเคเฅเคช เคเคฐเฅเคเฅค",
+ "escapeBackslashes": "เคฌเฅเคเคธเฅเคฒเฅเคถ เคเคธเฅเคเฅเคช เคเคฐเฅเค",
+ "escapeNewlines": "เคจเค เคชเคเคเฅเคคเคฟเคฏเคพเค เคเคธเฅเคเฅเคช เคเคฐเฅเค",
+ "escapeOptions": "เคเคธเฅเคเฅเคช เคตเคฟเคเคฒเฅเคช",
+ "escapeQuotes": "เคเคฆเฅเคงเคฐเคฃ เคเคธเฅเคเฅเคช เคเคฐเฅเค",
+ "escapeTabs": "เคเฅเคฌ เคเคธเฅเคเฅเคช เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค JSON",
+ "resultTitle": "เคเคธเฅเคเฅเคช เคเคฟเคฏเคพ เคเคฏเคพ JSON",
+ "title": "JSON เคเคธเฅเคเฅเคช เคเคฐเฅเค"
+ },
+ "escapeJson": {
+ "description": "JSON เคธเฅเคเฅเคฐเคฟเคเคเฅเคธ เคฎเฅเค เคตเคฟเคถเฅเคท เคตเคฐเฅเคฃเฅเค เคเฅ เคเคธเฅเคเฅเคช เคเคฐเฅเคเฅค เคธเฅเคฐเคเฅเคทเคฟเคค เคธเคเคเคฐเคฃ เคฏเคพ เคธเคเคเฅเคฐเคนเคฃ เคเฅ เคฒเคฟเค JSON เคกเฅเคเคพ เคเฅ เคเคเคฟเคค เคฐเฅเคช เคธเฅ เคเคธเฅเคเฅเคช เคเคฟเค เคเค เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเคเฅค",
+ "shortDescription": "JSON เคฎเฅเค เคตเคฟเคถเฅเคท เคตเคฐเฅเคฃเฅเค เคธเฅ เคฌเคเฅเค",
+ "title": "JSON เคธเฅ เคฌเคเฅเค"
+ },
+ "jsonToXml": {
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "JSON เคกเฅเคเคพ เคเฅ XML เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "includeAttributes": "เคตเคฟเคถเฅเคทเคคเคพเคเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "indentSize": "เคเคเคกเฅเคเค เคเคเคพเคฐ",
+ "inputTitle": "เคเคจเคชเฅเค JSON",
+ "resultTitle": "XML เคชเคฐเคฟเคฃเคพเคฎ",
+ "rootElement": "เคฎเฅเคฒ เคคเคคเฅเคต",
+ "rootPlaceholder": "เคคเคคเฅเคต เคจเคพเคฎ",
+ "shortDescription": "JSON เคเฅ XML เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค",
+ "sizePlaceholder": "เคเคเคพเคฐ",
+ "title": "JSON เคธเฅ XML"
+ },
+ "minify": {
+ "compactArrays": "เคธเคฐเคฃเคฟเคฏเคพเค เคธเคเคเฅเคทเคฟเคชเฅเคค เคเคฐเฅเค",
+ "description": "JSON เคเฅ เคธเคเคเฅเคทเคฟเคชเฅเคค เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค JSON",
+ "minifyOptions": "เคธเคเคเฅเคทเคฟเคชเฅเคค เคเคฐเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "removeComments": "เคเคฟเคชเฅเคชเคฃเคฟเคฏเคพเค เคนเคเคพเคเค",
+ "removeWhitespace": "เคธเคซเฅเคฆ เคธเฅเคฅเคพเคจ เคนเคเคพเคเค",
+ "resultTitle": "เคธเคเคเฅเคทเคฟเคชเฅเคค JSON",
+ "shortDescription": "เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ เคนเคเคพเคเคฐ JSON เคเฅ เคเฅเคเคพ เคเคฐเฅเค",
+ "title": "JSON เคธเคเคเฅเคทเคฟเคชเฅเคค เคเคฐเฅเค",
+ "toolInfo": {
+ "description": "JSON เคฎเคฟเคจเคฟเคซเคฟเคเฅเคถเคจ, JSON เคกเฅเคเคพ เคธเฅ เคธเคญเฅ เค
เคจเคพเคตเคถเฅเคฏเค เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ เคตเคฐเฅเคฃเฅเค เคเฅ เคนเคเคพเคจเฅ เคเฅ เคชเฅเคฐเคเฅเคฐเคฟเคฏเคพ เคนเฅ, เคเคฌเคเคฟ เคเคธเคเฅ เคตเฅเคงเคคเคพ เคฌเคฐเคเคฐเคพเคฐ เคฐเคนเคคเฅ เคนเฅเฅค เคเคธเคฎเฅเค เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ, เคจเค เคชเคเคเฅเคคเคฟเคฏเคพเค เคเคฐ เคเคเคกเฅเคเคเฅเคถเคจ เคนเคเคพเคจเคพ เคถเคพเคฎเคฟเคฒ เคนเฅ เคเฅ JSON เคเฅ เคธเคนเฅ เคขเคเค เคธเฅ เคชเคพเคฐเฅเคธ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคตเคถเฅเคฏเค เคจเคนเฅเค เคนเฅเคเฅค เคฎเคฟเคจเคฟเคซเคฟเคเฅเคถเคจ JSON เคกเฅเคเคพ เคเฅ เคเคเคพเคฐ เคเฅ เคเคฎ เคเคฐเคคเคพ เคนเฅ, เคเคฟเคธเคธเฅ เคฏเคน เคธเคเคเฅเคฐเคนเคฃ เคเคฐ เคธเคเคเคฐเคฃ เคเฅ เคฒเคฟเค เค
เคงเคฟเค เคเฅเคถเคฒ เคนเฅ เคเคพเคคเคพ เคนเฅ, เคเคฌเคเคฟ เคกเฅเคเคพ เคธเคเคฐเคเคจเคพ เคเคฐ เคฎเคพเคจ เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคฎเคพเคจ เคฐเคนเคคเฅ เคนเฅเคเฅค",
+ "title": "JSON เคฎเคฟเคจเคฟเคฎเคพเคเคเฅเคถเคจ เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "prettify": {
+ "description": "JSON เคเฅ เคธเฅเคเคฆเคฐ เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "formattingOptions": "เคซเฅเคฐเฅเคฎเฅเคเคฟเคเค เคตเคฟเคเคฒเฅเคช",
+ "indentCharacter": "เคเคเคกเฅเคเค เคตเคฐเฅเคฃ",
+ "indentSize": "เคเคเคกเฅเคเค เคเคเคพเคฐ",
+ "indentation": "เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค JSON",
+ "resultTitle": "เคธเฅเคเคฆเคฐ JSON",
+ "shortDescription": "JSON เคเฅเคก เคเฅ เคชเฅเคฐเคพเคฐเฅเคชเคฟเคค เคเคฐ เคธเฅเคถเฅเคญเคฟเคค เคเคฐเฅเค",
+ "sizePlaceholder": "เคเคเคพเคฐ",
+ "sortKeys": "เคเฅเคเคเคฟเคฏเคพเค เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "space": "เคธเฅเคชเฅเคธ",
+ "tab": "เคเฅเคฌ",
+ "title": "JSON เคธเฅเคเคฆเคฐ เคฌเคจเคพเคเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ JSON เคกเฅเคเคพ เคเฅ เคเคเคฟเคค เคเคเคกเฅเคเคเฅเคถเคจ เคเคฐ เคธเฅเคชเฅเคธเคฟเคเค เคเฅ เคธเคพเคฅ เคซเฅเคฐเฅเคฎเฅเค เคเคฐเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅ, เคเคฟเคธเคธเฅ เคฏเคน เค
เคงเคฟเค เคชเค เคจเฅเคฏ เคเคฐ เคเคพเคฎ เคเคฐเคจเฅ เคฎเฅเค เคเคธเคพเคจ เคนเฅ เคเคพเคคเคพ เคนเฅเฅค",
+ "title": "JSON เคธเฅเคเคฆเคฐ เคฌเคจเคพเคเค"
+ },
+ "useSpaces": "เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
+ "useSpacesDescription": "เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ เคเฅ เคธเคพเคฅ เคเคเคเคชเฅเค เคเคเคกเฅเคเค เคเคฐเฅเค",
+ "useTabs": "เคเฅเคฌ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
+ "useTabsDescription": "เคเฅเคฌ เคเฅ เคธเคพเคฅ เคเคเคเคชเฅเค เคเคเคกเฅเคเค เคเคฐเฅเค."
+ },
+ "stringify": {
+ "description": "JavaScript เคเคฌเฅเคเฅเคเฅเค เคเฅ JSON เคธเฅเคเฅเคฐเคฟเคเค เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "includeFunctions": "เคซเคผเคเคเฅเคถเคจ เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "includeUndefined": "เค
เคชเคฐเคฟเคญเคพเคทเคฟเคค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค เคเคฌเฅเคเฅเคเฅเค",
+ "prettyPrint": "เคธเฅเคเคฆเคฐ เคชเฅเคฐเคฟเคเค",
+ "resultTitle": "JSON เคธเฅเคเฅเคฐเคฟเคเค",
+ "shortDescription": "เคเคฌเฅเคเฅเคเฅเค เคเฅ JSON เคธเฅเคเฅเคฐเคฟเคเค เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค",
+ "stringifyOptions": "เคธเฅเคเฅเคฐเคฟเคเคเคฟเคซเคพเค เคตเคฟเคเคฒเฅเคช",
+ "title": "JSON เคธเฅเคเฅเคฐเคฟเคเคเคฟเคซเคพเค"
+ },
+ "tsvToJson": {
+ "arrayFormat": "เคธเคฐเคฃเฅ เคชเฅเคฐเคพเคฐเฅเคช",
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "TSV เคกเฅเคเคพ เคเฅ JSON เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "firstRowAsHeaders": "เคชเคนเคฒเฅ เคชเคเคเฅเคคเคฟ เคถเฅเคฐเฅเคทเค เคเฅ เคฐเฅเคช เคฎเฅเค",
+ "includeHeaders": "เคถเฅเคฐเฅเคทเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค TSV",
+ "objectFormat": "เคเคฌเฅเคเฅเคเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "resultTitle": "JSON เคชเคฐเคฟเคฃเคพเคฎ",
+ "shortDescription": "TSV เคเฅ JSON เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค",
+ "title": "TSV เคธเฅ JSON"
+ },
+ "validateJson": {
+ "allowComments": "เคเคฟเคชเฅเคชเคฃเคฟเคฏเคพเค เค
เคจเฅเคฎเคคเคฟ เคฆเฅเค",
+ "allowTrailingCommas": "เค
เคจเฅเคเคพเคฎเฅ เคเฅเคฎเคพ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเค",
+ "description": "JSON เคธเฅเคเฅเคฐเคฟเคเค เคเฅ เคตเฅเคงเคคเคพ เคเคพเคเคเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค JSON",
+ "invalidJson": "โ {{error}}",
+ "resultTitle": "เคฎเคพเคจเฅเคฏเคคเคพ เคชเคฐเคฟเคฃเคพเคฎ",
+ "shortDescription": "เคคเฅเคฐเฅเคเคฟเคฏเฅเค เคเฅ เคฒเคฟเค JSON เคเฅเคก เคธเคคเฅเคฏเคพเคชเคฟเคค เคเคฐเฅเค",
+ "strictMode": "เคธเคเฅเคค เคฎเฅเคก",
+ "title": "JSON เคฎเคพเคจเฅเคฏ เคเคฐเฅเค",
+ "toolInfo": {
+ "description": "JSON (เคเคพเคตเคพเคธเฅเคเฅเคฐเคฟเคชเฅเค เคเคฌเฅเคเฅเคเฅเค เคจเฅเคเฅเคถเคจ) เคเค เคนเคฒเฅเคเคพ เคกเฅเคเคพ-เคเคเคเคฐเคเฅเคเค เคซเคผเฅเคฐเฅเคฎเฅเค เคนเฅเฅค JSON เคธเคคเฅเคฏเคพเคชเคจ เคฏเคน เคธเฅเคจเคฟเคถเฅเคเคฟเคค เคเคฐเคคเคพ เคนเฅ เคเคฟ เคกเฅเคเคพ เคเฅ เคธเคเคฐเคเคจเคพ JSON เคฎเคพเคจเค เคเฅ เค
เคจเฅเคฐเฅเคช เคนเฅเฅค เคเค เคฎเคพเคจเฅเคฏ JSON เคเคฌเฅเคเฅเคเฅเค เคฎเฅเค เคฏเฅ เคเฅเคเคผเฅเค เคนเฅเคจเฅ เคเคพเคนเคฟเค: - เคชเฅเคฐเฅเคชเคฐเฅเคเฅ เคเฅ เคจเคพเคฎ เคฆเฅเคนเคฐเฅ เคเคฆเฅเคงเคฐเคฃ เคเคฟเคนเฅเคจเฅเค เคฎเฅเค เคธเคเคฒเคเฅเคจ เคนเฅเคเฅค - เคเคเคฟเคค เคฐเฅเคช เคธเฅ เคธเคเคคเฅเคฒเคฟเคค เคเคฐเฅเคฒเฅ เคฌเฅเคฐเฅเคธเฅเคเคผ {}เฅค - เค
เคเคคเคฟเคฎ เคเฅเคเคเฅ-เคฎเคพเคจ เคฏเฅเคเฅเคฎ เคเฅ เคฌเคพเคฆ เคเฅเค เค
เคจเฅเคเคพเคฎเฅ เค
เคฒเฅเคชเคตเคฟเคฐเคพเคฎ เคจ เคนเฅเฅค - เคเคฌเฅเคเฅเคเฅเคเฅเคธ เคเคฐ เคเคฐเฅ เคเคพ เคเคเคฟเคค เคจเฅเคธเฅเคเคฟเคเคเฅค เคฏเคน เคเฅเคฒ เคเคจเคชเฅเค JSON เคเฅ เคเคพเคเค เคเคฐเคคเคพ เคนเฅ เคเคฐ เคธเคพเคฎเคพเคจเฅเคฏ เคคเฅเคฐเฅเคเคฟเคฏเฅเค เคเฅ เคชเคนเคเคพเคจ เคเคฐเคจเฅ เคเคฐ เคเคจเฅเคนเฅเค เค เฅเค เคเคฐเคจเฅ เคฎเฅเค เคฎเคฆเคฆ เคเฅ เคฒเคฟเค เคซเคผเฅเคกเคฌเฅเค เคชเฅเคฐเคฆเคพเคจ เคเคฐเคคเคพ เคนเฅเฅค",
+ "title": "JSON เคธเคคเฅเคฏเคพเคชเคจ เคเฅเคฏเคพ เคนเฅ?"
+ },
+ "validJson": "โ
เคฎเคพเคจเฅเคฏ JSON",
+ "validationOptions": "เคฎเคพเคจเฅเคฏเคคเคพ เคตเคฟเคเคฒเฅเคช"
+ }
+}
diff --git a/public/locales/hi/list.json b/public/locales/hi/list.json
new file mode 100644
index 0000000..3cbf179
--- /dev/null
+++ b/public/locales/hi/list.json
@@ -0,0 +1,283 @@
+{
+ "duplicate": {
+ "concatenate": "CONCATENATE",
+ "concatenateDescription": "เคชเฅเคฐเคคเคฟเคฏเฅเค เคเฅ เคธเคเคฏเฅเคเคฟเคค เคเคฐเฅเค (เคฏเคฆเคฟ เค
เคจเคเฅเค เคเคฟเคฏเคพ เคเคฏเคพ, เคคเฅ เคเคเคเคฎ เคเคชเคธ เคฎเฅเค เคเฅเคเคฅ เคเคพเคเคเคเฅ)",
+ "copyDescription": "เคชเฅเคฐเคคเคฟเคฏเฅเค เคเฅ เคธเคเคเฅเคฏเคพ (เคเคเคถเคฟเค เคนเฅ เคธเคเคคเฅ เคนเฅ)",
+ "countPlaceholder": "เคธเคเคเฅเคฏเคพ",
+ "description": "เคธเฅเคเฅ เคฎเฅเค เคเคเคเคฎ เคเฅ เคฆเฅเคนเคฐเคพเคเคเฅค",
+ "duplicateAll": "เคธเคญเฅ เคเคเคเคฎ เคฆเฅเคนเคฐเคพเคเค",
+ "duplicateCount": "เคฆเฅเคนเคฐเคพเคต เคเฅ เคธเคเคเฅเคฏเคพ",
+ "duplicateEach": "เคชเฅเคฐเคคเฅเคฏเฅเค เคเคเคเคฎ เคฆเฅเคนเคฐเคพเคเค",
+ "duplicationOptions": "เคฆเฅเคนเคฐเคพเคต เคตเคฟเคเคฒเฅเคช",
+ "examples": {
+ "fractional": {
+ "description": "เคฏเคน เคเคฆเคพเคนเคฐเคฃ เคฆเคฟเคเคพเคคเคพ เคนเฅ เคเคฟ เคเคฟเคธเฅ เคธเฅเคเฅ เคเฅ เคเคเคถเคฟเค เคธเคเคเฅเคฏเคพ เคเฅ เคชเฅเคฐเคคเคฟเคฒเคฟเคชเคฟ เคเฅเคธเฅ เคฌเคจเคพเค เคเคพเคเฅค",
+ "title": "เคเคเคถเคฟเค เคฆเฅเคนเคฐเคพเคต"
+ },
+ "interweave": {
+ "description": "เคฏเคน เคเคฆเคพเคนเคฐเคฃ เคฆเคฟเคเคพเคคเคพ เคนเฅ เคเคฟ เคตเคธเฅเคคเฅเคเค เคเฅ เคธเคเคฏเฅเคเคฟเคค เคเคฐเคจเฅ เคเฅ เคฌเคเคพเคฏ เคเคจเฅเคนเฅเค เคเฅเคธเฅ เคเคชเคธ เคฎเฅเค เคเฅเคกเคผเคพ เคเคพเคเฅค",
+ "title": "เคเคชเคธ เคฎเฅเค เคเฅเคกเคผเฅ เคนเฅเค เคตเคธเฅเคคเฅเคเค"
+ },
+ "reverse": {
+ "description": "เคฏเคน เคเคฆเคพเคนเคฐเคฃ เคฆเคฟเคเคพเคคเคพ เคนเฅ เคเคฟ เคเคฟเคธเฅ เคธเฅเคเฅ เคเฅ เคเคฒเฅเคเฅ เคเฅเคฐเคฎ เคฎเฅเค เคเฅเคธเฅ เคฆเฅเคนเคฐเคพเคฏเคพ เคเคพเคเฅค",
+ "title": "เคฐเคฟเคตเคฐเฅเคธ เคกเฅเคชเฅเคฒเคฟเคเฅเคถเคจ"
+ },
+ "simple": {
+ "description": "เคฏเคน เคเคฆเคพเคนเคฐเคฃ เคฆเคฟเคเคพเคคเคพ เคนเฅ เคเคฟ เคถเคฌเฅเคฆเฅเค เคเฅ เคธเฅเคเฅ เคเฅ เคชเฅเคฐเคคเคฟเคฒเคฟเคชเคฟ เคเฅเคธเฅ เคฌเคจเคพเค เคเคพเคเฅค",
+ "title": "เคธเคฐเคฒ เคฆเฅเคนเคฐเคพเคต"
+ }
+ },
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "joinSeparatorDescription": "เคกเฅเคชเฅเคฒเคฟเคเฅเค เคธเฅเคเฅ เคฎเฅเค เคถเคพเคฎเคฟเคฒ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคตเคฟเคญเคพเคเค",
+ "resultTitle": "เคฆเฅเคนเคฐเคพเค เคเค เคธเฅเคเฅ",
+ "reverse": "เคธเฅเคเฅ เคเคฒเคเคพ เคเคฐเฅเค",
+ "reverseDescription": "เคกเฅเคชเฅเคฒเคฟเคเฅเค เคเคเคเคฎ เคเฅ เคเคฒเค เคฆเฅเค",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคฎเคพเคจเคฆเคเคกเฅเค เคเฅ เคธเคพเคฅ เคกเฅเคชเฅเคฒเคฟเคเฅเค เคธเฅเคเฅ เคเคเคเคฎ",
+ "splitByRegex": "เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคฆเฅเคตเคพเคฐเคพ เคตเคฟเคญเคพเคเคฟเคค",
+ "splitBySymbol": "เคชเฅเคฐเคคเฅเค เคฆเฅเคตเคพเคฐเคพ เคตเคฟเคญเคพเคเคฟเคค",
+ "splitOptions": "เคตเคฟเคญเคพเคเคฟเคค เคตเคฟเคเคฒเฅเคช",
+ "splitSeparatorDescription": "เคธเฅเคเฅ เคเฅ เคตเคฟเคญเคพเคเคฟเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคตเคฟเคญเคพเคเค",
+ "title": "เคเคเคเคฎ เคฆเฅเคนเคฐเคพเคเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคธเฅเคเฅ เคฎเฅเค เคเคเคเคฎเฅเคธ เคเฅ เคชเฅเคฐเคคเคฟเคฒเคฟเคชเคฟ เคฌเคจเคพเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคชเฅเคฐเคคเคฟเคฏเฅเค เคเฅ เคธเคเคเฅเคฏเคพ (เคเคเคถเคฟเค เคฎเคพเคจเฅเค เคธเคนเคฟเคค) เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค, เคจเคฟเคฏเคเคคเฅเคฐเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเค เคเคฟ เคเคเคเคฎเฅเคธ เคธเคเคฏเฅเคเคฟเคค เคนเฅเค เคฏเคพ เค
เคเคคเคฐเฅเคเฅเคเคฅเคฟเคค, เคเคฐ เคฏเคนเคพเค เคคเค เคเคฟ เคกเฅเคชเฅเคฒเคฟเคเฅเค เคเคฟเค เคเค เคเคเคเคฎเฅเคธ เคเฅ เคเคฒเค เคญเฅ เคธเคเคคเฅ เคนเฅเคเฅค เคฏเคน เคฆเฅเคนเคฐเคพเค เคเค เคชเฅเคเคฐเฅเคจ เคฌเคจเคพเคจเฅ, เคชเคฐเฅเคเฅเคทเคฃ เคกเฅเคเคพ เคเคคเฅเคชเคจเฅเคจ เคเคฐเคจเฅ, เคฏเคพ เคชเฅเคฐเฅเคตเคพเคจเฅเคฎเคพเคจเคฟเคค เคธเคพเคฎเคเฅเคฐเฅ เคตเคพเคฒเฅ เคธเฅเคเคฟเคฏเฅเค เคเคพ เคตเคฟเคธเฅเคคเคพเคฐ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเคเฅ เคนเฅเฅค",
+ "title": "เคธเฅเคเฅ เคฆเฅเคนเคฐเคพเคต"
+ }
+ },
+ "findMostPopular": {
+ "caseSensitive": "เคเฅเคธ เคธเคเคตเฅเคฆเฅ",
+ "countPlaceholder": "เคธเคเคเฅเคฏเคพ",
+ "description": "เคธเฅเคเฅ เคฎเฅเค เคธเคฌเคธเฅ เค
เคงเคฟเค เคฌเคพเคฐ เคเคจเฅ เคตเคพเคฒเฅ เคเคเคเคฎ เคเฅเคเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "popularityOptions": "เคฒเฅเคเคชเฅเคฐเคฟเคฏเคคเคพ เคตเคฟเคเคฒเฅเคช",
+ "removeEmpty": "เคเคพเคฒเฅ เคเคเคเคฎ เคนเคเคพเคเค",
+ "resultTitle": "เคฒเฅเคเคชเฅเคฐเคฟเคฏ เคเคเคเคฎ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคธเคฌเคธเฅ เค
เคงเคฟเค เคฌเคพเคฐ เคเคจเฅ เคตเคพเคฒเฅ เคตเคธเฅเคคเฅเคเค เคเฅ เคเฅเคเฅเค",
+ "title": "เคธเคฌเคธเฅ เคฒเฅเคเคชเฅเคฐเคฟเคฏ เคเฅเคเฅเค",
+ "topCount": "เคถเฅเคฐเฅเคท เคธเคเคเฅเคฏเคพ"
+ },
+ "findUnique": {
+ "caseSensitive": "เคเฅเคธ เคธเคเคตเฅเคฆเฅ",
+ "caseSensitiveItems": "เคเฅเคธ เคธเฅเคเคธเคฟเคเคฟเคต เคเคเคเคฎ",
+ "caseSensitiveItemsDescription": "เคธเฅเคเฅ เคฎเฅเค เค
เคฒเค-เค
เคฒเค เคเฅเคธ เคตเคพเคฒเฅ เคเคเคเคฎ เคเฅ เค
เคฆเฅเคตเคฟเคคเฅเคฏ เคคเคคเฅเคต เคเฅ เคฐเฅเคช เคฎเฅเค เคเคเคเคชเฅเค เคเคฐเฅเคเฅค",
+ "delimiterDescription": "เคเค เคธเฅเคฎเคพเคเคเค เคชเฅเคฐเคคเฅเค เคฏเคพ เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคธเฅเค เคเคฐเฅเค.",
+ "description": "เคธเฅเคเฅ เคธเฅ เค
เคฆเฅเคตเคฟเคคเฅเคฏ เคเคเคเคฎ เคจเคฟเคเคพเคฒเฅเคเฅค",
+ "findAbsolutelyUniqueItems": "เคฌเคฟเคฒเฅเคเฅเคฒ เค
เคจเฅเคเฅ เคตเคธเฅเคคเฅเคเค เคเฅเคเฅเค",
+ "findAbsolutelyUniqueItemsDescription": "เคธเฅเคเฅ เคเฅ เคเฅเคตเคฒ เคเคจ เคเคเคเคฎเฅเค เคเฅ เคชเฅเคฐเคฆเคฐเฅเคถเคฟเคค เคเคฐเฅเค เคเฅ เคเคเคฒ เคชเฅเคฐเคคเคฟเคฒเคฟเคชเคฟ เคฎเฅเค เคฎเฅเคเฅเคฆ เคนเฅเคเฅค",
+ "inputListDelimiter": "เคเคจเคชเฅเค เคธเฅเคเฅ เคธเฅเคฎเคพเคเคเค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "outputListDelimiter": "เคเคเคเคชเฅเค เคธเฅเคเฅ เคธเฅเคฎเคพเคเคเค",
+ "removeEmpty": "เคเคพเคฒเฅ เคเคเคเคฎ เคนเคเคพเคเค",
+ "resultTitle": "เค
เคฆเฅเคตเคฟเคคเฅเคฏ เคเคเคเคฎ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคธเฅเคเฅ เคฎเฅเค เค
เคฆเฅเคตเคฟเคคเฅเคฏ เคเคเคเคฎ เคเฅเคเฅเค",
+ "skipEmptyItems": "เคเคพเคฒเฅ เคเคเคเคฎ เคเฅเคกเคผเฅเค",
+ "skipEmptyItemsDescription": "เคเคเคเคชเฅเค เคฎเฅเค เคเคพเคฒเฅ เคธเฅเคเฅ เคเคเคเคฎ เคถเคพเคฎเคฟเคฒ เคจ เคเคฐเฅเคเฅค",
+ "title": "เค
เคฆเฅเคตเคฟเคคเฅเคฏ เคเคเคเคฎ เคเฅเคเฅเค",
+ "trimItems": "เคธเฅเคเฅ เคเคเคเคฎ เคเฅเคฐเคฟเคฎ เคเคฐเฅเค",
+ "trimItemsDescription": "เคตเคธเฅเคคเฅเคเค เคเฅ เคคเฅเคฒเคจเคพ เคเคฐเคจเฅ เคธเฅ เคชเคนเคฒเฅ เคชเฅเคฐเคพเคฐเคเคญเคฟเค เคเคฐ เค
เคเคคเคฟเคฎ เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ เคนเคเคพ เคฆเฅเคเฅค",
+ "trimWhitespace": "เคธเคซเฅเคฆ เคธเฅเคฅเคพเคจ เคเฅเคฐเคฟเคฎ เคเคฐเฅเค",
+ "uniqueItemOptions": "เค
เคฆเฅเคตเคฟเคคเฅเคฏ เคเคเคเคฎ เคตเคฟเคเคฒเฅเคช",
+ "uniqueOptions": "เค
เคฆเฅเคตเคฟเคคเฅเคฏ เคตเคฟเคเคฒเฅเคช"
+ },
+ "group": {
+ "deleteEmptyItems": "เคเคพเคฒเฅ เคเคเคเคฎ เคนเคเคพเคเค",
+ "deleteEmptyItemsDescription": "เคเคพเคฒเฅ เคเคเคเคฎเฅเค เคเฅ เค
เคจเคฆเฅเคเคพ เคเคฐเฅเค เคเคฐ เคเคจเฅเคนเฅเค เคธเคฎเฅเคนเฅเค เคฎเฅเค เคถเคพเคฎเคฟเคฒ เคจ เคเคฐเฅเคเฅค",
+ "description": "เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคธเคฎเฅเคนเคฟเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคธเคฐเคฒ เคเคชเคเคฐเคฃเฅค",
+ "emptyItemsAndPadding": "เคเคพเคฒเฅ เคเคเคเคฎ เคเคฐ เคชเฅเคกเคฟเคเค",
+ "groupByFirstChar": "เคชเคนเคฒเฅ เคตเคฐเฅเคฃ เคเฅ เค
เคจเฅเคธเคพเคฐ เคธเคฎเฅเคนเคฟเคค เคเคฐเฅเค",
+ "groupByLastChar": "เค
เคเคคเคฟเคฎ เคตเคฐเฅเคฃ เคเฅ เค
เคจเฅเคธเคพเคฐ เคธเคฎเฅเคนเคฟเคค เคเคฐเฅเค",
+ "groupByLength": "เคฒเคเคฌเคพเค เคเฅ เค
เคจเฅเคธเคพเคฐ เคธเคฎเฅเคนเคฟเคค เคเคฐเฅเค",
+ "groupByPattern": "เคชเฅเคเคฐเฅเคจ เคเฅ เค
เคจเฅเคธเคพเคฐ เคธเคฎเฅเคนเคฟเคค เคเคฐเฅเค",
+ "groupHeaders": "เคธเคฎเฅเคน เคถเฅเคฐเฅเคทเค เคเฅเคกเคผเฅเค",
+ "groupNumberDescription": "เคเค เคธเคฎเฅเคน เคฎเฅเค เคตเคธเฅเคคเฅเคเค เคเฅ เคธเคเคเฅเคฏเคพ",
+ "groupSeparatorDescription": "เคธเคฎเฅเคน เคตเคฟเคญเคพเคเค เคตเคฐเฅเคฃ",
+ "groupSizeAndSeparators": "เคธเคฎเฅเคน เคเคพ เคเคเคพเคฐ เคเคฐ เคตเคฟเคญเคพเคเค",
+ "groupingOptions": "เคธเคฎเฅเคนเฅเคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "inputItemSeparator": "เคเคจเคชเฅเค เคเคเคเคฎ เคตเคฟเคญเคพเคเค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "itemSeparatorDescription": "เคเคเคเคฎ เคตเคฟเคญเคพเคเค เคตเคฐเฅเคฃ",
+ "leftWrapDescription": "เคธเคฎเฅเคน เคเคพ เคฌเคพเคฏเคพเค เคเคตเคฐเคฃ เคชเฅเคฐเคคเฅเค.",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "padNonFullGroups": "เคชเฅเคก เคเฅเคฐ-เคชเฅเคฐเฅเคฃ เคธเคฎเฅเคน",
+ "padNonFullGroupsDescription": "เคเฅเคฐ-เคชเฅเคฐเฅเคฃ เคธเคฎเฅเคนเฅเค เคเฅ เคเคธเฅเคเคฎ เคเคเคเคฎ เคธเฅ เคญเคฐเฅเค (เคจเฅเคเฅ เคฆเคฐเฅเค เคเคฐเฅเค).",
+ "paddingCharDescription": "เคเฅเคฐ-เคชเฅเคฐเฅเคฃ เคธเคฎเฅเคนเฅเค เคเฅ เคชเฅเคก เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคธ เคตเคฐเฅเคฃ เคฏเคพ เคเคเคเคฎ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค.",
+ "patternPlaceholder": "เคฐเฅเคเฅเคเฅเคธ เคชเฅเคเคฐเฅเคจ",
+ "resultTitle": "เคธเคฎเฅเคนเคฟเคค เคธเฅเคเฅ",
+ "rightWrapDescription": "เคธเคฎเฅเคน เคเคพ เคฆเคพเคฏเคพเค เคเคตเคฐเคฃ เคชเฅเคฐเคคเฅเค.",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคธเคพเคฎเคพเคจเฅเคฏ เคเฅเคฃเฅเค เคฆเฅเคตเคพเคฐเคพ เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคธเคฎเฅเคนเคฟเคค เคเคฐเฅเค",
+ "splitOperators": {
+ "regex": {
+ "description": "เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคเฅ เคธเคพเคฅ เคเคจเคชเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคธเฅเคฎเคพเคเคเคฟเคค เคเคฐเฅเค.",
+ "title": "เคตเคฟเคญเคพเคเคจ เคเฅ เคฒเคฟเค เคฐเฅเคเฅเคเฅเคธ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค"
+ },
+ "symbol": {
+ "description": "เคเคจเคชเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคเคฟเคธเฅ เคตเคฐเฅเคฃ เคธเฅ เคธเฅเคฎเคพเคเคเคฟเคค เคเคฐเฅเค.",
+ "title": "เคตเคฟเคญเคพเคเคจ เคเฅ เคฒเคฟเค เคชเฅเคฐเคคเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค"
+ }
+ },
+ "splitSeparatorDescription": "เคเค เคธเฅเคฎเคพเคเคเค เคชเฅเคฐเคคเฅเค เคฏเคพ เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคธเฅเค เคเคฐเฅเค.",
+ "title": "เคธเฅเคเฅ เคธเคฎเฅเคนเคฟเคค เคเคฐเฅเค"
+ },
+ "reverse": {
+ "description": "เคธเฅเคเฅ เคฎเฅเค เคเคเคเคฎ เคเฅ เคเฅเคฐเคฎ เคเฅ เคเคฒเคเคพ เคเคฐเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "itemSeparator": "เคเคเคเคฎ เคตเคฟเคญเคพเคเค",
+ "itemSeparatorDescription": "เคเค เคธเฅเคฎเคพเคเคเค เคชเฅเคฐเคคเฅเค เคฏเคพ เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคธเฅเค เคเคฐเฅเค.",
+ "outputListOptions": "เคเคเคเคชเฅเค เคธเฅเคเฅ เคตเคฟเคเคฒเฅเคช",
+ "outputSeparatorDescription": "เคเคเคเคชเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคตเคฟเคญเคพเคเค.",
+ "resultTitle": "เคเคฒเคเฅ เคธเฅเคเฅ",
+ "reverseEachItem": "เคชเฅเคฐเคคเฅเคฏเฅเค เคเคเคเคฎ เคเคฒเคเคพ เคเคฐเฅเค",
+ "reverseOptions": "เคเคฒเคเคพเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "reverseOrder": "เคเฅเคฐเคฎ เคเคฒเคเคพ เคเคฐเฅเค",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคเคฒเฅเคฆเฅ เคธเฅ เคธเฅเคเฅ เคเฅ เคเคฒเคเคพ เคเคฐเฅเค",
+ "splitOperators": {
+ "regex": {
+ "description": "เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคเฅ เคธเคพเคฅ เคเคจเคชเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคธเฅเคฎเคพเคเคเคฟเคค เคเคฐเฅเค.",
+ "title": "เคตเคฟเคญเคพเคเคจ เคเฅ เคฒเคฟเค เคฐเฅเคเฅเคเฅเคธ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค"
+ },
+ "symbol": {
+ "description": "เคเคจเคชเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคเคฟเคธเฅ เคตเคฐเฅเคฃ เคธเฅ เคธเฅเคฎเคพเคเคเคฟเคค เคเคฐเฅเค.",
+ "title": "เคตเคฟเคญเคพเคเคจ เคเฅ เคฒเคฟเค เคชเฅเคฐเคคเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค"
+ }
+ },
+ "splitterMode": "เคธเฅเคชเฅเคฒเคฟเคเคฐ เคฎเฅเคก",
+ "title": "เคธเฅเคเฅ เคเคฒเคเคพ เคเคฐเฅเค",
+ "toolInfo": {
+ "description": "เคเคธ เคเคชเคฏเฅเคเคฟเคคเคพ เคธเฅ, เคเคช เคเคฟเคธเฅ เคธเฅเคเฅ เคฎเฅเค เคเคเคเคฎเฅเคธ เคเฅ เคเฅเคฐเคฎ เคเฅ เคเคฒเค เคธเคเคคเฅ เคนเฅเคเฅค เคฏเคน เคเคชเคฏเฅเคเคฟเคคเคพ เคชเคนเคฒเฅ เคเคจเคชเฅเค เคธเฅเคเฅ เคเฅ เค
เคฒเค-เค
เคฒเค เคเคเคเคฎเฅเคธ เคฎเฅเค เคตเคฟเคญเคพเคเคฟเคค เคเคฐเคคเฅ เคนเฅ เคเคฐ เคซเคฟเคฐ เค
เคเคคเคฟเคฎ เคเคเคเคฎ เคธเฅ เคชเคนเคฒเฅ เคเคเคเคฎ เคคเค เคเคจเคฎเฅเค เคชเฅเคจเคฐเคพเคตเฅเคคเคฟ เคเคฐเคคเฅ เคนเฅ, เคเคฐ เคชเฅเคจเคฐเคพเคตเฅเคคเฅเคคเคฟ เคเฅ เคฆเฅเคฐเคพเคจ เคชเฅเคฐเคคเฅเคฏเฅเค เคเคเคเคฎ เคเฅ เคเคเคเคชเฅเค เคฎเฅเค เคชเฅเคฐเคฟเคเค เคเคฐเคคเฅ เคนเฅเฅค เคเคจเคชเฅเค เคธเฅเคเฅ เคฎเฅเค เคเฅเค เคญเฅ เคนเฅ เคธเคเคคเคพ เคนเฅ เคเคฟเคธเฅ เคชเคพเค เฅเคฏ เคกเฅเคเคพ เคเฅ เคฐเฅเคช เคฎเฅเค เคฆเคฐเฅเคถเคพเคฏเคพ เคเคพ เคธเคเคคเคพ เคนเฅ, เคเคฟเคธเคฎเฅเค เค
เคเค, เคธเคเคเฅเคฏเคพเคเค, เคธเฅเคเฅเคฐเคฟเคเค, เคถเคฌเฅเคฆ, เคตเคพเคเฅเคฏ เคเคฆเคฟ เคถเคพเคฎเคฟเคฒ เคนเฅเคเฅค เคเคจเคชเฅเค เคเคเคเคฎ เคตเคฟเคญเคพเคเค เคเค เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคญเฅ เคนเฅ เคธเคเคคเคพ เคนเฅเฅค เคเคฆเคพเคนเคฐเคฃ เคเฅ เคฒเคฟเค, เคฐเฅเคเฅเคฒเคฐ เคเคเฅเคธเคชเฅเคฐเฅเคถเคจ /[;,]/ เคเคชเคเฅ เค
เคฒเฅเคชเคตเคฟเคฐเคพเคฎ เคฏเคพ เค
เคฐเฅเคงเคตเคฟเคฐเคพเคฎ เคธเฅ เค
เคฒเค เคเคฟเค เคเค เคเคเคเคฎเฅเคธ เคเคพ เคเคชเคฏเฅเค เคเคฐเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคเคพเฅค เคเคจเคชเฅเค เคเคฐ เคเคเคเคชเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคตเคฟเคญเคพเคเค เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค เค
เคจเฅเคเฅเคฒเคฟเคค เคเคฟเค เคเคพ เคธเคเคคเฅ เคนเฅเคเฅค เคกเคฟเคซเคผเฅเคฒเฅเค เคฐเฅเคช เคธเฅ, เคเคจเคชเฅเค เคเคฐ เคเคเคเคชเฅเค เคฆเฅเคจเฅเค เคธเฅเคเคฟเคฏเคพเค เค
เคฒเฅเคชเคตเคฟเคฐเคพเคฎ เคธเฅ เค
เคฒเค เคนเฅเคคเฅ เคนเฅเคเฅค Listabulous!",
+ "title": "เคธเฅเคเฅ เคเคฒเคเคจเฅ เคตเคพเคฒเคพ เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "rotate": {
+ "description": "เคธเฅเคเฅ เคฎเฅเค เคเคเคเคฎ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคธเฅเคฅเคพเคจเฅเค เคฆเฅเคตเคพเคฐเคพ เคเฅเคฎเคพเคเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "resultTitle": "เคเฅเคฎเคพเค เคเค เคธเฅเคเฅ",
+ "rotateDirection": "เคเฅเคฎเคพเคจเฅ เคเฅ เคฆเคฟเคถเคพ",
+ "rotateLeft": "เคฌเคพเคเค เคเคฐ เคเฅเคฎเคพเคเค",
+ "rotateRight": "เคฆเคพเคเค เคเคฐ เคเฅเคฎเคพเคเค",
+ "rotateSteps": "เคเฅเคฎเคพเคจเฅ เคเฅ เคเคฐเคฃ",
+ "rotationOptions": "เคเฅเคฎเคพเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคธเฅเคฅเคพเคจเฅเค เคชเคฐ เคเฅเคฎเคพเคเค",
+ "stepsPlaceholder": "เคเคฐเคฃเฅเค เคเฅ เคธเคเคเฅเคฏเคพ",
+ "title": "เคธเฅเคเฅ เคเฅเคฎเคพเคเค"
+ },
+ "shuffle": {
+ "delimiterDescription": "เคเค เคธเฅเคฎเคพเคเคเค เคชเฅเคฐเคคเฅเค เคฏเคพ เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคธเฅเค เคเคฐเฅเค.",
+ "description": "เคธเฅเคเฅ เคฎเฅเค เคเคเคเคฎ เคเฅ เคฏเคพเคฆเฅเคเฅเคเคฟเค เคเฅเคฐเคฎ เคฎเฅเค เคตเฅเคฏเคตเคธเฅเคฅเคฟเคค เคเคฐเฅเคเฅค",
+ "inputListSeparator": "เคเคจเคชเฅเค เคธเฅเคเฅ เคตเคฟเคญเคพเคเค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "joinSeparatorDescription": "เคฏเคพเคฆเฅเคเฅเคเคฟเค เคธเฅเคเฅ เคฎเฅเค เคเคธ เคตเคฟเคญเคพเคเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเคเฅค",
+ "outputLengthDescription": "เคเคคเคจเฅ เคธเคพเคฐเฅ เคฏเคพเคฆเฅเคเฅเคเคฟเค เคเคเคเคฎ เคเคเคเคชเฅเค เคเคฐเฅเค",
+ "randomSeed": "เคฏเคพเคฆเฅเคเฅเคเคฟเค เคฌเฅเค",
+ "resultTitle": "เคซเฅเคฐเคฌเคฆเคฒ เคเฅ เคเค เคธเฅเคเฅ",
+ "seedPlaceholder": "เคฌเฅเค เคฎเคพเคจ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคธเฅเคเฅ เคเคเคเคฎเฅเค เคเคพ เคเฅเคฐเคฎ เคฏเคพเคฆเฅเคเฅเคเคฟเค เคเคฐเฅเค",
+ "shuffleOptions": "เคซเฅเคฐเคฌเคฆเคฒ เคตเคฟเคเคฒเฅเคช",
+ "shuffledListLength": "เคซเฅเคฐเคฌเคฆเคฒ เคธเฅเคเฅ เคเฅ เคฒเคเคฌเคพเค",
+ "shuffledListSeparator": "เคซเฅเคฐเคฌเคฆเคฒ เคธเฅเคเฅ เคตเคฟเคญเคพเคเค",
+ "title": "เคธเฅเคเฅ เคซเฅเคฐเคฌเคฆเคฒ เคเคฐเฅเค"
+ },
+ "sort": {
+ "ascending": "เคเคฐเฅเคนเฅ",
+ "caseSensitive": "เคเฅเคธ เคธเฅเคเคธเคฟเคเคฟเคต เคธเฅเคฐเฅเค",
+ "caseSensitiveDescription": "เคฌเคกเคผเฅ เคเคฐ เคเฅเคเฅ เค
เคเฅเคทเคฐเฅเค เคตเคพเคฒเฅ เคเคเคเคฎ เคเฅ เค
เคฒเค-เค
เคฒเค เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเคเฅค เคฌเคกเคผเฅ เค
เคเฅเคทเคฐเฅเค เคเฅ เคเคฐเฅเคนเฅ เคเฅเคฐเคฎ เคฎเฅเค เคเฅเคเฅ เค
เคเฅเคทเคฐเฅเค เคธเฅ เคชเคนเคฒเฅ เคฐเคเฅเคเฅค (เคเฅเคตเคฒ เคตเคฐเฅเคฃเคพเคจเฅเคเฅเคฐเคฎเคฟเค เคเฅเคฐเคฎ เคฎเฅเค เคเคพเคฎ เคเคฐเคคเคพ เคนเฅเฅค)",
+ "descending": "เค
เคตเคฐเฅเคนเฅ",
+ "description": "เคธเฅเคเฅ เคฎเฅเค เคเคเคเคฎ เคเฅ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเคเฅค",
+ "inputItemSeparator": "เคเคจเคชเฅเค เคเคเคเคฎ เคตเคฟเคญเคพเคเค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "joinSeparatorDescription": "เคเคธ เคชเฅเคฐเคคเฅเค เคเคพ เคเคชเคฏเฅเค เคเฅเคฐเคฎเคฌเคฆเฅเคง เคธเฅเคเฅ เคฎเฅเค เคเคเคเคฎเฅเค เคเฅ เคฌเฅเค เคเฅเคกเคผเคจเฅ เคตเคพเคฒเฅ เคเฅ เคฐเฅเคช เคฎเฅเค เคเคฐเฅเคเฅค",
+ "orderDescription": "เคเค เคธเฅเคฐเฅเคเคฟเคเค เคเฅเคฐเคฎ เคเคพ เคเคฏเคจ เคเคฐเฅเค.",
+ "orderOptions": {
+ "decreasing": "เคเคเคคเฅ เคเฅเคฐเคฎ",
+ "increasing": "เคฌเคขเคผเคคเฅ เคเฅเคฐเคฎ"
+ },
+ "removeDuplicates": "เคกเฅเคชเฅเคฒเคฟเคเฅเค เคนเคเคพเคเค",
+ "removeDuplicatesDescription": "เคกเฅเคชเฅเคฒเคฟเคเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคนเคเคพเคเค.",
+ "removeEmpty": "เคเคพเคฒเฅ เคเคเคเคฎ เคนเคเคพเคเค",
+ "resultTitle": "เคเฅเคฐเคฎเคฌเคฆเฅเคง เคธเฅเคเฅ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเฅเคฐเคฎ เคฎเฅเค เคธเฅเคฐเฅเค เคเคฐเฅเค",
+ "sortAlphabetically": "เคตเคฐเฅเคฃเคพเคจเฅเคเฅเคฐเคฎเคฟเค เคฐเฅเคช เคธเฅ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "sortByLength": "เคฒเคเคฌเคพเค เคเฅ เค
เคจเฅเคธเคพเคฐ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "sortMethod": "เคธเฅเคฐเฅเค เคตเคฟเคงเคฟ",
+ "sortMethodDescription": "เคเค เคธเฅเคฐเฅเคเคฟเคเค เคตเคฟเคงเคฟ เคเคพ เคเคฏเคจ เคเคฐเฅเค.",
+ "sortNumerically": "เคธเคเคเฅเคฏเคพเคคเฅเคฎเค เคฐเฅเคช เคธเฅ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "sortOptions": {
+ "alphabetic": "เคตเคฐเฅเคฃเคพเคจเฅเคเฅเคฐเคฎ เคฎเฅเค เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "length": "เคฒเคเคฌเคพเค เคเฅ เค
เคจเฅเคธเคพเคฐ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "numeric": "เคธเคเคเฅเคฏเคพเคคเฅเคฎเค เคฐเฅเคช เคธเฅ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค"
+ },
+ "sortOrder": "เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเคจเฅ เคเคพ เคเฅเคฐเคฎ",
+ "sortedItemProperties": "เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคเคเคฎ เคเฅเคฃ",
+ "sortingOptions": "เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "splitOperators": {
+ "regex": {
+ "description": "เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคเฅ เคธเคพเคฅ เคเคจเคชเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคธเฅเคฎเคพเคเคเคฟเคค เคเคฐเฅเค.",
+ "title": "เคตเคฟเคญเคพเคเคจ เคเฅ เคฒเคฟเค เคฐเฅเคเฅเคเฅเคธ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค"
+ },
+ "symbol": {
+ "description": "เคเคจเคชเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคเคฟเคธเฅ เคตเคฐเฅเคฃ เคธเฅ เคธเฅเคฎเคพเคเคเคฟเคค เคเคฐเฅเค.",
+ "title": "เคตเคฟเคญเคพเคเคจ เคเฅ เคฒเคฟเค เคชเฅเคฐเคคเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค"
+ }
+ },
+ "splitSeparatorDescription": "เคเค เคธเฅเคฎเคพเคเคเค เคชเฅเคฐเคคเฅเค เคฏเคพ เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคธเฅเค เคเคฐเฅเค.",
+ "title": "เคธเฅเคเฅ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "trimWhitespace": "เคธเคซเฅเคฆ เคธเฅเคฅเคพเคจ เคเฅเคฐเคฟเคฎ เคเคฐเฅเค"
+ },
+ "truncate": {
+ "description": "เคธเฅเคเฅ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคฒเคเคฌเคพเค เคคเค เคเคพเคเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "lengthPlaceholder": "เคฒเคเคฌเคพเค",
+ "resultTitle": "เคเคพเคเฅ เคเค เคธเฅเคเฅ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคธเฅเคเฅ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคธเคเคเฅเคฏเคพ เคฎเฅเค เคเคเคเคฎ เคคเค เคเฅเคเคพ เคเคฐเฅเค",
+ "title": "เคธเฅเคเฅ เคเคพเคเฅเค",
+ "truncateFrom": "เคเคนเคพเค เคธเฅ เคเคพเคเฅเค",
+ "truncateFromEnd": "เค
เคเคค เคธเฅ",
+ "truncateFromStart": "เคถเฅเคฐเฅเคเคค เคธเฅ",
+ "truncateLength": "เคเคพเคเคจเฅ เคเฅ เคฒเคเคฌเคพเค",
+ "truncationOptions": "เคเคพเคเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช"
+ },
+ "unwrap": {
+ "characterPlaceholder": "เคตเคฐเฅเคฃ",
+ "description": "เคฒเคชเฅเคเฅ เคเค เคธเฅเคเฅ เคเฅ เคเฅเคฒเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "removeEmpty": "เคเคพเคฒเฅ เคเคเคเคฎ เคนเคเคพเคเค",
+ "resultTitle": "เคเฅเคฒเฅ เคเค เคธเฅเคเฅ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคธเคเคฐเคเคฟเคค เคชเฅเคฐเคพเคฐเฅเคช เคธเฅ เคธเฅเคเฅ เคเคเคเคฎ เคเฅเคฒเคจเคพ",
+ "title": "เคธเฅเคเฅ เคเฅเคฒเฅเค",
+ "unwrapCharacter": "เคเฅเคฒเคจเฅ เคเคพ เคตเคฐเฅเคฃ",
+ "unwrapOptions": "เคเฅเคฒเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช"
+ },
+ "wrap": {
+ "characterPlaceholder": "เคตเคฐเฅเคฃ",
+ "description": "เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคฒเคเคฌเคพเค เคฎเฅเค เคฒเคชเฅเคเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเฅ",
+ "joinSeparatorDescription": "เคฒเคฟเคชเคเฅ เคธเฅเคเฅ เคฎเฅเค เคถเคพเคฎเคฟเคฒ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคตเคฟเคญเคพเคเค",
+ "leftTextDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคเคเคเคฎ เคธเฅ เคชเคนเคฒเฅ เคเฅเคกเคผเคจเฅ เคเฅ เคฒเคฟเค เคชเคพเค ",
+ "removeEmptyItems": "เคเคพเคฒเฅ เคเคเคเคฎ เคนเคเคพเคเค",
+ "resultTitle": "เคฒเคชเฅเคเฅ เคเค เคธเฅเคเฅ",
+ "rightTextDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคเคเคเคฎ เคเฅ เคฌเคพเคฆ เคเฅเคกเคผเคจเฅ เคเฅ เคฒเคฟเค เคชเคพเค ",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคฎเคพเคจเคฆเคเคกเฅเค เคเฅ เคธเคพเคฅ เคฒเคชเฅเคเฅเค",
+ "splitByRegex": "เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคฆเฅเคตเคพเคฐเคพ เคตเคฟเคญเคพเคเคฟเคค",
+ "splitBySymbol": "เคชเฅเคฐเคคเฅเค เคฆเฅเคตเคพเคฐเคพ เคตเคฟเคญเคพเคเคฟเคค",
+ "splitOptions": "เคตเคฟเคญเคพเคเคฟเคค เคตเคฟเคเคฒเฅเคช",
+ "splitSeparatorDescription": "เคธเฅเคเฅ เคเฅ เคตเคฟเคญเคพเคเคฟเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคตเคฟเคญเคพเคเค",
+ "title": "เคธเฅเคเฅ เคฒเคชเฅเคเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคธเฅเคเฅ เคฎเฅเค เคชเฅเคฐเคคเฅเคฏเฅเค เคเคเคเคฎ เคเฅ เคชเคนเคฒเฅ เคเคฐ เคฌเคพเคฆ เคฎเฅเค เคเฅเคเฅเคธเฅเค เคเฅเคกเคผเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคฌเคพเคเค เคเคฐ เคฆเคพเคเค เคชเคเฅเคทเฅเค เคเฅ เคฒเคฟเค เค
เคฒเค-เค
เคฒเค เคเฅเคเฅเคธเฅเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค, เคเคฐ เคธเฅเคเฅ เคเฅ เคเฅเคธเฅ เคธเคเคธเคพเคงเคฟเคค เคเคฟเคฏเคพ เคเคพเค, เคเคธเฅ เคจเคฟเคฏเคเคคเฅเคฐเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคฏเคน เคธเฅเคเฅ เคเคเคเคฎ เคฎเฅเค เคเคฆเฅเคงเคฐเคฃ เคเคฟเคนเฅเคจ, เคเฅเคทเฅเค เค เคฏเคพ เค
เคจเฅเคฏ เคธเฅเคตเคฐเฅเคชเคฃ เคเฅเคกเคผเคจเฅ, เคตเคฟเคญเคฟเคจเฅเคจ เคธเฅเคตเคฐเฅเคชเฅเค เคเฅ เคฒเคฟเค เคกเฅเคเคพ เคคเฅเคฏเคพเคฐ เคเคฐเคจเฅ, เคฏเคพ เคธเคเคฐเคเคฟเคค เคเฅเคเฅเคธเฅเค เคฌเคจเคพเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเคเฅ เคนเฅเฅค",
+ "title": "เคธเฅเคเฅ เคฒเคชเฅเคเคจเคพ"
+ },
+ "widthPlaceholder": "เคเฅเคกเคผเคพเค",
+ "wrapCharacter": "เคฒเคชเฅเคเคจเฅ เคเคพ เคตเคฐเฅเคฃ",
+ "wrapOptions": "เคฒเคชเฅเคเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "wrapWidth": "เคฒเคชเฅเคเคจเฅ เคเฅ เคเฅเคกเคผเคพเค"
+ }
+}
diff --git a/public/locales/hi/number.json b/public/locales/hi/number.json
new file mode 100644
index 0000000..ff50bed
--- /dev/null
+++ b/public/locales/hi/number.json
@@ -0,0 +1,115 @@
+{
+ "arithmeticSequence": {
+ "commonDifference": "เคธเคพเคฎเคพเคจเฅเคฏ เค
เคเคคเคฐ",
+ "commonDifferenceDescription": "เคถเคฌเฅเคฆเฅเค เคเฅ เคฌเฅเค เคธเคพเคฎเคพเคจเฅเคฏ เค
เคเคคเคฐ (d)",
+ "description": "เค
เคเคเคเคฃเคฟเคคเฅเคฏ เค
เคจเฅเคเฅเคฐเคฎ เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเคเฅค",
+ "differencePlaceholder": "เค
เคเคคเคฐ",
+ "firstTerm": "เคชเคนเคฒเคพ เคชเคฆ",
+ "firstTermDescription": "เค
เคจเฅเคเฅเคฐเคฎ เคเคพ เคชเคนเคฒเคพ เคชเคฆ (aโ)",
+ "firstTermPlaceholder": "เคชเคฆ",
+ "inputTitle": "เค
เคจเฅเคเฅเคฐเคฎ",
+ "numberOfTerms": "เคชเคฆเฅเค เคเฅ เคธเคเคเฅเคฏเคพ",
+ "numberOfTermsDescription": "เคเคคเฅเคชเคจเฅเคจ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคชเคฆเฅเค เคเฅ เคธเคเคเฅเคฏเคพ (n)",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "resultTitle": "เค
เคเคเคเคฃเคฟเคคเฅเคฏ เค
เคจเฅเคเฅเคฐเคฎ",
+ "separatorDescription": "เคถเคฌเฅเคฆเฅเค เคเฅ เคฌเฅเค เคตเคฟเคญเคพเคเค",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "sequenceOptions": "เค
เคจเฅเคเฅเคฐเคฎ เคตเคฟเคเคฒเฅเคช",
+ "sequenceParameters": "เค
เคจเฅเคเฅเคฐเคฎ เคชเฅเคฐเคพเคฎเฅเคเคฐ",
+ "shortDescription": "เค
เคเคเคเคฃเคฟเคคเฅเคฏ เค
เคจเฅเคเฅเคฐเคฎ เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค",
+ "termsPlaceholder": "เคธเคเคเฅเคฏเคพ",
+ "title": "เค
เคเคเคเคฃเคฟเคคเฅเคฏ เค
เคจเฅเคเฅเคฐเคฎ",
+ "toolInfo": {
+ "description": "เค
เคเคเคเคฃเคฟเคคเฅเคฏ เค
เคจเฅเคเฅเคฐเคฎ เคธเคเคเฅเคฏเคพเคเค เคเคพ เคเค เคเคธเคพ เค
เคจเฅเคเฅเคฐเคฎ เคนเฅเคคเคพ เคนเฅ เคเคนเคพเค เคชเฅเคฐเคคเฅเคฏเฅเค เคเฅเคฐเคฎเคพเคเคค เคชเคฆ เคเคพ เค
เคเคคเคฐ เคธเฅเคฅเคฟเคฐ เคนเฅเคคเคพ เคนเฅเฅค เคเคธ เคธเฅเคฅเคฟเคฐ เค
เคเคคเคฐ เคเฅ เคธเคพเคฐเฅเคต เค
เคเคคเคฐ เคเคนเคคเฅ เคนเฅเคเฅค เคชเคนเคฒเคพ เคชเคฆ (aโ) เคเคฐ เคธเคพเคฐเฅเคต เค
เคเคคเคฐ (d) เคฆเคฟเค เคนเฅเคจเฅ เคชเคฐ, เคชเฅเคฐเคคเฅเคฏเฅเค เคชเคฆ เคเฅ เคชเคฟเคเคฒเฅ เคชเคฆ เคฎเฅเค เคธเคพเคฐเฅเคต เค
เคเคคเคฐ เคเฅเคกเคผเคเคฐ เคเฅเคเคพเคค เคเคฟเคฏเคพ เคเคพ เคธเคเคคเคพ เคนเฅเฅค",
+ "title": "เค
เคเคเคเคฃเคฟเคคเฅเคฏ เค
เคจเฅเคเฅเคฐเคฎ เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "generate": {
+ "arithmeticSequenceOption": "เค
เคเคเคเคฃเคฟเคคเฅเคฏ เค
เคจเฅเคเฅเคฐเคฎ เคตเคฟเคเคฒเฅเคช",
+ "countNumbers": "เคธเคเคเฅเคฏเคพเคเค เคเฅ เคธเคเคเฅเคฏเคพ",
+ "countPlaceholder": "เคธเคเคเฅเคฏเคพ",
+ "description": "เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคฎเคพเคชเคฆเคเคกเฅเค เคเฅ เค
เคจเฅเคธเคพเคฐ เคธเคเคเฅเคฏเคพเคเค เคเฅ เคธเฅเคเฅ เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเคเฅค",
+ "generationOptions": "เคเคคเฅเคชเคจเฅเคจ เคเคฐเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "inputTitle": "เคเคคเฅเคชเคจเฅเคจ เคเฅ เคเค เคธเคเคเฅเคฏเคพเคเค",
+ "numberOfElementsDescription": "เค
เคจเฅเคเฅเคฐเคฎ เคฎเฅเค เคคเคคเฅเคตเฅเค เคเฅ เคธเคเคเฅเคฏเคพ.",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "resultTitle": "เคธเคเคเฅเคฏเคพเคเค เคเฅ เคธเฅเคเฅ",
+ "separator": "เคธเฅเคชเคฐเฅเคเคฐ",
+ "separatorDescription": "เคเคธ เคตเคฐเฅเคฃ เคฆเฅเคตเคพเคฐเคพ เค
เคเคเคเคฃเคฟเคคเฅเคฏ เค
เคจเฅเคเฅเคฐเคฎ เคฎเฅเค เคคเคคเฅเคตเฅเค เคเฅ เค
เคฒเค เคเคฐเฅเคเฅค",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคถเฅเคฐเฅเคฃเคฟเคฏเฅเค เคฎเฅเค เคฏเคพเคฆเฅเคเฅเคเคฟเค เคธเคเคเฅเคฏเคพเคเค เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค",
+ "startNumber": "เคถเฅเคฐเฅเคเคคเฅ เคธเคเคเฅเคฏเคพ",
+ "startPlaceholder": "เคธเคเคเฅเคฏเคพ",
+ "startSequenceDescription": "เคเคธ เคธเคเคเฅเคฏเคพ เคธเฅ เค
เคจเฅเคเฅเคฐเคฎ เคชเฅเคฐเคพเคฐเคเคญ เคเคฐเฅเค.",
+ "stepDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคคเคคเฅเคต เคเฅ เคเคธ เคฎเคพเคคเฅเคฐเคพ เคธเฅ เคฌเคขเคผเคพเคเค",
+ "stepPlaceholder": "เคฎเคพเคจ",
+ "stepValue": "เคเคฐเคฃ เคฎเคพเคจ",
+ "title": "เคธเคเคเฅเคฏเคพเคเค เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เค
เคจเฅเคเฅเคฒเคจ เคฏเฅเคเฅเคฏ เคฎเคพเคชเคฆเคเคกเฅเค เคเฅ เคธเคพเคฅ เคธเคเคเฅเคฏเคพเคเค เคเคพ เคเค เคเฅเคฐเคฎ เคฌเคจเคพเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคชเฅเคฐเคพเคฐเคเคญเคฟเค เคฎเคพเคจ, เคเคฐเคฃ เคเคเคพเคฐ เคเคฐ เคคเคคเฅเคตเฅเค เคเฅ เคธเคเคเฅเคฏเคพ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "title": "เคธเคเคเฅเคฏเคพเคเค เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค"
+ }
+ },
+ "ohmsLaw": {
+ "description": "เคตเฅเคฒเฅเคเฅเค, เคงเคพเคฐเคพ เคเคฐ เคชเฅเคฐเคคเคฟเคฐเฅเคง เคเฅ เคเคฃเคจเคพ เคเคฐเคคเคพ เคนเฅ",
+ "longDescription": "เคฏเคน เคเฅเคฒเคเฅเคฒเฅเคเคฐ เคเคฎ เคเฅ เคจเคฟเคฏเคฎ (V = I ร R) เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคคเฅเคจ เคตเคฟเคฆเฅเคฏเฅเคค เคชเฅเคฐเคพเคเคฒเฅเค เคฎเฅเค เคธเฅ เคเคฟเคธเฅ เคเค เคเคพ เคจเคฟเคฐเฅเคงเคพเคฐเคฃ เคเคฐเคคเคพ เคนเฅ, เคเคฌ เค
เคจเฅเคฏ เคฆเฅ เคเฅเคเคพเคค เคนเฅเคเฅค เคเคฎ เคเคพ เคจเคฟเคฏเคฎ เคตเคฟเคฆเฅเคฏเฅเคค เคเคเคเฅเคจเคฟเคฏเคฐเคฟเคเค เคเคพ เคเค เคฎเฅเคฒเคญเฅเคค เคธเคฟเคฆเฅเคงเคพเคเคค เคนเฅ เคเฅ เคตเฅเคฒเฅเคเฅเค (V), เคงเคพเคฐเคพ (I), เคเคฐ เคชเฅเคฐเคคเคฟเคฐเฅเคง (R) เคเฅ เคฌเฅเค เคธเคเคฌเคเคง เคเคพ เคตเคฐเฅเคฃเคจ เคเคฐเคคเคพ เคนเฅเฅค เคฏเคน เคเคชเคเคฐเคฃ เคเคฒเฅเคเฅเคเฅเคฐเฅเคจเคฟเคเฅเคธ เคเฅ เคถเฅเคเฅเคจเฅเค, เคตเคฟเคฆเฅเคฏเฅเคค เคเคเคเฅเคจเคฟเคฏเคฐเฅเค เคเคฐ เคธเคฐเฅเคเคฟเค เคชเคฐ เคเคพเคฎ เคเคฐเคจเฅ เคตเคพเคฒเฅ เคเคพเคคเฅเคฐเฅเค เคเฅ เคฒเคฟเค เคเคจเคเฅ เคตเคฟเคฆเฅเคฏเฅเคค เคกเคฟเคเคผเคพเคเคจเฅเค เคฎเฅเค เค
เคเฅเคเคพเคค เคฎเคพเคจเฅเค เคเฅ เคถเฅเคเฅเคฐเคคเคพ เคธเฅ เคนเคฒ เคเคฐเคจเฅ เคนเฅเคคเฅ เคเคตเคถเฅเคฏเค เคนเฅเฅค",
+ "shortDescription": "เคเคฎ เคเฅ เคจเคฟเคฏเคฎ เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคตเคฟเคฆเฅเคฏเฅเคค เคชเคฐเคฟเคชเคฅเฅเค เคฎเฅเค เคตเฅเคฒเฅเคเฅเค, เคงเคพเคฐเคพ เคฏเคพ เคชเฅเคฐเคคเคฟเคฐเฅเคง เคเฅ เคเคฃเคจเคพ เคเคฐเฅเค",
+ "title": "เคเคฎ เคเคพเคจเฅเคจ"
+ },
+ "slackline": {
+ "description": "เคธเฅเคฒเฅเคเคฒเคพเคเคจ เคฎเฅเค เคคเคจเคพเคต เคเฅ เคเคฃเคจเคพ เคเคฐเคคเคพ เคนเฅ",
+ "longDescription": "เคฏเคน เคเฅเคฒเคเฅเคฒเฅเคเคฐ เคฐเคธเฅเคธเฅ เคเฅ เคเฅเคเคฆเฅเคฐ เคฎเฅเค เคญเคพเคฐ เคฎเคพเคจเคคเคพ เคนเฅ",
+ "shortDescription": "เคธเฅเคฒเฅเคเคฒเคพเคเคจ เคฏเคพ เคเฅเคฒเฅเคฅเคฒเคพเคเคจ เคเฅ เค
เคจเฅเคฎเคพเคจเคฟเคค เคคเคจเคพเคต เคเฅ เคเคฃเคจเคพ เคเคฐเฅเคเฅค เคธเฅเคฐเคเฅเคทเคพ เคเฅ เคฒเคฟเค เคเคธ เคชเคฐ เคจเคฟเคฐเฅเคญเคฐ เคจ เคฐเคนเฅเคเฅค",
+ "title": "เคธเฅเคฒเฅเคเคฒเคพเคเคจ เคคเคจเคพเคต"
+ },
+ "sphereArea": {
+ "description": "เคเฅเคฒเฅ เคเคพ เคเฅเคทเฅเคคเฅเคฐเคซเคฒ",
+ "longDescription": "เคฏเคน เคเฅเคฒเคเฅเคฒเฅเคเคฐ เคธเฅเคคเฅเคฐ A = 4ฯrยฒ เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคเค เคเฅเคฒเฅ เคเคพ เคชเฅเคทเฅเค เฅเคฏ เคเฅเคทเฅเคคเฅเคฐเคซเคฒ เคเฅเคเคพเคค เคเคฐเคคเคพ เคนเฅเฅค เคเคช เคชเฅเคทเฅเค เฅเคฏ เคเฅเคทเฅเคคเฅเคฐเคซเคฒ เคเฅเคเคพเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคคเฅเคฐเคฟเคเฅเคฏเคพ เคฆเคฐเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค เคฏเคพ เคเคตเคถเฅเคฏเค เคคเฅเคฐเคฟเคเฅเคฏเคพ เคเฅ เคเคฃเคจเคพ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคชเฅเคทเฅเค เฅเคฏ เคเฅเคทเฅเคคเฅเคฐเคซเคฒ เคฆเคฐเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคฏเคน เคเคชเคเคฐเคฃ เคเฅเคฏเคพเคฎเคฟเคคเคฟ เคเฅ เคเคพเคคเฅเคฐเฅเค, เคเฅเคฒเคพเคเคพเคฐ เคตเคธเฅเคคเฅเคเค เคชเคฐ เคเคพเคฎ เคเคฐเคจเฅ เคตเคพเคฒเฅ เคเคเคเฅเคจเคฟเคฏเคฐเฅเค, เคเคฐ เคเฅเคฒเคพเคเคพเคฐ เคธเคคเคนเฅเค เคธเฅ เคธเคเคฌเคเคงเคฟเคค เคเคฃเคจเคพเคเค เคเคฐเคจเฅ เคตเคพเคฒเฅ เคเคฟเคธเฅ เคญเฅ เคตเฅเคฏเคเฅเคคเคฟ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเคเฅ เคนเฅเฅค",
+ "shortDescription": "เคเค เคเฅเคฒเฅ เคเฅ เคธเคคเคน เคเฅเคทเฅเคคเฅเคฐ เคเฅ เคเคฃเคจเคพ เคเคธเคเฅ เคคเฅเคฐเคฟเคเฅเคฏเคพ เคเฅ เคเคงเคพเคฐ เคชเคฐ เคเคฐเฅเค",
+ "title": "เคเฅเคฒเฅ เคเคพ เคเฅเคทเฅเคคเฅเคฐเคซเคฒ"
+ },
+ "sphereVolume": {
+ "description": "เคเฅเคฒเฅ เคเคพ เคเคฏเคคเคจ",
+ "longDescription": "เคฏเคน เคเฅเคฒเคเฅเคฒเฅเคเคฐ เคธเฅเคคเฅเคฐ V = (4/3)ฯrยณ เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคเค เคเฅเคฒเฅ เคเคพ เคเคฏเคคเคจ เคเฅเคเคพเคค เคเคฐเคคเคพ เคนเฅเฅค เคเคช เคเคฏเคคเคจ เคเฅเคเคพเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคคเฅเคฐเคฟเคเฅเคฏเคพ เคฏเคพ เคตเฅเคฏเคพเคธ เคฆเคฐเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค, เคฏเคพ เคเคตเคถเฅเคฏเค เคคเฅเคฐเคฟเคเฅเคฏเคพ เคเฅเคเคพเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคฏเคคเคจ เคฆเคฐเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคฏเคน เคเคชเคเคฐเคฃ เคญเฅเคคเคฟเคเฅ, เคเคเคเฅเคจเคฟเคฏเคฐเคฟเคเค เคเคฐ เคตเคฟเคจเคฟเคฐเฅเคฎเคพเคฃ เคเฅเคธเฅ เคเฅเคทเฅเคคเฅเคฐเฅเค เคฎเฅเค เคเฅเคฒเคพเคเคพเคฐ เคตเคธเฅเคคเฅเคเค เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคตเคพเคฒเฅ เคเคพเคคเฅเคฐเฅเค, เคเคเคเฅเคจเคฟเคฏเคฐเฅเค เคเคฐ เคชเฅเคถเฅเคตเคฐเฅเค เคเฅ เคฒเคฟเค เคเคชเคฏเฅเคเฅ เคนเฅเฅค",
+ "shortDescription": "เคคเฅเคฐเคฟเคเฅเคฏเคพ เคฏเคพ เคตเฅเคฏเคพเคธ เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคเค เคเฅเคฒเฅ เคเคพ เคเคฏเคคเคจ เคเฅเคเคพเคค เคเคฐเฅเค",
+ "title": "เคเฅเคฒเฅ เคเคพ เคเคฏเคคเคจ"
+ },
+ "sum": {
+ "description": "เคธเคเคเฅเคฏเคพเคเค เคเฅ เคธเฅเคเฅ เคเคพ เคฏเฅเค เคเคฐเฅเคเฅค",
+ "extractionTypes": {
+ "delimiter": {
+ "description": "เคฏเคนเคพเค เคธเคเคเฅเคฏเคพ เคตเคฟเคญเคพเคเค เคเฅ เค
เคจเฅเคเฅเคฒเคฟเคค เคเคฐเฅเคเฅค (เคกเคฟเคซเคผเฅเคฒเฅเค เคฐเฅเคช เคธเฅ เคเค เคฒเคพเคเคจ เคฌเฅเคฐเฅเคเฅค)",
+ "title": "เคธเคเคเฅเคฏเคพ เคธเฅเคฎเคพเคเคเค"
+ },
+ "smart": {
+ "description": "เคเคจเคชเฅเค เคฎเฅเค เคธเคเคเฅเคฏเคพเคเค เคเคพ เคธเฅเคตเคคเค เคชเคคเคพ เคฒเคเคพเคจเคพ.",
+ "title": "เคธเฅเคฎเคพเคฐเฅเค เคฏเฅเค"
+ }
+ },
+ "ignoreNonNumbers": "เคเฅเคฐ-เคธเคเคเฅเคฏเคพเคคเฅเคฎเค เคฎเคพเคจ เค
เคจเคฆเฅเคเคพ เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค เคธเคเคเฅเคฏเคพเคเค",
+ "numberExtraction": "เคธเคเคเฅเคฏเคพ เคจเคฟเคทเฅเคเคฐเฅเคทเคฃ",
+ "printRunningSum": "เคเคฒ เคฏเฅเค เคชเฅเคฐเคฟเคเค เคเคฐเฅเค",
+ "printRunningSumDescription": "เคเคฐเคฃ เคฆเคฐ เคเคฐเคฃ เคเคฃเคจเคพ เคเคฐเคเฅ เคฏเฅเค เคชเฅเคฐเคฆเคฐเฅเคถเคฟเคค เคเคฐเฅเคเฅค",
+ "resultFormat": "เคชเคฐเคฟเคฃเคพเคฎ เคชเฅเคฐเคพเคฐเฅเคช",
+ "resultTitle": "เคฏเฅเค",
+ "runningSum": "เคเคฒ เคฏเฅเค",
+ "separatorPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "shortDescription": "เคธเคเคเฅเคฏเคพเคเค เคเคพ เคฏเฅเค เคเฅเคเคพเคค เคเฅเคเคฟเค",
+ "showAverage": "เคเคธเคค เคฆเคฟเคเคพเคเค",
+ "showCount": "เคเคฃเคจเคพ เคฆเคฟเคเคพเคเค",
+ "showSum": "เคฏเฅเค เคฆเคฟเคเคพเคเค",
+ "sumOptions": "เคเฅเคกเคผเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "title": "เคธเคเคเฅเคฏเคพเคเค เคเฅเคกเคผเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคธเคเคเฅเคฏเคพเคเค เคเฅ เคธเคฎเฅเคน เคเคพ เคฏเฅเค เคจเคฟเคเคพเคฒเคจเฅ เคเฅ เคฒเคฟเค เคเค เคเคจเคฒเคพเคเคจ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพ เคนเฅเฅค เคเคช เคธเคเคเฅเคฏเคพเคเค เคเฅ เค
เคฒเฅเคชเคตเคฟเคฐเคพเคฎ, เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ เคฏเคพ เคเคฟเคธเฅ เค
เคจเฅเคฏ เคตเคฐเฅเคฃ (เคฒเคพเคเคจ เคฌเฅเคฐเฅเค เคธเคนเคฟเคค) เคธเฅ เค
เคฒเค เคเคฐเคเฅ เคฆเคฐเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคเคช เคชเคพเค เฅเคฏ เคกเฅเคเคพ เคเคพ เคเค เค
เคเคถ เคญเฅ เคชเฅเคธเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค เคเคฟเคธเคฎเฅเค เคตเฅ เคธเคเคเฅเคฏเคพเคคเฅเคฎเค เคฎเคพเคจ เคนเฅเค เคเคฟเคจเคเคพ เคเคช เคฏเฅเค เคเคฐเคจเคพ เคเคพเคนเคคเฅ เคนเฅเค เคเคฐ เคเคชเคฏเฅเคเคฟเคคเคพ เคเคจเฅเคนเฅเค เคจเคฟเคเคพเคฒเคเคฐ เคเคจเคเคพ เคฏเฅเค เคเฅเคเคพเคค เคเคฐ เคฒเฅเคเฅเฅค",
+ "title": "เคธเคเคเฅเคฏเคพ เคฏเฅเค เคเฅเคฒเคเฅเคฒเฅเคเคฐ เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "voltageDropInWire": {
+ "description": "2 เคเคเคกเคเฅเคเคฐ เคเฅเคฌเคฒ เคฎเฅเค เคฐเคพเคเคเคก เคเฅเคฐเคฟเคช เคตเฅเคฒเฅเคเฅเค เคเคฐ เคฌเคฟเคเคฒเฅ เคนเคพเคจเคฟ เคเฅ เคเคฃเคจเคพ เคเคฐเคคเคพ เคนเฅ",
+ "longDescription": "เคฏเคน เคเฅเคฒเคเฅเคฒเฅเคเคฐ เคฆเฅ-เคเคพเคฒเค เคตเคฟเคฆเฅเคฏเฅเคค เคเฅเคฌเคฒ เคฎเฅเค เคตเฅเคฒเฅเคเฅเค เคกเฅเคฐเฅเคช เคเคฐ เคชเคพเคตเคฐ เคฒเฅเคธ เคเคพ เคชเคคเคพ เคฒเคเคพเคจเฅ เคฎเฅเค เคฎเคฆเคฆ เคเคฐเคคเคพ เคนเฅเฅค เคฏเคน เคเฅเคฌเคฒ เคเฅ เคฒเคเคฌเคพเค, เคคเคพเคฐ เคเฅ เคเฅเค (เค
เคจเฅเคชเฅเคฐเคธเฅเคฅ เคเฅเคทเฅเคคเฅเคฐ), เคชเคฆเคพเคฐเฅเคฅ เคเฅ เคชเฅเคฐเคคเคฟเคฐเฅเคงเคเคคเคพ เคเคฐ เคงเคพเคฐเคพ เคชเฅเคฐเคตเคพเคน เคเฅ เคงเฅเคฏเคพเคจ เคฎเฅเค เคฐเคเคคเคพ เคนเฅเฅค เคฏเคน เคเคชเคเคฐเคฃ เคฐเคพเคเคเคก-เคเฅเคฐเคฟเคช เคตเฅเคฒเฅเคเฅเค เคกเฅเคฐเฅเคช, เคเฅเคฌเคฒ เคเฅ เคเฅเคฒ เคชเฅเคฐเคคเคฟเคฐเฅเคง เคเคฐ เคเคทเฅเคฎเคพ เคเฅ เคฐเฅเคช เคฎเฅเค เคเฅเคทเคฏ เคนเฅเคจเฅ เคตเคพเคฒเฅ เคถเคเฅเคคเคฟ เคเฅ เคเคฃเคจเคพ เคเคฐเคคเคพ เคนเฅเฅค เคฏเคน เคตเคฟเคถเฅเคท เคฐเฅเคช เคธเฅ เคตเคฟเคฆเฅเคฏเฅเคค เคเคเคเฅเคจเคฟเคฏเคฐเฅเค, เคเคฒเฅเคเฅเคเฅเคฐเฅเคถเคฟเคฏเคจเฅเค เคเคฐ เคถเฅเคเคฟเคฏเคพ เคฒเฅเคเฅเค เคเฅ เคฒเคฟเค เคเคชเคฏเฅเคเฅ เคนเฅ, เคเคฌ เคตเฅ เคตเคฟเคฆเฅเคฏเฅเคค เคชเฅเคฐเคฃเคพเคฒเคฟเคฏเฅเค เคเฅ เคกเคฟเคเคผเคพเคเคจ เคเคฐเคคเฅ เคนเฅเค เคคเคพเคเคฟ เคฏเคน เคธเฅเคจเคฟเคถเฅเคเคฟเคค เคเคฟเคฏเคพ เคเคพ เคธเคเฅ เคเคฟ เคตเฅเคฒเฅเคเฅเค เคเคพ เคธเฅเคคเคฐ เคฒเฅเคก เคชเคฐ เคธเฅเคตเฅเคเคพเคฐเฅเคฏ เคธเฅเคฎเคพ เคเฅ เคญเฅเคคเคฐ เคฐเคนเฅเฅค",
+ "shortDescription": "เคฒเคเคฌเคพเค, เคธเคพเคฎเคเฅเคฐเฅ เคเคฐ เคงเคพเคฐเคพ เคเฅ เคเคงเคพเคฐ เคชเคฐ เคตเคฟเคฆเฅเคฏเฅเคค เคเฅเคฌเคฒเฅเค เคฎเฅเค เคตเฅเคฒเฅเคเฅเค เคกเฅเคฐเฅเคช เคเคฐ เคฌเคฟเคเคฒเฅ เคนเคพเคจเคฟ เคเฅ เคเคฃเคจเคพ เคเคฐเฅเค",
+ "title": "เคเฅเคฌเคฒ เคฎเฅเค เคฐเคพเคเคเคก เคเฅเคฐเคฟเคช เคตเฅเคฒเฅเคเฅเค เคกเฅเคฐเฅเคช"
+ }
+}
diff --git a/public/locales/hi/pdf.json b/public/locales/hi/pdf.json
new file mode 100644
index 0000000..33b2524
--- /dev/null
+++ b/public/locales/hi/pdf.json
@@ -0,0 +1,159 @@
+{
+ "compressPdf": {
+ "compressedFileSize": "เคธเคเคชเฅเคกเคผเคฟเคค เคซเคผเคพเคเคฒ เคเคพ เคเคเคพเคฐ",
+ "compressingPdf": "เคชเฅเคกเฅเคเคซ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฟเคฏเคพ เคเคพ เคฐเคนเคพ เคนเฅ...",
+ "compressionLevel": "เคธเคเคชเฅเคกเคผเคจ เคธเฅเคคเคฐ",
+ "compressionOptions": "เคธเคเคชเฅเคกเคผเคจ เคตเคฟเคเคฒเฅเคช",
+ "compressionSettings": "เคธเคเคชเฅเคกเคผเคจ เคธเฅเคเคฟเคเคเฅเคธ",
+ "description": "PDF เคซเคผเคพเคเคฒ เคเคเคพเคฐ เคเคฎ เคเคฐเฅเคเฅค",
+ "errorCompressingPdf": "เคชเฅเคกเฅเคเคซ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒ: {{error}}",
+ "errorReadingPdf": "PDF เคซเคผเคพเคเคฒ เคชเคขเคผเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒเฅค เคเฅเคชเคฏเคพ เคธเฅเคจเคฟเคถเฅเคเคฟเคค เคเคฐเฅเค เคเคฟ เคฏเคน เคเค เคฎเคพเคจเฅเคฏ PDF เคนเฅเฅค",
+ "fileSize": "เคฎเฅเคฒ เคซเคผเคพเคเคฒ เคเคเคพเคฐ",
+ "high": "เคเคเฅเค",
+ "highCompression": "เคเคเฅเค เคธเคเคชเฅเคกเคผเคจ",
+ "highCompressionDescription": "เคเฅเค เคเฅเคฃเคตเคคเฅเคคเคพ เคนเคพเคจเคฟ เคเฅ เคธเคพเคฅ เค
เคงเคฟเคเคคเคฎ เคซเคผเคพเคเคฒ เคเคเคพเคฐ เคฎเฅเค เคเคฎเฅ",
+ "imageQuality": "เคเคตเคฟ เคเฅเคฃเคตเคคเฅเคคเคพ",
+ "inputTitle": "เคเคจเคชเฅเค PDF",
+ "low": "เคเคฎ",
+ "lowCompression": "เคเคฎ เคธเคเคชเฅเคกเคผเคจ",
+ "lowCompressionDescription": "เคจเฅเคฏเฅเคจเคคเคฎ เคเฅเคฃเคตเคคเฅเคคเคพ เคนเคพเคจเคฟ เคเฅ เคธเคพเคฅ เคซเคผเคพเคเคฒ เคเคเคพเคฐ เคเฅ เคฅเฅเคกเคผเคพ เคเคฎ เคเคฐเฅเค",
+ "medium": "เคฎเคงเฅเคฏเคฎ",
+ "mediumCompression": "เคฎเคงเฅเคฏเคฎ เคธเคเคชเฅเคกเคผเคจ",
+ "mediumCompressionDescription": "เคซเคผเคพเคเคฒ เคเคเคพเคฐ เคเคฐ เคเฅเคฃเคตเคคเฅเคคเคพ เคเฅ เคฌเฅเค เคธเคเคคเฅเคฒเคจ",
+ "pages": "เคชเฅเคทเฅเค เฅเค เคเฅ เคธเคเคเฅเคฏเคพ",
+ "qualityPlaceholder": "เคเฅเคฃเคตเคคเฅเคคเคพ (1-100)",
+ "removeMetadata": "เคฎเฅเคเคพเคกเฅเคเคพ เคนเคเคพเคเค",
+ "resultTitle": "เคธเคเคชเฅเคกเคผเคฟเคค PDF",
+ "shortDescription": "เค
เคชเคจเฅ เคฌเฅเคฐเคพเคเคเคผเคฐ เคฎเฅเค เคธเฅเคฐเคเฅเคทเคฟเคค เคฐเฅเคช เคธเฅ เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒเฅเค เคเฅ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค",
+ "title": "PDF เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค"
+ },
+ "editor": {
+ "description": "เคเคจเฅเคเฅเคถเคจ, เคซเคผเฅเคฐเฅเคฎ-เคซเคผเคฟเคฒ, เคนเคพเคเคฒเคพเคเค เคเคฐ เคจเคฟเคฐเฅเคฏเคพเคค เคเฅเคทเคฎเคคเคพเคเค เคตเคพเคฒเคพ เคเคจเฅเคจเคค PDF เคธเคเคชเคพเคฆเคเฅค เคเฅเคเฅเคธเฅเค เคเคเคธเคฐเฅเคถเคจ, เคกเฅเคฐเฅเคเคเค, เคนเคพเคเคฒเคพเคเคเคฟเคเค, เคนเคธเฅเคคเคพเคเฅเคทเคฐ เคเคฐ เคซเคผเฅเคฐเฅเคฎ เคญเคฐเคจเฅ เคเฅเคธเฅ เคชเฅเคถเฅเคตเคฐ-เคธเฅเคคเคฐเฅเคฏ เคเฅเคฒ เคธเฅ เคธเฅเคงเฅ เคฌเฅเคฐเคพเคเคเคผเคฐ เคฎเฅเค เค
เคชเคจเฅ PDF เคซเคผเคพเคเคฒเฅเค เคเฅ เคธเคเคชเคพเคฆเคฟเคค เคเคฐเฅเคเฅค",
+ "shortDescription": "เคเคจเฅเคจเคค เคเคจเฅเคเฅเคถเคจ, เคนเคธเฅเคคเคพเคเฅเคทเคฐ เคเคฐ เคธเคเคชเคพเคฆเคจ เคเฅเคฒ เคเฅ เคธเคพเคฅ PDF เคธเคเคชเคพเคฆเคฟเคค เคเคฐเฅเค",
+ "title": "เคชเฅเคกเฅเคเคซ เคธเคเคชเคพเคฆเค"
+ },
+ "merge": {
+ "inputTitle": "เคเคจเคชเฅเค PDF",
+ "loadingText": "เคชเฅเคทเฅเค เคจเคฟเคเคพเคฒเคจเคพ",
+ "resultTitle": "เคเคเคเคชเฅเค เคฎเคฐเฅเค เคเคฟเคฏเคพ เคเคฏเคพ PDF",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคเค PDF เคซเคผเคพเคเคฒเฅเค เคเฅ เคเค เคนเฅ เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคฎเฅเค เคฎเคฐเฅเค เคเคฐเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคธ เคเฅเคฒ เคเคพ เคเคธเฅเคคเฅเคฎเคพเคฒ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค, เคฌเคธ เคเคจ PDF เคซเคผเคพเคเคฒเฅเค เคเฅ เค
เคชเคฒเฅเคก เคเคฐเฅเค เคเคฟเคจเฅเคนเฅเค เคเคช เคฎเคฐเฅเค เคเคฐเคจเคพ เคเคพเคนเคคเฅ เคนเฅเคเฅค เคซเคฟเคฐ เคฏเคน เคเฅเคฒ เคเคจเคชเฅเค เคซเคผเคพเคเคฒเฅเค เคเฅ เคธเคญเฅ เคชเฅเคทเฅเค เฅเค เคเฅ เคเค เคนเฅ PDF เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคฎเฅเค เคฎเคฐเฅเค เคเคฐ เคฆเฅเคเคพเฅค",
+ "title": "เคฎเคฐเฅเค เคชเฅเคกเฅเคเคซ เคเฅเคฒ เคเคพ เคเคชเคฏเฅเค เคเฅเคธเฅ เคเคฐเฅเค?"
+ }
+ },
+ "mergePdf": {
+ "customOrder": "เคเคธเฅเคเคฎ เคเฅเคฐเคฎ",
+ "description": "เคเค PDF เคซเคผเคพเคเคฒเฅเค เคเฅ เคเค เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคฎเฅเค เคเฅเคกเคผเฅเคเฅค",
+ "includeBookmarks": "เคฌเฅเคเคฎเคพเคฐเฅเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค PDF เคซเคผเคพเคเคฒเฅเค",
+ "mergeOptions": "เคฎเคฐเฅเค เคตเคฟเคเคฒเฅเคช",
+ "mergeOrder": "เคฎเคฐเฅเค เคเฅเคฐเคฎ",
+ "mergingPdfs": "PDF เคเฅ เคฎเคฐเฅเค เคเคฐเคจเคพ",
+ "orderByFilename": "เคซเคผเคพเคเคฒ เคจเคพเคฎ เคเฅ เค
เคจเฅเคธเคพเคฐ เคเฅเคฐเคฎ",
+ "orderByUpload": "เค
เคชเคฒเฅเคก เคเฅเคฐเคฎ เคเฅ เค
เคจเฅเคธเคพเคฐ",
+ "pdfOptions": "เคชเฅเคกเฅเคเคซ เคตเคฟเคเคฒเฅเคช",
+ "resultTitle": "เคฎเคฐเฅเค เคเคฟเคฏเคพ เคเคฏเคพ PDF",
+ "shortDescription": "เคเค เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเค เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคฎเฅเค เคฎเคฐเฅเค เคเคฐเฅเค",
+ "sortByFileName": "เคซเคผเคพเคเคฒ เคจเคพเคฎ เคเฅ เค
เคจเฅเคธเคพเคฐ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "sortByFileNameDescription": "PDF เคเฅ เคซเคผเคพเคเคฒ เคจเคพเคฎ เคเฅ เค
เคจเฅเคธเคพเคฐ เคตเคฐเฅเคฃเคพเคจเฅเคเฅเคฐเคฎ เคฎเฅเค เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "sortByUploadOrder": "เค
เคชเคฒเฅเคก เคเฅเคฐเคฎ เคเฅ เค
เคจเฅเคธเคพเคฐ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "sortByUploadOrderDescription": "PDF เคเฅ เคเคธเฅ เคเฅเคฐเคฎ เคฎเฅเค เคฐเคเฅเค เคเคฟเคธ เคเฅเคฐเคฎ เคฎเฅเค เคเคจเฅเคนเฅเค เค
เคชเคฒเฅเคก เคเคฟเคฏเคพ เคเคฏเคพ เคฅเคพ",
+ "title": "PDF เคฎเคฐเฅเค เคเคฐเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคเค PDF เคซเคผเคพเคเคฒเฅเค เคเฅ เคเค เคนเฅ เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคฎเฅเค เคธเคเคฏเฅเคเคฟเคค เคเคฐเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช PDF เคซเคผเคพเคเคฒเฅเค เคเฅ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเคจเฅ เคเคพ เคคเคฐเฅเคเคพ เคเฅเคจ เคธเคเคคเฅ เคนเฅเค เคเคฐ เคฏเคน เคเฅเคฒ เคเคจเฅเคนเฅเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเฅเคฐเคฎ เคฎเฅเค เคฎเคฐเฅเค เคเคฐ เคฆเฅเคเคพเฅค",
+ "title": "เคชเฅเคกเฅเคเคซ เคซเคพเคเคฒเฅเค เคเฅ เคฎเคฐเฅเค เคเคฐเฅเค"
+ }
+ },
+ "pdfToEpub": {
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "PDF เคฆเคธเฅเคคเคพเคตเฅเคเคผเฅเค เคเฅ EPUB เคซเคผเคพเคเคฒเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "extractImages": "เคเคตเคฟเคฏเคพเค เคจเคฟเคเคพเคฒเฅเค",
+ "generateToc": "เคธเคพเคฎเคเฅเคฐเฅ เคคเคพเคฒเคฟเคเคพ เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค PDF",
+ "preserveFormatting": "เคซเฅเคฐเฅเคฎเฅเคเคฟเคเค เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "resultTitle": "EPUB เคซเคผเคพเคเคฒ",
+ "shortDescription": "เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเคชเฅเคฏเฅเคฌเฅ เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเค",
+ "title": "PDF เคธเฅ EPUB"
+ },
+ "pdfToPng": {
+ "description": "เคชเฅเคกเฅเคเคซ เคฆเคธเฅเคคเคพเคตเฅเคเฅเค เคเฅ เคชเฅเคเคจเคเฅ เคชเฅเคจเคฒ เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "longDescription": "เคเค PDF เค
เคชเคฒเฅเคก เคเคฐเฅเค เคเคฐ เคชเฅเคฐเคคเฅเคฏเฅเค เคชเฅเคทเฅเค เคเฅ เคธเฅเคงเฅ เค
เคชเคจเฅ เคฌเฅเคฐเคพเคเคเคผเคฐ เคฎเฅเค เคเค เคเคเฅเค-เคเฅเคฃเคตเคคเฅเคคเคพ เคตเคพเคฒเฅ PNG เคเคตเคฟ เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค เคฏเคน เคเฅเคฒ เคตเคฟเคเคผเฅเค
เคฒ เคธเคพเคฎเคเฅเคฐเฅ เคจเคฟเคเคพเคฒเคจเฅ เคฏเคพ เค
เคฒเค-เค
เคฒเค เคชเฅเคทเฅเค เฅเค เคเฅ เคธเคพเคเคพ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคฆเคฐเฅเคถ เคนเฅเฅค เคเฅเค เคกเฅเคเคพ เค
เคชเคฒเฅเคก เคจเคนเฅเค เคเคฟเคฏเคพ เคเคพเคคเคพ เคนเฅ - เคธเคฌ เคเฅเค เคธเฅเคฅเคพเคจเฅเคฏ เคฐเฅเคช เคธเฅ เคเคฒเคคเคพ เคนเฅเฅค",
+ "shortDescription": "PDF เคเฅ PNG เคเคตเคฟเคฏเฅเค เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค",
+ "title": "เคชเฅเคกเฅเคเคซ เคธเฅ เคชเฅเคเคจเคเฅ"
+ },
+ "protectPdf": {
+ "allowCopying": "เคเฅเคชเฅ เคเคฐเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเค",
+ "allowModification": "เคธเคเคถเฅเคงเคจ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเค",
+ "allowPrinting": "เคชเฅเคฐเคฟเคเคเคฟเคเค เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเค",
+ "description": "PDF เคซเคผเคพเคเคฒเฅเค เคฎเฅเค เคชเคพเคธเคตเคฐเฅเคก เคธเฅเคฐเคเฅเคทเคพ เคเฅเคกเคผเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค PDF",
+ "ownerPassword": "เคฎเคพเคฒเคฟเค เคชเคพเคธเคตเคฐเฅเคก",
+ "ownerPasswordPlaceholder": "เคชเคพเคธเคตเคฐเฅเคก",
+ "permissions": "เค
เคจเฅเคฎเคคเคฟเคฏเคพเค",
+ "protectionOptions": "เคธเฅเคฐเคเฅเคทเคพ เคตเคฟเคเคฒเฅเคช",
+ "resultTitle": "เคธเฅเคฐเคเฅเคทเคฟเคค PDF",
+ "shortDescription": "เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒเฅเค เคเฅ เคธเฅเคฐเคเฅเคทเคฟเคค เคฐเฅเคช เคธเฅ เคชเคพเคธเคตเคฐเฅเคก เคธเฅเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "title": "PDF เคธเฅเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "userPassword": "เคเคชเคฏเฅเคเคเคฐเฅเคคเคพ เคชเคพเคธเคตเคฐเฅเคก",
+ "userPasswordPlaceholder": "เคชเคพเคธเคตเคฐเฅเคก"
+ },
+ "rotatePdf": {
+ "allPagesWillBeRotated": "เคธเคญเฅ {{count}} เคชเฅเคทเฅเค เคเฅเคฎเคพเค เคเคพเคเคเคเฅ",
+ "angle180": "180 เคกเคฟเคเฅเคฐเฅ",
+ "angle270": "270 เคกเคฟเคเฅเคฐเฅ",
+ "angle90": "90 เคกเคฟเคเฅเคฐเฅ",
+ "angleOptions": {
+ "clockwise90": "90ยฐ เคฆเคเฅเคทเคฟเคฃเคพเคตเคฐเฅเคค",
+ "counterClockwise270": "270ยฐ (90ยฐ เคตเคพเคฎเคพเคตเคฐเฅเคค)",
+ "upsideDown180": "180ยฐ (เคเคฒเฅเคเคพ)"
+ },
+ "applyToAll": "เคธเคญเฅ เคชเฅเคเฅเค เคชเคฐ เคฒเคพเคเฅ เคเคฐเฅเค",
+ "applyToAllPages": "เคธเคญเฅ เคชเฅเคทเฅเค เฅเค เคชเคฐ เคฒเคพเคเฅ เคเคฐเฅเค",
+ "applyToSelected": "เคเคฏเคจเคฟเคค เคชเฅเคเฅเค เคชเคฐ เคฒเคพเคเฅ เคเคฐเฅเค",
+ "description": "PDF เคชเฅเคเฅเค เคเฅ เคเฅเคฎเคพเคเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค PDF",
+ "longDescription": "PDF เคชเฅเคทเฅเค เฅเค เคเฅ 90, 180, เคฏเคพ 270 เคกเคฟเคเฅเคฐเฅ เคเฅเคฎเคพเคเคฐ เคเคจเคเคพ เคเคฐเคฟเคเคเคเฅเคถเคจ เคฌเคฆเคฒเฅเคเฅค เคเคฒเคค เคคเคฐเฅเคเฅ เคธเฅ เคธเฅเคเฅเคจ เคเคฟเค เคเค เคฆเคธเฅเคคเคพเคตเฅเคเคผเฅเค เคเฅ เค เฅเค เคเคฐเคจเฅ เคฏเคพ PDF เคเฅ เคชเฅเคฐเคฟเคเค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคคเฅเคฏเคพเคฐ เคเคฐเคจเฅ เคฎเฅเค เคเคชเคฏเฅเคเฅเฅค",
+ "pageRangesDescription": "เคชเฅเคทเฅเค เคธเคเคเฅเคฏเคพ เคฏเคพ เคถเฅเคฐเฅเคฃเคฟเคฏเคพเค เค
เคฒเฅเคชเคตเคฟเคฐเคพเคฎ เคธเฅ เค
เคฒเค เคเคฐเคเฅ เคฆเคฐเฅเค เคเคฐเฅเค (เคเคฆเคพเคนเคฐเคฃ เคเฅ เคฒเคฟเค, 1,3,5-7)",
+ "pageRangesPlaceholder": "เคเคฆเคพเคนเคฐเคฃเคพเคฐเฅเคฅ, 1,5-8",
+ "pagesPlaceholder": "เคเฅเคธเฅ 1,3-5,7",
+ "pagesWillBeRotated": "{{count}} เคชเฅเคทเฅเค {{count !== 1 ? 's' : ''}} เคเฅเคฎเคพเคฏเคพ เคเคพเคเคเคพ",
+ "pdfPageCount": "เคชเฅเคกเฅเคเคซ เคฎเฅเค เคนเฅ {{count}} เคชเฅเคทเฅเค {{count !== 1 ? 's' : ''}}",
+ "resultTitle": "เคเฅเคฎเคพเคฏเคพ เคเคฏเคพ PDF",
+ "rotatingPages": "เคเฅเคฎเคคเฅ เคนเฅเค เคชเฅเคทเฅเค ",
+ "rotationAngle": "เคเฅเคฎเคพเคจเฅ เคเคพ เคเฅเคฃ",
+ "rotationOptions": "เคเฅเคฎเคพเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "rotationSettings": "เคฐเฅเคเฅเคถเคจ เคธเฅเคเคฟเคเคเฅเคธ",
+ "selectedPages": "เคเคฏเคจเคฟเคค เคชเฅเค",
+ "shortDescription": "PDF เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคฎเฅเค เคชเฅเคทเฅเค เฅเค เคเฅ เคเฅเคฎเคพเคเค",
+ "title": "PDF เคเฅเคฎเคพเคเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ PDF เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคฎเฅเค เคชเฅเคทเฅเค เฅเค เคเฅ เคเฅเคฎเคพเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคธเคญเฅ เคชเฅเคทเฅเค เฅเค เคเฅ เคเฅเคฎเคพ เคธเคเคคเฅ เคนเฅเค เคฏเคพ เคเฅเคฎเคพเคจเฅ เคเฅ เคฒเคฟเค เค
เคฒเค-เค
เคฒเค เคชเฅเคทเฅเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคเฅเคฎเคพเคต เคเฅเคฃ เคเฅเคจเฅเค: 90ยฐ เคฆเคเฅเคทเคฟเคฃเคพเคตเคฐเฅเคค, 180ยฐ (เคเคฒเฅเคเคพ), เคฏเคพ 270ยฐ (90ยฐ เคตเคพเคฎเคพเคตเคฐเฅเคค)เฅค เคตเคฟเคถเคฟเคทเฅเค เคชเฅเคทเฅเค เฅเค เคเฅ เคเฅเคฎเคพเคจเฅ เคเฅ เคฒเคฟเค, \"เคธเคญเฅ เคชเฅเคทเฅเค เฅเค เคชเคฐ เคฒเคพเคเฅ เคเคฐเฅเค\" เคเฅ เค
เคจเคเฅเค เคเคฐเฅเค เคเคฐ เคชเฅเคทเฅเค เคธเคเคเฅเคฏเคพเคเค เคฏเคพ เค
เคฒเฅเคชเคตเคฟเคฐเคพเคฎ เคธเฅ เค
เคฒเค เคเฅ เคเค เคถเฅเคฐเฅเคฃเคฟเคฏเคพเค (เคเฅเคธเฅ, 1,3,5-7) เคฆเคฐเฅเค เคเคฐเฅเคเฅค",
+ "title": "เคฐเฅเคเฅเค เคชเฅเคกเฅเคเคซ เคเฅเคฒ เคเคพ เคเคชเคฏเฅเค เคเฅเคธเฅ เคเคฐเฅเค"
+ }
+ },
+ "splitPdf": {
+ "description": "PDF เคซเคผเคพเคเคฒ เคธเฅ เคตเคฟเคถเคฟเคทเฅเค เคชเฅเค เคจเคฟเคเคพเคฒเฅเคเฅค",
+ "extractingPages": "เคชเฅเคทเฅเค เคจเคฟเคเคพเคฒเคจเคพ",
+ "includeBookmarks": "เคฌเฅเคเคฎเคพเคฐเฅเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค PDF",
+ "pageExtractionPreview": "{{count}} เคชเฅเคทเฅเค {{count !== 1 ? 's' : ''}} เคจเคฟเคเคพเคฒเคพ เคเคพเคเคเคพ",
+ "pageRanges": "เคชเฅเค เคถเฅเคฐเฅเคฃเคฟเคฏเคพเค",
+ "pageRangesDescription": "เคชเฅเคทเฅเค เคธเคเคเฅเคฏเคพ เคฏเคพ เคถเฅเคฐเฅเคฃเคฟเคฏเคพเค เค
เคฒเฅเคชเคตเคฟเคฐเคพเคฎ เคธเฅ เค
เคฒเค เคเคฐเคเฅ เคฆเคฐเฅเค เคเคฐเฅเค (เคเคฆเคพเคนเคฐเคฃ เคเฅ เคฒเคฟเค, 1,3,5-7)",
+ "pageRangesPlaceholder": "เคเคฆเคพเคนเคฐเคฃเคพเคฐเฅเคฅ, 1,5-8",
+ "pageSelection": "เคชเฅเคทเฅเค เคเคฏเคจ",
+ "pdfPageCount": "เคชเฅเคกเฅเคเคซ เคฎเฅเค เคนเฅ {{count}} เคชเฅเคทเฅเค {{count !== 1 ? 's' : ''}}",
+ "rangesPlaceholder": "เคเฅเคธเฅ 1,3-5,7",
+ "resultTitle": "เคตเคฟเคญเคพเคเคฟเคค PDF เคซเคผเคพเคเคฒเฅเค",
+ "shortDescription": "เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒ เคธเฅ เคตเคฟเคถเคฟเคทเฅเค เคชเฅเค เคจเคฟเคเคพเคฒเฅเค",
+ "splitByBookmarks": "เคฌเฅเคเคฎเคพเคฐเฅเค เคฆเฅเคตเคพเคฐเคพ เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค",
+ "splitByPages": "เคชเฅเค เคฆเฅเคตเคพเคฐเคพ เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค",
+ "splitByRanges": "เคถเฅเคฐเฅเคฃเคฟเคฏเฅเค เคฆเฅเคตเคพเคฐเคพ เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค",
+ "splitMethod": "เคตเคฟเคญเคพเคเคจ เคตเคฟเคงเคฟ",
+ "splitOptions": "เคตเคฟเคญเคพเคเคจ เคตเคฟเคเคฒเฅเคช",
+ "title": "PDF เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคเคฟเคธเฅ PDF เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคธเฅ เคตเคฟเคถเคฟเคทเฅเค เคชเฅเคทเฅเค เคจเคฟเคเคพเคฒเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคจเคฟเคเคพเคฒเคจเฅ เคเฅ เคฒเคฟเค เค
เคฒเค-เค
เคฒเค เคชเฅเคทเฅเค เคฏเคพ เคชเฅเคทเฅเค เฅเค เคเฅ เคถเฅเคฐเฅเคฃเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "title": "PDF เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค"
+ }
+ }
+}
diff --git a/public/locales/hi/string.json b/public/locales/hi/string.json
new file mode 100644
index 0000000..25b3f10
--- /dev/null
+++ b/public/locales/hi/string.json
@@ -0,0 +1,261 @@
+{
+ "base64": {
+ "decode": "เคฌเฅเคธ64 เคกเคฟเคเฅเคก",
+ "description": "เคฌเฅเคธ64 เคเคจเคเฅเคกเคฟเคเค เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคเฅเคเฅเคธเฅเค เคเฅ เคเคจเคเฅเคก เคฏเคพ เคกเคฟเคเฅเคก เคเคฐเฅเคเฅค",
+ "encode": "เคฌเฅเคธ64 เคเคจเคเฅเคก",
+ "inputTitle": "เคเคจเคชเฅเค เคกเฅเคเคพ",
+ "optionsTitle": "เคฌเฅเคธ64 เคตเคฟเคเคฒเฅเคช",
+ "resultTitle": "เคชเคฐเคฟเคฃเคพเคฎ",
+ "shortDescription": "เคฌเฅเคธ64 เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคกเฅเคเคพ เคเฅ เคเคจเคเฅเคก เคฏเคพ เคกเคฟเคเฅเคก เคเคฐเฅเคเฅค",
+ "title": "เคฌเฅเคธ64 เคเคจเคเฅเคกเคฐ/เคกเคฟเคเฅเคกเคฐ",
+ "toolInfo": {
+ "description": "เคฌเฅเคธ64 เคเค เคเคจเคเฅเคกเคฟเคเค เคฏเฅเคเคจเคพ เคนเฅ เคเฅ เคกเฅเคเคพ เคเฅ เคฐเฅเคกเคฟเคเฅเคธ-64 เคชเฅเคฐเคคเคฟเคจเคฟเคงเคฟเคคเฅเคต เคฎเฅเค เค
เคจเฅเคตเคพเคฆ เคเคฐเคเฅ ASCII เคธเฅเคเฅเคฐเคฟเคเค เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคชเฅเคฐเคธเฅเคคเฅเคค เคเคฐเคคเฅ เคนเฅเฅค เคนเคพเคฒเคพเคเคเคฟ เคเคธเคเคพ เคเคชเคฏเฅเค เคธเฅเคเฅเคฐเคฟเคเคเฅเคธ เคเฅ เคเคจเคเฅเคก เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคฟเคฏเคพ เคเคพ เคธเคเคคเคพ เคนเฅ, เคฏเคน เคเคฎเคคเฅเคฐ เคชเคฐ เคฌเคพเคเคจเคฐเฅ เคกเฅเคเคพ เคเฅ เคเคจเคเฅเคก เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเค เคเคฟเคฏเคพ เคเคพเคคเคพ เคนเฅ เคเฅ เคเฅเคเฅเคธเฅเค เคกเฅเคเคพ เคธเฅ เคจเคฟเคชเคเคจเฅ เคเฅ เคฒเคฟเค เคกเคฟเคเคผเคพเคเคจ เคเคฟเค เคเค เคฎเฅเคกเคฟเคฏเคพ เคชเคฐ เคชเฅเคฐเคธเคพเคฐเคฃ เคเฅ เคฒเคฟเค เคนเฅเคคเคพ เคนเฅเฅค",
+ "title": "เคฌเฅเคธ64 เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "censor": {
+ "description": "เคชเคพเค เคฎเฅเค เคถเคฌเฅเคฆเฅเค เคเฅ เคธเฅเคเคธเคฐ เคเคฐเคจเฅ เคเฅ เคเคชเคฏเฅเคเคฟเคคเคพเฅค เคฌเคพเคเค เคเคฐ เคฆเคฟเค เคเค เคเคจเคชเฅเค เคซเคผเฅเคฐเฅเคฎ เคฎเฅเค เค
เคชเคจเคพ เคชเคพเค เคฒเฅเคก เคเคฐเฅเค, เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค เคธเคญเฅ เคเคฒเคค เคถเคฌเฅเคฆ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเฅเค, เคเคฐ เคเคชเคเฅ เคเคเคเคชเฅเค เคเฅเคทเฅเคคเฅเคฐ เคฎเฅเค เคคเฅเคฐเคเคค เคธเฅเคเคธเคฐ เคเคฟเคฏเคพ เคเคฏเคพ เคชเคพเค เคฎเคฟเคฒ เคเคพเคเคเคพเฅค\", longDescription: 'เคเคธ เคเคจเคฒเคพเคเคจ เคเฅเคฒ เคธเฅ, เคเคช เคเคฟเคธเฅ เคญเฅ เคชเคพเค เคฎเฅเค เคเฅเค เคถเคฌเฅเคฆเฅเค เคเฅ เคธเฅเคเคธเคฐ เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคเคช เค
เคตเคพเคเคเคฟเคค เคถเคฌเฅเคฆเฅเค (เคเฅเคธเฅ เค
เคชเคถเคฌเฅเคฆ เคฏเคพ เคเฅเคชเฅเคค เคถเคฌเฅเคฆ) เคเฅ เคเค เคธเฅเคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค เคเคฐ เคชเฅเคฐเฅเคเฅเคฐเคพเคฎ เคเคจเฅเคนเฅเค เคตเฅเคเคฒเฅเคชเคฟเค เคถเคฌเฅเคฆเฅเค เคธเฅ เคฌเคฆเคฒเคเคฐ เคเค เคธเฅเคฐเคเฅเคทเคฟเคค เคชเคพเค เคคเฅเคฏเคพเคฐ เคเคฐ เคฆเฅเคเคพเฅค เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค เคเค เคฌเคนเฅ-เคชเคเคเฅเคคเคฟ เคชเคพเค เคซเคผเฅเคฒเฅเคก เคฎเฅเค เคชเฅเคฐเคคเคฟ เคชเคเคเฅเคคเคฟ เคเค เคถเคฌเฅเคฆ เคฆเคฐเฅเค เคเคฐเคเฅ เคถเคฌเฅเคฆเฅเค เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฟเคฏเคพ เคเคพ เคธเคเคคเคพ เคนเฅเฅค', keywords: ['text', 'censor', 'words', 'characters'], component: lazy(() => import('./index')), i18n: { name: 'string:censor.title', description: 'string:censor.description'",
+ "shortDescription": "เคฌเฅเคฐเฅ เคถเคฌเฅเคฆเฅเค เคเฅ เคคเฅเคฐเคเคค เคนเคเคพ เคฆเฅเค เคฏเคพ เคเคจเฅเคนเฅเค เคตเฅเคเคฒเฅเคชเคฟเค เคถเคฌเฅเคฆเฅเค เคธเฅ เคฌเคฆเคฒ เคฆเฅเคเฅค",
+ "title": "เคชเคพเค เคธเฅเคเคธเคฐ"
+ },
+ "createPalindrome": {
+ "description": "เคเคฟเคธเฅ เคญเฅ เคเฅเคเฅเคธเฅเค เคธเฅ เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคฌเคจเคพเคจเฅ เคเฅ เคฒเคฟเค เคฆเฅเคจเคฟเคฏเคพ เคเคพ เคธเคฌเคธเฅ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพเฅค เคเฅเคเฅเคธเฅเค เคเคจเคชเฅเค เคเคฐเฅเค เคเคฐ เคเคธเฅ เคคเฅเคฐเคเคค เคเค เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคฎเฅเค เคฌเคฆเคฒ เคฆเฅเค เคเฅ เคเคเฅ เคเคฐ เคชเฅเคเฅ เคเค เคเฅเคธเคพ เคชเคขเคผเคคเคพ เคนเฅเฅค เคถเคฌเฅเคฆ เคเฅเคฒเฅเค, เคธเคฎเคฎเคฟเคค เคเฅเคเฅเคธเฅเค เคชเฅเคเคฐเฅเคจ เคฌเคจเคพเคจเฅ, เคฏเคพ เคญเคพเคทเคพเค เคเคฟเคเฅเคเคพเคธเคพเคเค เคเฅ เคเฅเค เคเฅ เคฒเคฟเค เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅเฅค",
+ "shortDescription": "เคเคธเคพ เคเฅเคเฅเคธเฅเค เคฌเคจเคพเคเค เคเฅ เคเคเฅ เคเคฐ เคชเฅเคเฅ เคเค เคเฅเคธเคพ เคชเคขเคผเคคเคพ เคนเฅ",
+ "title": "เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคฌเคจเคพเคเค"
+ },
+ "extractSubstring": {
+ "description": "เคเฅเคเฅเคธเฅเค เคธเฅ เคธเคฌเคธเฅเคเฅเคฐเคฟเคเค เคจเคฟเคเคพเคฒเคจเฅ เคเฅ เคฒเคฟเค เคฆเฅเคจเคฟเคฏเคพ เคเฅ เคธเคฌเคธเฅ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพเฅค เค
เคชเคจเคพ เคเฅเคเฅเคธเฅเค เคเคจเคชเฅเค เคเคฐเฅเค เคเคฐ เคตเคพเคเคเคฟเคค เคญเคพเค เคจเคฟเคเคพเคฒเคจเฅ เคเฅ เคฒเคฟเค เคเคฐเคเคญ เคเคฐ เค
เคเคค เคธเฅเคฅเคฟเคคเคฟเคฏเคพเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเฅเคเฅค เคกเฅเคเคพ เคชเฅเคฐเฅเคธเฅเคธเคฟเคเค, เคเฅเคเฅเคธเฅเค เคตเคฟเคถเฅเคฒเฅเคทเคฃ, เคฏเคพ เคฌเคกเคผเฅ เคเฅเคเฅเคธเฅเค เคฌเฅเคฒเฅเค เคธเฅ เคตเคฟเคถเคฟเคทเฅเค เคธเคพเคฎเคเฅเคฐเฅ เคจเคฟเคเคพเคฒเคจเฅ เคเฅ เคฒเคฟเค เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅเฅค",
+ "shortDescription": "เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคธเฅเคฅเคพเคจเฅเค เคเฅ เคฌเฅเค เคชเคพเค เคเคพ เคเค เคญเคพเค เคจเคฟเคเคพเคฒเฅเค",
+ "title": "เคธเคฌเคธเฅเคเฅเคฐเคฟเคเค เคจเคฟเคเคพเคฒเฅเค"
+ },
+ "join": {
+ "blankLinesAndTrailingSpaces": "เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคเคฐ เค
เคจเฅเคเคพเคฎเฅ เคธเฅเคฅเคพเคจ",
+ "deleteBlankDescription": "เคเคจ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคนเคเคพเคเค เคเคฟเคจเคฎเฅเค เคเฅเคเฅเคธเฅเค เคชเฅเคฐเคคเฅเค เคจเคนเฅเค เคนเฅเคเฅค",
+ "deleteBlankTitle": "เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคนเคเคพเคเค",
+ "deleteTrailingDescription": "เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เค
เคเคค เคธเฅ เคธเฅเคชเฅเคธ เคเคฐ เคเฅเคฌ เคนเคเคพเคเคเฅค",
+ "deleteTrailingTitle": "เค
เคจเฅเคเคพเคฎเฅ เคธเฅเคฅเคพเคจ เคนเคเคพเคเค",
+ "description": "เคเคธเฅเคเคฎเคพเคเคเคผ เคเคฐเคจเฅ เคฏเฅเคเฅเคฏ เคตเคฟเคญเคพเคเคเฅเค เคเฅ เคธเคพเคฅ เคเฅเคเฅเคธเฅเค เคเฅเคเคกเคผเฅเค เคเฅ เคเค เคธเคพเคฅ เคเฅเคกเคผเฅเคเฅค",
+ "inputTitle": "เคเฅเคเฅเคธเฅเค เคเฅเคเคกเคผเฅ",
+ "joinCharacterDescription": "เคชเฅเคฐเคคเฅเค เคเฅ เคเฅเคเฅเคธเฅเค เคเฅ เคเฅเคเฅ เคนเฅเค เคเฅเคเคกเคผเฅเค เคเฅ เคเฅเคกเคผเคคเคพ เคนเฅเฅค (เคกเคฟเคซเคผเฅเคฒเฅเค เคฐเฅเคช เคธเฅ เคธเฅเคชเฅเคธเฅค)",
+ "joinCharacterPlaceholder": "เคเฅเคกเคผเคจเฅ เคเคพ เคตเคฐเฅเคฃ",
+ "resultTitle": "เคเฅเคกเคผเคพ เคนเฅเค เคเฅเคเฅเคธเฅเค",
+ "shortDescription": "เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคตเคฟเคญเคพเคเค เคเฅ เคธเคพเคฅ เคชเคพเค เคคเคคเฅเคตเฅเค เคเฅ เคเฅเคกเคผเฅเค",
+ "textMergedOptions": "เคเฅเคเฅเคธเฅเค เคฎเคฐเฅเค เคตเคฟเคเคฒเฅเคช",
+ "title": "เคเฅเคเฅเคธเฅเค เคเฅเคกเคผเฅเค",
+ "toolInfo": {
+ "description": "เคเคธ เคเฅเคฒ เคเฅ เคธเคพเคฅ เคเคช เคเฅเคเฅเคธเฅเค เคเฅ เคญเคพเคเฅเค เคเฅ เคเค เคธเคพเคฅ เคเฅเคกเคผ เคธเคเคคเฅ เคนเฅเคเฅค เคฏเคน เคจเค เคชเคเคเฅเคคเคฟเคฏเฅเค เคธเฅ เค
เคฒเค เคเคฟเค เคเค เคเฅเคเฅเคธเฅเค เคฎเฅเคฒเฅเคฏเฅเค เคเฅ เคธเฅเคเฅ เคฒเฅเคคเคพ เคนเฅ เคเคฐ เคเคจเฅเคนเฅเค เคเค เคธเคพเคฅ เคฎเคฐเฅเค เคเคฐเคคเคพ เคนเฅเฅค เคเคช เคเคธ เคตเคฐเฅเคฃ เคเฅ เคธเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค เคเฅ เคธเคเคฏเฅเคเฅเคค เคเฅเคเฅเคธเฅเค เคเฅ เคญเคพเคเฅเค เคเฅ เคฌเฅเค เคฐเคเคพ เคเคพเคเคเคพเฅค เคธเคพเคฅ เคนเฅ, เคเคช เคธเคญเฅ เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เค
เคจเคฆเฅเคเคพ เคเคฐ เคธเคเคคเฅ เคนเฅเค เคเคฐ เคธเคญเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เค
เคเคค เคธเฅ เคธเฅเคชเฅเคธ เคเคฐ เคเฅเคฌ เคนเคเคพ เคธเคเคคเฅ เคนเฅเคเฅค เคเฅเคเฅเคธเฅเคเคพเคฌเฅเคฒเคธ!",
+ "title": "เคเฅเคเฅเคธเฅเค เคเฅเคเคจเคฐ เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "palindrome": {
+ "description": "เคฏเคน เคเคพเคเคเคจเฅ เคเฅ เคฒเคฟเค เคฆเฅเคจเคฟเคฏเคพ เคเคพ เคธเคฌเคธเฅ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพ เคเคฟ เคเฅเคเฅเคธเฅเค เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคนเฅ เคฏเคพ เคจเคนเฅเคเฅค เคคเฅเคฐเคเคค เคธเคคเฅเคฏเคพเคชเคฟเคค เคเคฐเฅเค เคเคฟ เคเฅเคฏเคพ เคเคชเคเคพ เคเฅเคเฅเคธเฅเค เคเคเฅ เคเคฐ เคชเฅเคเฅ เคเค เคเฅเคธเคพ เคชเคขเคผเคคเคพ เคนเฅเฅค เคถเคฌเฅเคฆ เคชเคนเฅเคฒเคฟเคฏเฅเค, เคญเคพเคทเคพเค เคตเคฟเคถเฅเคฒเฅเคทเคฃ, เคฏเคพ เคธเคฎเคฎเคฟเคค เคเฅเคเฅเคธเฅเค เคชเฅเคเคฐเฅเคจ เคเฅ เคฎเคพเคจเฅเคฏ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅเฅค เคตเคฟเคญเคฟเคจเฅเคจ เคตเคฟเคญเคพเคเคเฅเค เคเคฐ เคฌเคนเฅ-เคถเคฌเฅเคฆ เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคชเคนเคเคพเคจ เคเคพ เคธเคฎเคฐเฅเคฅเคจ เคเคฐเคคเคพ เคนเฅเฅค",
+ "shortDescription": "เคเคพเคเคเฅเค เคเคฟ เคเฅเคฏเคพ เคเฅเคเฅเคธเฅเค เคเคเฅ เคเคฐ เคชเฅเคเฅ เคเค เคเฅเคธเคพ เคชเคขเคผเคคเคพ เคนเฅ",
+ "title": "เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ"
+ },
+ "passwordGenerator": {
+ "avoidAmbiguous": "เค
เคธเฅเคชเคทเฅเค เคตเคฐเฅเคฃเฅเค (i, I, l, 0, O) เคธเฅ เคฌเคเฅเค",
+ "description": "เค
เคจเฅเคเฅเคฒเคจ เคฏเฅเคเฅเคฏ เคฒเคเคฌเคพเค เคเคฐ เคตเคฐเฅเคฃ เคชเฅเคฐเคเคพเคฐเฅเค เคเฅ เคธเคพเคฅ เคธเฅเคฐเคเฅเคทเคฟเคค, เคฏเคพเคฆเฅเคเฅเคเคฟเค เคชเคพเคธเคตเคฐเฅเคก เคฌเคจเคพเคเคเฅค เคฒเฅเค
เคฐเคเฅเคธ, เค
เคชเคฐเคเฅเคธ, เคธเคเคเฅเคฏเคพเคเค เคเคฐ เคตเคฟเคถเฅเคท เคตเคฐเฅเคฃเฅเค เคฎเฅเค เคธเฅ เคเฅเคจเฅเคเฅค เคฌเฅเคนเคคเคฐ เคชเค เคจเฅเคฏเคคเคพ เคเฅ เคฒเคฟเค เค
เคธเฅเคชเคทเฅเค เคตเคฐเฅเคฃเฅเค เคธเฅ เคฌเคเคจเฅ เคเคพ เคตเคฟเคเคฒเฅเคชเฅค",
+ "includeLowercase": "เคเฅเคเฅ เค
เคเฅเคทเคฐ (a-z) เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "includeNumbers": "เคธเคเคเฅเคฏเคพเคเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค (0-9)",
+ "includeSymbols": "เคตเคฟเคถเฅเคท เคตเคฐเฅเคฃ เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "includeUppercase": "เคฌเคกเคผเฅ เค
เคเฅเคทเคฐ (A-Z) เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "lengthDesc": "เคชเคพเคธเคตเคฐเฅเคก เคเฅ เคฒเคเคฌเคพเค",
+ "lengthPlaceholder": "เคเคฆเคพเคนเคฐเคฃเคพเคฐเฅเคฅ 12",
+ "optionsTitle": "เคชเคพเคธเคตเคฐเฅเคก เคตเคฟเคเคฒเฅเคช",
+ "resultTitle": "เคเคจเคฐเฅเค เคเคฟเคฏเคพ เคเคฏเคพ เคชเคพเคธเคตเคฐเฅเคก",
+ "shortDescription": "เคเคธเฅเคเคฎ เคตเคฟเคเคฒเฅเคชเฅเค เคเฅ เคธเคพเคฅ เคธเฅเคฐเคเฅเคทเคฟเคค เคฏเคพเคฆเฅเคเฅเคเคฟเค เคชเคพเคธเคตเคฐเฅเคก เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค",
+ "title": "เคชเคพเคธเคตเคฐเฅเคก เคเคจเคฐเฅเคเคฐ",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคเฅเคจเฅ เคนเฅเค เคฎเคพเคจเคฆเคเคกเฅเค เคเฅ เคเคงเคพเคฐ เคชเคฐ เคธเฅเคฐเคเฅเคทเคฟเคค, เคฏเคพเคฆเฅเคเฅเคเคฟเค เคชเคพเคธเคตเคฐเฅเคก เคฌเคจเคพเคคเคพ เคนเฅเฅค เคเคช เคฒเคเคฌเคพเค เคเฅ เค
เคจเฅเคเฅเคฒเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเค, เคตเคฟเคญเคฟเคจเฅเคจ เคชเฅเคฐเคเคพเคฐ เคเฅ เคตเคฐเฅเคฃเฅเค เคเฅ เคถเคพเคฎเคฟเคฒ เคฏเคพ เคนเคเคพ เคธเคเคคเฅ เคนเฅเค, เคเคฐ เคฌเฅเคนเคคเคฐ เคชเค เคจเฅเคฏเคคเคพ เคเฅ เคฒเคฟเค เค
เคธเฅเคชเคทเฅเค เคตเคฐเฅเคฃเฅเค เคธเฅ เคฌเค เคธเคเคคเฅ เคนเฅเคเฅค เคเคพเคคเฅเค, เคเคชเฅเคฒเคฟเคเฅเคถเคจ เคฏเคพ เคเคฟเคธเฅ เคญเฅ เคธเฅเคฐเคเฅเคทเคพ เคเคตเคถเฅเคฏเคเคคเคพเคเค เคเฅ เคฒเคฟเค เคฎเคเคผเคฌเฅเคค เคชเคพเคธเคตเคฐเฅเคก เคฌเคจเคพเคจเฅ เคเฅ เคฒเคฟเค เคฏเคน เคเคเคฆเคฎ เคธเคนเฅ เคนเฅเฅค",
+ "title": "เคชเคพเคธเคตเคฐเฅเคก เคเคจเคฐเฅเคเคฐ เคเฅ เคฌเคพเคฐเฅ เคฎเฅเค"
+ }
+ },
+ "quote": {
+ "allowDoubleQuotation": "เคฆเฅเคนเคฐเฅ เคเคฆเฅเคงเคฐเคฃ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเค",
+ "description": "เคเคธเฅเคเคฎเคพเคเคเคผ เคเคฐเคจเฅ เคฏเฅเคเฅเคฏ เคตเคฟเคเคฒเฅเคชเฅเค เคเฅ เคธเคพเคฅ เคเฅเคเฅเคธเฅเค เคเฅ เคเคพเคฐเฅเค เคเคฐ เคเคฆเฅเคงเคฐเคฃ เคเฅเคกเคผเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคเฅเคเฅเคธเฅเค",
+ "leftQuoteDescription": "เคฌเคพเคเค เคเคฆเฅเคงเคฐเคฃ เคตเคฐเฅเคฃ",
+ "processAsMultiLine": "เคฌเคนเฅ-เคชเคเคเฅเคคเคฟ เคเฅเคเฅเคธเฅเค เคเฅ เคฐเฅเคช เคฎเฅเค เคชเฅเคฐเคเฅเคฐเคฟเคฏเคพ เคเคฐเฅเค",
+ "quoteEmptyLines": "เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเฅเค เคเคฐเฅเค",
+ "quoteOptions": "เคเคฆเฅเคงเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "resultTitle": "เคเฅเคเฅเคก เคเฅเคเฅเคธเฅเค",
+ "rightQuoteDescription": "เคฆเคพเคเค เคเคฆเฅเคงเคฐเคฃ เคตเคฐเฅเคฃ",
+ "shortDescription": "เคตเคฟเคญเคฟเคจเฅเคจ เคถเฅเคฒเคฟเคฏเฅเค เคเฅ เคธเคพเคฅ เคชเคพเค เคเฅ เคเคพเคฐเฅเค เคเคฐ เคเคฆเฅเคงเคฐเคฃ เคเฅเคกเคผเฅเค",
+ "title": "เคเฅเคเฅเคธเฅเค เคเฅเคเคฐ",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคเฅเคเฅเคธเฅเค เคเฅ เคเคพเคฐเฅเค เคเคฐ เคเคฆเฅเคงเคฐเคฃ เคเฅเคกเคผเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคตเคฟเคญเคฟเคจเฅเคจ เคเคฆเฅเคงเคฐเคฃ เคตเคฐเฅเคฃ เคเฅเคจ เคธเคเคคเฅ เคนเฅเค, เคฌเคนเฅ-เคชเคเคเฅเคคเคฟ เคเฅเคเฅเคธเฅเค เคเฅ เคธเคเคญเคพเคฒ เคธเคเคคเฅ เคนเฅเค, เคเคฐ เคจเคฟเคฏเคเคคเฅเคฐเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเค เคเคฟ เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเฅเคธเฅ เคธเคเคธเคพเคงเคฟเคค เคเคฟเคฏเคพ เคเคพเคคเคพ เคนเฅเฅค เคฏเคน เคชเฅเคฐเฅเคเฅเคฐเคพเคฎเคฟเคเค เคเฅ เคฒเคฟเค เคเฅเคเฅเคธเฅเค เคคเฅเคฏเคพเคฐ เคเคฐเคจเฅ, เคกเฅเคเคพ เคเฅ เคซเฅเคฐเฅเคฎเฅเค เคเคฐเคจเฅ, เคฏเคพ เคธเฅเคเคพเคเคฒเคฟเคถ เคเฅเคเฅเคธเฅเค เคฌเคจเคพเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเคเฅ เคนเฅเฅค",
+ "title": "เคเฅเคเฅเคธเฅเค เคเฅเคเคฐ"
+ }
+ },
+ "randomizeCase": {
+ "description": "เคเฅเคเฅเคธเฅเค เคเฅเคธ เคเฅ เคฐเฅเคเคกเคฎเคพเคเคเคผ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคฆเฅเคจเคฟเคฏเคพ เคเฅ เคธเคฌเคธเฅ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพเฅค เค
เคชเคจเคพ เคเฅเคเฅเคธเฅเค เคเคจเคชเฅเค เคเคฐเฅเค เคเคฐ เคเคธเฅ เคคเฅเคฐเคเคค เคฐเฅเคเคกเคฎ เค
เคชเคฐ เคเคฐ เคฒเฅเค
เคฐ เคเฅเคธ เค
เคเฅเคทเคฐเฅเค เคธเฅ เคฌเคฆเคฒ เคฆเฅเคเฅค เค
เคจเฅเคเฅ เคเฅเคเฅเคธเฅเค เคเคซเคผเฅเคเฅเค เคฌเคจเคพเคจเฅ, เคเฅเคธ เคธเฅเคเคธเคฟเคเคฟเคตเคฟเคเฅ เคเฅเคธเฅเค เคเคฐเคจเฅ, เคฏเคพ เค
เคฒเค-เค
เคฒเค เคเฅเคเฅเคธเฅเค เคชเฅเคเคฐเฅเคจ เคฌเคจเคพเคจเฅ เคเฅ เคฒเคฟเค เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅเฅค",
+ "shortDescription": "เคชเคพเค เคฎเฅเค เค
เคเฅเคทเคฐเฅเค เคเฅ เคเฅเคธ เคเฅ เคฏเคพเคฆเฅเคเฅเคเคฟเค เคเคฐเฅเค",
+ "title": "เคฎเคพเคฎเคฒเฅ เคเฅ เคฏเคพเคฆเฅเคเฅเคเคฟเค เคเคฐเฅเค"
+ },
+ "removeDuplicateLines": {
+ "description": "เคฌเคพเคเค เคเคฐ เคฆเคฟเค เคเค เคเคจเคชเฅเค เคซเคผเฅเคฐเฅเคฎ เคฎเฅเค เค
เคชเคจเคพ เคเฅเคเฅเคธเฅเค เคฒเฅเคก เคเคฐเฅเค เคเคฐ เคเคชเคเฅ เคคเฅเคฐเคเคค เคเคธเคพ เคเฅเคเฅเคธเฅเค เคฎเคฟเคฒเฅเคเคพ เคเคฟเคธเคฎเฅเค เคเคเคเคชเฅเค เคเฅเคทเฅเคคเฅเคฐ เคฎเฅเค เคเฅเค เคกเฅเคชเฅเคฒเคฟเคเฅเค เคฒเคพเคเคจ เคจเคนเฅเค เคนเฅเคเฅเฅค เคถเคเฅเคคเคฟเคถเคพเคฒเฅ, เคฎเฅเคซเคผเฅเคค เคเคฐ เคคเฅเคเคผเฅค เคเฅเคเฅเคธเฅเค เคฒเคพเคเคจ เคฒเฅเคก เคเคฐเฅเค - เค
เคจเฅเคเฅ เคเฅเคเฅเคธเฅเค เคฒเคพเคเคจ เคชเฅเคฐเคพเคชเฅเคค เคเคฐเฅเค",
+ "shortDescription": "เคชเคพเค เคธเฅ เคธเคญเฅ เคฆเฅเคนเคฐเคพเค เคเค เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคคเฅเคฐเคเคค เคนเคเคพเคเค",
+ "title": "เคกเฅเคชเฅเคฒเคฟเคเฅเค เคชเคเคเฅเคคเคฟเคฏเคพเค เคนเคเคพเคเค"
+ },
+ "repeat": {
+ "delimiterDescription": "เคเคเคเคชเฅเค เคชเฅเคฐเคคเคฟเคฏเฅเค เคเฅ เคฒเคฟเค เคตเคฟเคญเคพเคเคเฅค",
+ "delimiterPlaceholder": "เคตเคฟเคญเคพเคเค",
+ "description": "เคเคธเฅเคเคฎเคพเคเคเคผ เคเคฐเคจเฅ เคฏเฅเคเฅเคฏ เคตเคฟเคญเคพเคเคเฅเค เคเฅ เคธเคพเคฅ เคเฅเคเฅเคธเฅเค เคเฅ เคเค เคฌเคพเคฐ เคฆเฅเคนเคฐเคพเคเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคเฅเคเฅเคธเฅเค",
+ "numberPlaceholder": "เคธเคเคเฅเคฏเคพ",
+ "repeatAmountDescription": "เคฆเฅเคนเคฐเคพเคต เคเฅ เคธเคเคเฅเคฏเคพเฅค",
+ "repetitionsDelimiter": "เคฆเฅเคนเคฐเคพเคต เคตเคฟเคญเคพเคเค",
+ "resultTitle": "เคฆเฅเคนเคฐเคพเคฏเคพ เคเคฏเคพ เคเฅเคเฅเคธเฅเค",
+ "shortDescription": "เคเฅเคเฅเคธเฅเค เคเฅ เคเค เคฌเคพเคฐ เคฆเฅเคนเคฐเคพเคเค",
+ "textRepetitions": "เคเฅเคเฅเคธเฅเค เคฆเฅเคนเคฐเคพเคต",
+ "title": "เคเฅเคเฅเคธเฅเค เคฆเฅเคนเคฐเคพเคเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคตเฅเคเคฒเฅเคชเคฟเค เคตเคฟเคญเคพเคเค เคเฅ เคธเคพเคฅ เคฆเคฟเค เคเค เคเฅเคเฅเคธเฅเค เคเฅ เคเค เคฌเคพเคฐ เคฆเฅเคนเคฐเคพเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅเฅค",
+ "title": "เคเฅเคเฅเคธเฅเค เคฆเฅเคนเคฐเคพเคเค"
+ }
+ },
+ "reverse": {
+ "description": "เคเฅเคเฅเคธเฅเค เคฎเฅเค เคตเคฐเฅเคฃเฅเค เคเฅ เคเฅเคฐเคฎ เคเฅ เคเคฒเคเคพ เคเคฐเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคเฅเคเฅเคธเฅเค",
+ "processMultiLine": "เคฌเคนเฅ-เคชเคเคเฅเคคเคฟ เคเฅเคเฅเคธเฅเค เคเฅ เคฐเฅเคช เคฎเฅเค เคชเฅเคฐเคเฅเคฐเคฟเคฏเคพ เคเคฐเฅเค (เคชเฅเคฐเคคเฅเคฏเฅเค เคชเคเคเฅเคคเคฟ เคเฅ เค
เคฒเค เคธเฅ เคเคฒเคเคพ เคเคฐเฅเค)",
+ "processMultiLineDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคชเคเคเฅเคคเคฟ เคธเฅเคตเคคเคเคคเฅเคฐ เคฐเฅเคช เคธเฅ เคเคฒเคเฅ เคเคพเคเคเฅ",
+ "resultTitle": "เคเคฒเคเคพ เคเฅเคเฅเคธเฅเค",
+ "reversalOptions": "เคเคฒเค เคตเคฟเคเคฒเฅเคช",
+ "shortDescription": "เคเคฟเคธเฅ เคญเฅ เคเฅเคเฅเคธเฅเค เคเฅ เคตเคฐเฅเคฃ เคฆเคฐ เคตเคฐเฅเคฃ เคเคฒเคเคพ เคเคฐเฅเค",
+ "skipEmptyLines": "เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเฅเคกเคผเฅเค",
+ "skipEmptyLinesDescription": "เคเคเคเคชเฅเค เคธเฅ เคเคพเคฒเฅ เคฒเคพเคเคจเฅเค เคนเคเคพ เคฆเฅ เคเคพเคเคเคเฅ",
+ "title": "เคเฅเคเฅเคธเฅเค เคเคฒเคเคพ เคเคฐเฅเค",
+ "trimWhitespace": "เคชเคเคเฅเคคเคฟเคฏเฅเค เคธเฅ เคธเคซเฅเคฆ เคธเฅเคฅเคพเคจ เคเฅเคฐเคฟเคฎ เคเคฐเฅเค",
+ "trimWhitespaceDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคชเคเคเฅเคคเคฟ เคธเฅ เคเคฐเคเคญเคฟเค เคเคฐ เค
เคเคคเคฟเคฎ เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ เคนเคเคพเคเค"
+ },
+ "rot13": {
+ "description": "ROT13 เคธเคฟเคซเคฐ เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคเฅเคเฅเคธเฅเค เคเฅ เคเคจเคเฅเคก เคฏเคพ เคกเคฟเคเฅเคก เคเคฐเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคเฅเคเฅเคธเฅเค",
+ "resultTitle": "ROT13 เคชเคฐเคฟเคฃเคพเคฎ",
+ "shortDescription": "ROT13 เคธเคฟเคซเคฐ เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคเฅเคเฅเคธเฅเค เคเฅ เคเคจเคเฅเคก เคฏเคพ เคกเคฟเคเฅเคก เคเคฐเฅเคเฅค",
+ "title": "ROT13 เคเคจเคเฅเคกเคฐ/เคกเคฟเคเฅเคกเคฐ",
+ "toolInfo": {
+ "description": "ROT13 (13 เคธเฅเคฅเคพเคจเฅเค เคธเฅ เคเฅเคฎเคพเคเค) เคเค เคธเคฐเคฒ เค
เคเฅเคทเคฐ เคชเฅเคฐเคคเคฟเคธเฅเคฅเคพเคชเคจ เคธเคฟเคซเคฐ เคนเฅ เคเฅ เคเค เค
เคเฅเคทเคฐ เคเฅ เคตเคฐเฅเคฃเคฎเคพเคฒเคพ เคฎเฅเค เคเคธเคเฅ เคฌเคพเคฆ เคเฅ 13เคตเฅเค เค
เคเฅเคทเคฐ เคธเฅ เคฌเคฆเคฒ เคฆเฅเคคเคพ เคนเฅเฅค ROT13 เคธเฅเคเคผเคฐ เคธเคฟเคซเคฐ เคเคพ เคเค เคตเคฟเคถเฅเคท เคฎเคพเคฎเคฒเคพ เคนเฅ เคเฅ เคชเฅเคฐเคพเคเฅเคจ เคฐเฅเคฎ เคฎเฅเค เคตเคฟเคเคธเคฟเคค เคเคฟเคฏเคพ เคเคฏเคพ เคฅเคพเฅค เคเฅเคฏเฅเคเคเคฟ เค
เคเคเฅเคฐเฅเคเฅ เคตเคฐเฅเคฃเคฎเคพเคฒเคพ เคฎเฅเค 26 เค
เคเฅเคทเคฐ เคนเฅเค, ROT13 เค
เคชเคจเคพ เคธเฅเคตเคฏเค เคเคพ เคตเฅเคฏเฅเคคเฅเคเฅเคฐเคฎ เคนเฅ; เค
เคฐเฅเคฅเคพเคค, ROT13 เคเฅ เคชเฅเคฐเฅเคตเคตเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค, เคเค เคนเฅ เคเคฒเฅเคเฅเคฐเคฟเคฅเคฎ เคฒเคพเคเฅ เคเคฟเคฏเคพ เคเคพเคคเคพ เคนเฅ, เคเคธเคฒเคฟเค เคเคจเคเฅเคกเคฟเคเค เคเคฐ เคกเคฟเคเฅเคกเคฟเคเค เคฆเฅเคจเฅเค เคเฅ เคฒเคฟเค เคเค เคนเฅ เคเฅเคฐเคฟเคฏเคพ เคเคพ เคเคชเคฏเฅเค เคเคฟเคฏเคพ เคเคพ เคธเคเคคเคพ เคนเฅเฅค",
+ "title": "ROT13 เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "rotate": {
+ "description": "เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคธเฅเคฅเคพเคจเฅเค เคฆเฅเคตเคพเคฐเคพ เคเฅเคเฅเคธเฅเค เคฎเฅเค เคตเคฐเฅเคฃเฅเค เคเฅ เคเฅเคฎเคพเคเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคเฅเคเฅเคธเฅเค",
+ "processAsMultiLine": "เคฌเคนเฅ-เคชเคเคเฅเคคเคฟ เคเฅเคเฅเคธเฅเค เคเฅ เคฐเฅเคช เคฎเฅเค เคชเฅเคฐเคเฅเคฐเคฟเคฏเคพ เคเคฐเฅเค (เคชเฅเคฐเคคเฅเคฏเฅเค เคชเคเคเฅเคคเคฟ เคเฅ เค
เคฒเค เคธเฅ เคเฅเคฎเคพเคเค)",
+ "resultTitle": "เคเฅเคฎเคพเคฏเคพ เคเคฏเคพ เคเฅเคเฅเคธเฅเค",
+ "rotateLeft": "เคฌเคพเคเค เคเคฐ เคเฅเคฎเคพเคเค",
+ "rotateRight": "เคฆเคพเคเค เคเคฐ เคเฅเคฎเคพเคเค",
+ "rotationOptions": "เคเฅเคฎเคพเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "shortDescription": "เคชเคพเค เคฎเฅเค เคตเคฐเฅเคฃเฅเค เคเฅ เคธเฅเคฅเคพเคจ เคเฅ เค
เคจเฅเคธเคพเคฐ เคธเฅเคฅเคพเคจเคพเคเคคเคฐเคฟเคค เคเคฐเฅเคเฅค",
+ "stepDescription": "เคเฅเคฎเคพเคจเฅ เคเฅ เคฒเคฟเค เคธเฅเคฅเคพเคจเฅเค เคเฅ เคธเคเคเฅเคฏเคพ",
+ "title": "เคเฅเคเฅเคธเฅเค เคเฅเคฎเคพเคเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคธเคเคเฅเคฏเคพ เคฎเฅเค เคธเฅเคฅเคพเคจเฅเค เคฆเฅเคตเคพเคฐเคพ เคธเฅเคเฅเคฐเคฟเคเค เคฎเฅเค เคตเคฐเฅเคฃเฅเค เคเฅ เคเฅเคฎเคพเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคฌเคพเคเค เคฏเคพ เคฆเคพเคเค เคเฅเคฎเคพ เคธเคเคคเฅ เคนเฅเค, เคเคฐ เคชเฅเคฐเคคเฅเคฏเฅเค เคชเคเคเฅเคคเคฟ เคเฅ เค
เคฒเค เคธเฅ เคเฅเคฎเคพเคเคฐ เคฌเคนเฅ-เคชเคเคเฅเคคเคฟ เคเฅเคเฅเคธเฅเค เคเฅ เคธเคเคธเคพเคงเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคธเฅเคเฅเคฐเคฟเคเค เคฐเฅเคเฅเคถเคจ เคธเคฐเคฒ เคเฅเคเฅเคธเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคจเฅเค, เคชเฅเคเคฐเฅเคจ เคฌเคจเคพเคจเฅ, เคฏเคพ เคฌเฅเคจเคฟเคฏเคพเคฆเฅ เคเคจเฅเคเฅเคฐเคฟเคชเฅเคถเคจ เคคเคเคจเฅเคเฅเค เคเฅ เคฒเคพเคเฅ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเคเฅ เคนเฅเฅค",
+ "title": "เคธเฅเคเฅเคฐเคฟเคเค เคฐเฅเคเฅเคถเคจ"
+ }
+ },
+ "split": {
+ "charAfterChunkDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคเคเค เคเฅ เคฌเคพเคฆ เคตเคฐเฅเคฃ",
+ "charBeforeChunkDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคเคเค เคธเฅ เคชเคนเคฒเฅ เคตเคฐเฅเคฃ",
+ "chunksDescription": "เคเคเคเคชเฅเค เคฎเฅเค เคธเคฎเคพเคจ เคฒเคเคฌเคพเค เคเฅ เคเคเค เคเฅ เคธเคเคเฅเคฏเคพเฅค",
+ "chunksTitle": "เคเคเค เคเฅ เคธเคเคเฅเคฏเคพ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
+ "description": "เคตเคฟเคญเคฟเคจเฅเคจ เคฎเคพเคจเคฆเคเคกเฅเค เคเฅ เคเคงเคพเคฐ เคชเคฐ เคเฅเคเฅเคธเฅเค เคเฅ เคญเคพเคเฅเค เคฎเฅเค เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเคเฅค",
+ "lengthDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคเคเคเคชเฅเค เคเคเค เคฎเฅเค เคฐเคเฅ เคเคพเคจเฅ เคตเคพเคฒเฅ เคตเคฐเฅเคฃเฅเค เคเฅ เคธเคเคเฅเคฏเคพเฅค",
+ "lengthTitle": "เคตเคฟเคญเคพเคเคจ เคเฅ เคฒเคฟเค เคฒเคเคฌเคพเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
+ "outputSeparatorDescription": "เคตเคฐเฅเคฃ เคเฅ เคตเคฟเคญเคพเคเคฟเคค เคเคเค เคเฅ เคฌเฅเค เคฐเคเคพ เคเคพเคเคเคพเฅค (เคฏเคน เคกเคฟเคซเคผเฅเคฒเฅเค เคฐเฅเคช เคธเฅ เคจเค เคชเคเคเฅเคคเคฟ \"\\n\" เคนเฅเฅค)",
+ "outputSeparatorOptions": "เคเคเคเคชเฅเค เคตเคฟเคญเคพเคเค เคตเคฟเคเคฒเฅเคช",
+ "regexDescription": "เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคเฅ เคเฅเคเฅเคธเฅเค เคเฅ เคญเคพเคเฅเค เคฎเฅเค เคคเฅเคกเคผเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเค เคเฅ เคเคพเคเคเฅเฅค (เคกเคฟเคซเคผเฅเคฒเฅเค เคฐเฅเคช เคธเฅ เคเค เคธเฅเคชเฅเคธเฅค)",
+ "regexTitle": "เคตเคฟเคญเคพเคเคจ เคเฅ เคฒเคฟเค เคฐเฅเคเฅเคเฅเคธ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
+ "resultTitle": "เคเฅเคเฅเคธเฅเค เคเฅเคเคกเคผเฅ",
+ "shortDescription": "เคตเคฟเคญเคพเคเค เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคชเคพเค เคเฅ เคเค เคญเคพเคเฅเค เคฎเฅเค เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค",
+ "splitSeparatorOptions": "เคตเคฟเคญเคพเคเค เคตเคฟเคเคฒเฅเคช",
+ "symbolDescription": "เคตเคฐเฅเคฃ เคเฅ เคเฅเคเฅเคธเฅเค เคเฅ เคญเคพเคเฅเค เคฎเฅเค เคคเฅเคกเคผเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเค เคเคฟเคฏเคพ เคเคพเคเคเคพเฅค (เคกเคฟเคซเคผเฅเคฒเฅเค เคฐเฅเคช เคธเฅ เคธเฅเคชเฅเคธเฅค)",
+ "symbolTitle": "เคตเคฟเคญเคพเคเคจ เคเฅ เคฒเคฟเค เคชเฅเคฐเคคเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
+ "title": "เคเฅเคเฅเคธเฅเค เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค"
+ },
+ "statistic": {
+ "characterFrequencyAnalysis": "เคตเคฐเฅเคฃ เคเคตเฅเคคเฅเคคเคฟ เคตเคฟเคถเฅเคฒเฅเคทเคฃ",
+ "characterFrequencyAnalysisDescription": "เคเคฃเคจเคพ เคเคฐเฅเค เคเคฟ เคชเฅเคฐเคคเฅเคฏเฅเค เคตเคฐเฅเคฃ เคเฅเคเฅเคธเฅเค เคฎเฅเค เคเคฟเคคเคจเฅ เคฌเคพเคฐ เคฆเคฟเคเคพเค เคฆเฅเคคเคพ เคนเฅ",
+ "delimitersOptions": "เคตเคฟเคญเคพเคเค เคตเคฟเคเคฒเฅเคช",
+ "description": "เคเฅเคเฅเคธเฅเค เคเคพ เคตเคฟเคถเฅเคฒเฅเคทเคฃ เคเคฐเฅเค เคเคฐ เคตเฅเคฏเคพเคชเค เคเคเคเคกเคผเฅ เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเคเฅค",
+ "includeEmptyLines": "เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "includeEmptyLinesDescription": "เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเคฃเคจเคพ เคเคฐเคคเฅ เคธเคฎเคฏ เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค เคเฅเคเฅเคธเฅเค",
+ "resultTitle": "เคเฅเคเฅเคธเฅเค เคเคเคเคกเคผเฅ",
+ "sentenceDelimitersDescription": "เค
เคชเคจเฅ เคญเคพเคทเคพ เคฎเฅเค เคตเคพเคเฅเคฏเฅเค เคเฅ เคตเคฟเคญเคพเคเคฟเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเค เคเคฟเค เคเคพเคจเฅ เคตเคพเคฒเฅ เคเคธเฅเคเคฎ เคตเคฐเฅเคฃ เคฆเคฐเฅเค เคเคฐเฅเค (เคเฅเคฎเคพ เคธเฅ เค
เคฒเค) เคฏเคพ เคกเคฟเคซเคผเฅเคฒเฅเค เคเฅ เคฒเคฟเค เคเคธเฅ เคเคพเคฒเฅ เคเฅเคกเคผ เคฆเฅเคเฅค",
+ "sentenceDelimitersPlaceholder": "เคเฅเคธเฅ ., !, ?, ...",
+ "shortDescription": "เค
เคชเคจเฅ เคชเคพเค เคเฅ เคฌเคพเคฐเฅ เคฎเฅเค เคเคเคเคกเคผเฅ เคชเฅเคฐเคพเคชเฅเคค เคเคฐเฅเค",
+ "statisticsOptions": "เคเคเคเคกเคผเฅ เคตเคฟเคเคฒเฅเคช",
+ "title": "เคเฅเคเฅเคธเฅเค เคเคเคเคกเคผเฅ",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคเฅเคเฅเคธเฅเค เคเคพ เคตเคฟเคถเฅเคฒเฅเคทเคฃ เคเคฐเคจเฅ เคเคฐ เคตเคฐเฅเคฃ เคเคฃเคจเคพ, เคถเคฌเฅเคฆ เคเคฃเคจเคพ, เคชเคเคเฅเคคเคฟ เคเคฃเคจเคพ, เคเคฐ เคตเคฐเฅเคฃเฅเค เคเคฐ เคถเคฌเฅเคฆเฅเค เคเฅ เคเคตเฅเคคเฅเคคเคฟ เคตเคฟเคถเฅเคฒเฅเคทเคฃ เคธเคนเคฟเคค เคตเฅเคฏเคพเคชเค เคเคเคเคกเคผเฅ เคเคคเฅเคชเคจเฅเคจ เคเคฐเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅเฅค",
+ "title": "{{title}} เคเฅเคฏเคพ เคนเฅ?"
+ },
+ "wordDelimitersDescription": "เคถเคฌเฅเคฆเฅเค เคเฅ เคเคฃเคจเคพ เคเฅ เคฒเคฟเค เคเคธเฅเคเคฎ เคฐเฅเคเฅเคเฅเคธ เคฆเคฐเฅเค เคเคฐเฅเค เคฏเคพ เคกเคฟเคซเคผเฅเคฒเฅเค เคเฅ เคฒเคฟเค เคเคธเฅ เคเคพเคฒเฅ เคเฅเคกเคผ เคฆเฅเคเฅค",
+ "wordDelimitersPlaceholder": "เคเฅเคธเฅ \\s.,;:!?\"ยซยป()โฆ",
+ "wordFrequencyAnalysis": "เคถเคฌเฅเคฆ เคเคตเฅเคคเฅเคคเคฟ เคตเคฟเคถเฅเคฒเฅเคทเคฃ",
+ "wordFrequencyAnalysisDescription": "เคเคฃเคจเคพ เคเคฐเฅเค เคเคฟ เคชเฅเคฐเคคเฅเคฏเฅเค เคถเคฌเฅเคฆ เคเฅเคเฅเคธเฅเค เคฎเฅเค เคเคฟเคคเคจเฅ เคฌเคพเคฐ เคฆเคฟเคเคพเค เคฆเฅเคคเคพ เคนเฅ"
+ },
+ "textReplacer": {
+ "description": "เคเฅเคเฅเคธเฅเค เคชเฅเคเคฐเฅเคจ เคเฅ เคจเค เคธเคพเคฎเคเฅเคฐเฅ เคธเฅ เคฌเคฆเคฒเฅเคเฅค",
+ "findPatternInText": "เคเฅเคเฅเคธเฅเค เคฎเฅเค เคฏเคน เคชเฅเคเคฐเฅเคจ เคเฅเคเฅเค",
+ "findPatternUsingRegexp": "เคฐเฅเคเฅเคเฅเคธ เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคชเฅเคเคฐเฅเคจ เคเฅเคเฅเค",
+ "inputTitle": "เคฌเคฆเคฒเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคเฅเคธเฅเค",
+ "newTextPlaceholder": "เคจเคฏเคพ เคเฅเคเฅเคธเฅเค",
+ "regexpDescription": "เคเคธ เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคเฅ เคฆเคฐเฅเค เคเคฐเฅเค เคเคฟเคธเฅ เคเคช เคฌเคฆเคฒเคจเคพ เคเคพเคนเคคเฅ เคนเฅเคเฅค",
+ "replacePatternDescription": "เคชเฅเคฐเคคเคฟเคธเฅเคฅเคพเคชเคจ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคชเฅเคเคฐเฅเคจ เคฆเคฐเฅเค เคเคฐเฅเคเฅค",
+ "replaceText": "เคเฅเคเฅเคธเฅเค เคฌเคฆเคฒเฅเค",
+ "resultTitle": "เคชเฅเคฐเคคเคฟเคธเฅเคฅเคพเคชเคจ เคเฅ เคธเคพเคฅ เคเฅเคเฅเคธเฅเค",
+ "searchPatternDescription": "เคเคธ เคเฅเคเฅเคธเฅเค เคชเฅเคเคฐเฅเคจ เคเฅ เคฆเคฐเฅเค เคเคฐเฅเค เคเคฟเคธเฅ เคเคช เคฌเคฆเคฒเคจเคพ เคเคพเคนเคคเฅ เคนเฅเคเฅค",
+ "searchText": "เคเฅเค เคเฅเคเฅเคธเฅเค",
+ "shortDescription": "เค
เคชเคจเฅ เคธเคพเคฎเคเฅเคฐเฅ เคฎเฅเค เคเฅเคเฅเคธเฅเค เคเฅ เคคเฅเคฐเคเคค เคฌเคฆเคฒเฅเค",
+ "title": "เคเฅเคเฅเคธเฅเค เคฐเคฟเคชเฅเคฒเฅเคธเคฐ",
+ "toolInfo": {
+ "description": "เคเคธ เคธเคฐเคฒ, เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเฅเคฒ เคเฅ เคธเคพเคฅ เค
เคชเคจเฅ เคธเคพเคฎเคเฅเคฐเฅ เคฎเฅเค เคตเคฟเคถเคฟเคทเฅเค เคเฅเคเฅเคธเฅเค เคเฅ เคเคธเคพเคจเฅ เคธเฅ เคฌเคฆเคฒเฅเคเฅค เคฌเคธ เค
เคชเคจเคพ เคเฅเคเฅเคธเฅเค เคเคจเคชเฅเค เคเคฐเฅเค, เคเคธ เคเฅเคเฅเคธเฅเค เคเฅ เคธเฅเค เคเคฐเฅเค เคเคฟเคธเฅ เคเคช เคฌเคฆเคฒเคจเคพ เคเคพเคนเคคเฅ เคนเฅเค เคเคฐ เคชเฅเคฐเคคเคฟเคธเฅเคฅเคพเคชเคจ เคฎเฅเคฒเฅเคฏ, เคเคฐ เคคเฅเคฐเคเคค เค
เคชเคกเฅเคเฅเคก เคธเคเคธเฅเคเคฐเคฃ เคชเฅเคฐเคพเคชเฅเคค เคเคฐเฅเคเฅค",
+ "title": "เคเฅเคเฅเคธเฅเค เคฐเคฟเคชเฅเคฒเฅเคธเคฐ"
+ }
+ },
+ "toMorse": {
+ "dashSymbolDescription": "เคชเฅเคฐเคคเฅเค เคเฅ เคฎเฅเคฐเฅเคธ เคเฅเคก เคฎเฅเค เคกเฅเคถ เคเฅ เค
เคจเฅเคฐเฅเคช เคนเฅเคเคพเฅค",
+ "description": "เคเฅเคเฅเคธเฅเค เคเฅ เคฎเฅเคฐเฅเคธ เคเฅเคก เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "dotSymbolDescription": "เคชเฅเคฐเคคเฅเค เคเฅ เคฎเฅเคฐเฅเคธ เคเฅเคก เคฎเฅเค เคกเฅเค เคเฅ เค
เคจเฅเคฐเฅเคช เคนเฅเคเคพเฅค",
+ "longSignal": "เคฒเคเคฌเคพ เคธเคเคเฅเคค",
+ "resultTitle": "เคฎเฅเคฐเฅเคธ เคเฅเคก",
+ "shortDescription": "เคเฅเคเฅเคธเฅเค เคเฅ เคเคฒเฅเคฆเฅ เคธเฅ เคฎเฅเคฐเฅเคธ เคฎเฅเค เคเคจเคเฅเคก เคเคฐเฅเค",
+ "shortSignal": "เคเฅเคเคพ เคธเคเคเฅเคค",
+ "title": "เคฎเฅเคฐเฅเคธ เคฎเฅเค"
+ },
+ "truncate": {
+ "addTruncationIndicator": "เคเคพเคเคจเฅ เคเคพ เคธเคเคเฅเคคเค เคเฅเคกเคผเฅเค",
+ "charactersPlaceholder": "เคตเคฐเฅเคฃ",
+ "description": "เคเฅเคเฅเคธเฅเค เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคฒเคเคฌเคพเค เคคเค เคเฅเคเคพ เคเคฐเฅเคเฅค",
+ "indicatorDescription": "เคเฅเคเฅเคธเฅเค เคเฅ เค
เคเคค (เคฏเคพ เคถเฅเคฐเฅเคเคค) เคฎเฅเค เคเฅเคกเคผเคจเฅ เคเฅ เคฒเคฟเค เคตเคฐเฅเคฃเฅค เคจเฅเค: เคตเฅ เคฒเคเคฌเคพเค เคเฅ เคเคฐ เคเคฟเคจเฅ เคเคพเคคเฅ เคนเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคเฅเคเฅเคธเฅเค",
+ "leftSideDescription": "เคเฅเคเฅเคธเฅเค เคเฅ เคถเฅเคฐเฅเคเคค เคธเฅ เคตเคฐเฅเคฃ เคนเคเคพเคเคเฅค",
+ "leftSideTruncation": "เคฌเคพเคเค เคคเคฐเคซ เคเคพเคเคจเคพ",
+ "lengthAndLines": "เคฒเคเคฌเคพเค เคเคฐ เคชเคเคเฅเคคเคฟเคฏเคพเค",
+ "lineByLineDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคชเคเคเฅเคคเคฟ เคเฅ เค
เคฒเค เคธเฅ เคเคพเคเฅเคเฅค",
+ "lineByLineTruncating": "เคชเคเคเฅเคคเคฟ เคฆเคฐ เคชเคเคเฅเคคเคฟ เคเคพเคเคจเคพ",
+ "maxLengthDescription": "เคเฅเคเฅเคธเฅเค เคฎเฅเค เคเฅเคกเคผเคจเฅ เคเฅ เคฒเคฟเค เคตเคฐเฅเคฃเฅเค เคเฅ เคธเคเคเฅเคฏเคพเฅค",
+ "numberPlaceholder": "เคธเคเคเฅเคฏเคพ",
+ "resultTitle": "เคเคพเคเคพ เคเคฏเคพ เคเฅเคเฅเคธเฅเค",
+ "rightSideDescription": "เคเฅเคเฅเคธเฅเค เคเฅ เค
เคเคค เคธเฅ เคตเคฐเฅเคฃ เคนเคเคพเคเคเฅค",
+ "rightSideTruncation": "เคฆเคพเคเค เคคเคฐเคซ เคเคพเคเคจเคพ",
+ "shortDescription": "เคชเคพเค เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคฒเคเคฌเคพเค เคคเค เคเฅเคเคพ เคเคฐเฅเค",
+ "suffixAndAffix": "เคชเฅเคฐเคคเฅเคฏเคฏ เคเคฐ เคเคชเคธเคฐเฅเค",
+ "title": "เคเฅเคเฅเคธเฅเค เคเคพเคเฅเค",
+ "toolInfo": {
+ "description": "เคฌเคพเคเค เคเคฐ เคเคจเคชเฅเค เคซเฅเคฐเฅเคฎ เคฎเฅเค เค
เคชเคจเคพ เคเฅเคเฅเคธเฅเค เคฒเฅเคก เคเคฐเฅเค เคเคฐ เคเคชเคเฅ เคฆเคพเคเค เคเคฐ เคธเฅเคตเคเคพเคฒเคฟเคค เคฐเฅเคช เคธเฅ เคเคพเคเคพ เคเคฏเคพ เคเฅเคเฅเคธเฅเค เคฎเคฟเคฒเฅเคเคพเฅค",
+ "title": "เคเฅเคเฅเคธเฅเค เคเคพเคเฅเค"
+ },
+ "truncationSide": "เคเคพเคเคจเฅ เคเฅ เคคเคฐเคซ"
+ },
+ "uppercase": {
+ "description": "เคเฅเคเฅเคธเฅเค เคเฅ เคฌเคกเคผเฅ เค
เคเฅเคทเคฐเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคเฅเคเฅเคธเฅเค",
+ "resultTitle": "เคฌเคกเคผเฅ เค
เคเฅเคทเคฐเฅเค เคฎเฅเค เคเฅเคเฅเคธเฅเค",
+ "shortDescription": "เคชเคพเค เคเฅ เคฌเคกเคผเฅ เค
เคเฅเคทเคฐเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค",
+ "title": "เคฌเคกเคผเฅ เค
เคเฅเคทเคฐเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค"
+ }
+}
diff --git a/public/locales/hi/time.json b/public/locales/hi/time.json
new file mode 100644
index 0000000..b27c976
--- /dev/null
+++ b/public/locales/hi/time.json
@@ -0,0 +1,163 @@
+{
+ "checkLeapYears": {
+ "checkMultiple": "เคเค เคตเคฐเฅเคท เคเคพเคเคเฅเค",
+ "checkOptions": "เคเคพเคเค เคตเคฟเคเคฒเฅเคช",
+ "description": "เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคตเคฐเฅเคทเฅเค เคเฅ เคฒเฅเคช เคตเคฐเฅเคท เคเฅ เคฐเฅเคช เคฎเฅเค เคเคพเคเคเฅเคเฅค",
+ "endPlaceholder": "เคตเคฐเฅเคท",
+ "endYear": "เค
เคเคคเคฟเคฎ เคตเคฐเฅเคท",
+ "inputTitle": "เคเคจเคชเฅเค เคตเคฐเฅเคท",
+ "resultTitle": "เคฒเฅเคช เคตเคฐเฅเคท เคชเคฐเคฟเคฃเคพเคฎ",
+ "shortDescription": "เคเคพเคเคเฅเค เคเคฟ เคเฅเค เคตเคฐเฅเคท เคฒเฅเคช เคตเคฐเฅเคท เคนเฅ เคฏเคพ เคจเคนเฅเค",
+ "startPlaceholder": "เคตเคฐเฅเคท",
+ "startYear": "เคถเฅเคฐเฅเคเคคเฅ เคตเคฐเฅเคท",
+ "title": "เคฒเฅเคช เคตเคฐเฅเคท เคเคพเคเคเฅเค",
+ "toolInfo": {
+ "description": "เคฒเฅเคช เคตเคฐเฅเคท เคตเคน เคตเคฐเฅเคท เคนเฅเคคเคพ เคนเฅ เคเคฟเคธเคฎเฅเค เคเฅเคฒเฅเคเคกเคฐ เคตเคฐเฅเคท เคเฅ เคเคเฅเคฒเฅเคฏ เคตเคฐเฅเคท เคเฅ เคธเคพเคฅ เคธเคฎเคเคพเคฒเคฟเค เคฌเคจเคพเค เคฐเคเคจเฅ เคเฅ เคฒเคฟเค เคเค เค
เคคเคฟเคฐเคฟเคเฅเคค เคฆเคฟเคจ (29 เคซเคผเคฐเคตเคฐเฅ) เคนเฅเคคเคพ เคนเฅเฅค เคฒเฅเคช เคตเคฐเฅเคท เคนเคฐ 4 เคตเคฐเฅเคท เคฎเฅเค เคเคคเฅ เคนเฅเค, เคธเคฟเคตเคพเคฏ เคเคจ เคตเคฐเฅเคทเฅเค เคเฅ เคเฅ 100 เคธเฅ เคตเคฟเคญเคพเคเฅเคฏ เคนเฅเคคเฅ เคนเฅเค เคฒเฅเคเคฟเคจ 400 เคธเฅ เคจเคนเฅเคเฅค",
+ "title": "เคฒเฅเคช เคตเคฐเฅเคท เคเฅเคฏเคพ เคนเฅ?"
+ },
+ "yearRange": "เคตเคฐเฅเคท เคถเฅเคฐเฅเคฃเฅ"
+ },
+ "convertDaysToHours": {
+ "addHoursName": "เคเคเคเฅ เคเคพ เคจเคพเคฎ เคเฅเคกเคผเฅเค",
+ "addHoursNameDescription": "เคเคเคเคชเฅเค เคฎเคพเคจเฅเค เคฎเฅเค เคธเฅเคเฅเคฐเคฟเคเค เคเคเคเฅ เคเฅเคกเคผเฅเค",
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "decimalPlaces": "เคฆเคถเคฎเคฒเคต เคธเฅเคฅเคพเคจ",
+ "description": "เคฆเคฟเคจเฅเค เคเฅ เคธเคเคเฅเคฏเคพ เคเฅ เคเคเคเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "hoursName": "เคเคเคเฅเค เคเคพ เคจเคพเคฎ",
+ "inputTitle": "เคเคจเคชเฅเค เคฆเคฟเคจ",
+ "placesPlaceholder": "เคธเฅเคฅเคพเคจ",
+ "resultTitle": "เคเคเคเฅ",
+ "shortDescription": "เคฆเคฟเคจเฅเค เคเฅ เคเคเคเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค",
+ "showBreakdown": "เคตเคฟเคธเฅเคคเฅเคค เคตเคฟเคตเคฐเคฃ เคฆเคฟเคเคพเคเค",
+ "title": "เคฆเคฟเคจเฅเค เคเฅ เคเคเคเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคฆเคฟเคจเฅเค เคเฅ เคเคเคเฅเค เคฎเฅเค เคฌเคฆเคฒเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคฆเคฟเคจเฅเค เคเฅ เคธเคเคเฅเคฏเคพเคเค เคฏเคพ เคเคเคพเคเคฏเฅเค เคเฅ เคฐเฅเคช เคฎเฅเค เคเคจเคชเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค, เคเคฐ เคฏเคน เคเฅเคฒ เคเคจเฅเคนเฅเค เคเคเคเฅเค เคฎเฅเค เคฌเคฆเคฒ เคฆเฅเคเคพเฅค เคเคช เคเคเคเคชเฅเค เคฎเคพเคจเฅเค เคฎเฅเค 'เคเคเคเฅ' เคชเฅเคฐเคคเฅเคฏเคฏ เคญเฅ เคเฅเคกเคผ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "title": "เคฆเคฟเคจเฅเค เคเฅ เคเคเคเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค"
+ }
+ },
+ "convertHoursToDays": {
+ "addDaysName": "เคฆเคฟเคจ เคเคพ เคจเคพเคฎ เคเฅเคกเคผเฅเค",
+ "addDaysNameDescription": "เคเคเคเคชเฅเค เคฎเคพเคจเฅเค เคฎเฅเค เคธเฅเคเฅเคฐเคฟเคเค days เคเฅเคกเคผเฅเค",
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "daysName": "เคฆเคฟเคจ เคเคพ เคจเคพเคฎ",
+ "decimalPlaces": "เคฆเคถเคฎเคฒเคต เคธเฅเคฅเคพเคจ",
+ "description": "เคเคเคเฅเค เคเฅ เคธเคเคเฅเคฏเคพ เคเฅ เคฆเคฟเคจเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคเคเคเฅ",
+ "placesPlaceholder": "เคธเฅเคฅเคพเคจ",
+ "resultTitle": "เคฆเคฟเคจ",
+ "shortDescription": "เคเคเคเฅเค เคเฅ เคฆเคฟเคจเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค",
+ "showBreakdown": "เคตเคฟเคธเฅเคคเฅเคค เคตเคฟเคตเคฐเคฃ เคฆเคฟเคเคพเคเค",
+ "title": "เคเคเคเฅเค เคเฅ เคฆเคฟเคจเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคเคเคเฅเค เคเฅ เคฆเคฟเคจเฅเค เคฎเฅเค เคฌเคฆเคฒเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคเคเคเฅเค เคเฅ เคธเคเคเฅเคฏเคพเคเค เคฏเคพ เคเคเคพเคเคฏเฅเค เคเฅ เคฐเฅเคช เคฎเฅเค เคเคจเคชเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค, เคเคฐ เคฏเคน เคเฅเคฒ เคเคจเฅเคนเฅเค เคฆเคฟเคจเฅเค เคฎเฅเค เคฌเคฆเคฒ เคฆเฅเคเคพเฅค เคเคช เคเคเคเคชเฅเค เคฎเคพเคจเฅเค เคฎเฅเค 'เคฆเคฟเคจ' เคชเฅเคฐเคคเฅเคฏเคฏ เคญเฅ เคเฅเคกเคผ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "title": "เคเคเคเฅเค เคเฅ เคฆเคฟเคจเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค"
+ }
+ },
+ "convertSecondsToTime": {
+ "addPadding": "เคชเฅเคกเคฟเคเค เคเฅเคกเคผเฅเค",
+ "addPaddingDescription": "เคเคเคเฅ, เคฎเคฟเคจเค เคเคฐ เคธเฅเคเคเคก เคฎเฅเค เคถเฅเคจเฅเคฏ เคชเฅเคกเคฟเคเค เคเฅเคกเคผเฅเคเฅค",
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "เคธเฅเคเคเคก เคเฅ เคธเคเคเฅเคฏเคพ เคเฅ เคชเค เคจเฅเคฏ เคธเคฎเคฏ เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "formatDHMS": "เคฆเคฟเคจ:เคเคเคเฅ:เคฎเคฟเคจเค:เคธเฅเคเคเคก",
+ "formatHMS": "เคเคเคเฅ:เคฎเคฟเคจเค:เคธเฅเคเคเคก",
+ "inputTitle": "เคเคจเคชเฅเค เคธเฅเคเคเคก",
+ "resultTitle": "เคธเคฎเคฏ",
+ "shortDescription": "เคธเฅเคเคเคก เคเฅ เคธเคฎเคฏ เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค",
+ "showZeroValues": "เคถเฅเคจเฅเคฏ เคฎเคพเคจ เคฆเคฟเคเคพเคเค",
+ "timeFormat": "เคธเคฎเคฏ เคชเฅเคฐเคพเคฐเฅเคช",
+ "timePadding": "เคธเคฎเคฏ เคชเฅเคกเคฟเคเค",
+ "title": "เคธเฅเคเคเคก เคเฅ เคธเคฎเคฏ เคฎเฅเค เคฌเคฆเคฒเฅเค",
+ "toolInfo": {
+ "title": "{{title}} เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "convertTimeToSeconds": {
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "เคธเคฎเคฏ เคชเฅเคฐเคพเคฐเฅเคช เคเฅ เคธเฅเคเคเคก เคเฅ เคธเคเคเฅเคฏเคพ เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "formatDHMS": "เคฆเคฟเคจ:เคเคเคเฅ:เคฎเคฟเคจเค:เคธเฅเคเคเคก",
+ "formatHMS": "เคเคเคเฅ:เคฎเคฟเคจเค:เคธเฅเคเคเคก",
+ "inputPlaceholder": "เคเฅเคธเฅ 1:30:45 เคฏเคพ 1d 2h 30m 45s",
+ "inputTitle": "เคเคจเคชเฅเค เคธเคฎเคฏ",
+ "resultTitle": "เคธเฅเคเคเคก",
+ "shortDescription": "เคธเคฎเคฏ เคชเฅเคฐเคพเคฐเฅเคช เคเฅ เคธเฅเคเคเคก เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคเคฐเฅเค",
+ "timeFormat": "เคธเคฎเคฏ เคชเฅเคฐเคพเคฐเฅเคช",
+ "title": "เคธเคฎเคฏ เคเฅ เคธเฅเคเคเคก เคฎเฅเค เคฌเคฆเคฒเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคซเคผเฅเคฐเฅเคฎเฅเค เคเคฟเค เคเค เคธเคฎเคฏ เคธเฅเคเฅเคฐเคฟเคเค (HH:MM:SS) เคเฅ เคธเฅเคเคเคก เคฎเฅเค เคฌเคฆเคฒเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคฏเคน เค
เคตเคงเคฟ เคเคฐ เคธเคฎเคฏ เค
เคเคคเคฐเคพเคฒ เคเฅ เคเคฃเคจเคพ เคเฅ เคฒเคฟเค เคเคชเคฏเฅเคเฅ เคนเฅเฅค",
+ "title": "เคธเคฎเคฏ เคเฅ เคธเฅเคเคเคก เคฎเฅเค เคฌเคฆเคฒเฅเค"
+ }
+ },
+ "crontabGuru": {
+ "countPlaceholder": "เคธเคเคเฅเคฏเคพ",
+ "cronOptions": "Cron เคตเคฟเคเคฒเฅเคช",
+ "description": "Cron เคเคเฅเคธเคชเฅเคฐเฅเคถเคจ เคเฅ เคฎเคพเคจเคต-เคชเค เคจเฅเคฏ เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "expressionPlaceholder": "เคเฅเคธเฅ */5 * * * *",
+ "inputTitle": "เคเคจเคชเฅเค Cron เคเคเฅเคธเคชเฅเคฐเฅเคถเคจ",
+ "resultTitle": "เคฎเคพเคจเคต-เคชเค เคจเฅเคฏ เคตเคฟเคตเคฐเคฃ",
+ "runCount": "เคฐเคจ เคเฅ เคธเคเคเฅเคฏเคพ",
+ "shortDescription": "เคเฅเคฐเฅเคจ เคเคเฅเคธเคชเฅเคฐเฅเคถเคจ เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค เคเคฐ เคธเคฎเคเฅเค",
+ "showNextRuns": "เค
เคเคฒเฅ เคฐเคจ เคฆเคฟเคเคพเคเค",
+ "title": "Crontab เคเฅเคฐเฅ"
+ },
+ "timeBetweenDates": {
+ "dateOptions": "เคคเคฟเคฅเคฟ เคตเคฟเคเคฒเฅเคช",
+ "description": "เคฆเฅ เคคเคฟเคฅเคฟเคฏเฅเค เคเฅ เคฌเฅเค เคเคพ เคธเคฎเคฏ เค
เคเคคเคฐเคพเคฒ เคเฅเคเคพเคค เคเคฐเฅเคเฅค",
+ "endDate": "เค
เคเคคเคฟเคฎ เคคเคฟเคฅเคฟ",
+ "endDatePlaceholder": "YYYY-MM-DD",
+ "endDateTime": "เคธเคฎเคพเคชเฅเคคเคฟ เคคเคฟเคฅเคฟ เคเคฐ เคธเคฎเคฏ",
+ "endTime": "เค
เคเคคเคฟเคฎ เคธเคฎเคฏ",
+ "endTimePlaceholder": "HH:MM:SS",
+ "endTimezone": "เคธเคฎเคพเคชเฅเคคเคฟ เคธเคฎเคฏ เคเฅเคทเฅเคคเฅเคฐ",
+ "formatDays": "เคฆเคฟเคจ",
+ "formatHours": "เคเคเคเฅ",
+ "formatMinutes": "เคฎเคฟเคจเค",
+ "formatSeconds": "เคธเฅเคเคเคก",
+ "includeTime": "เคธเคฎเคฏ เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
+ "inputTitle": "เคคเคฟเคฅเคฟ เคเฅเคกเคผเฅ",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "resultTitle": "เคธเคฎเคฏ เค
เคเคคเคฐเคพเคฒ",
+ "shortDescription": "เคฆเฅ เคคเคฟเคฅเคฟเคฏเฅเค เคเฅ เคฌเฅเค เคเคพ เคธเคฎเคฏ เคเคฃเคจเคพ เคเคฐเฅเค",
+ "startDate": "เคถเฅเคฐเฅเคเคคเฅ เคคเคฟเคฅเคฟ",
+ "startDatePlaceholder": "YYYY-MM-DD",
+ "startDateTime": "เคชเฅเคฐเคพเคฐเคเคญ เคคเคฟเคฅเคฟ เคเคฐ เคธเคฎเคฏ",
+ "startTime": "เคถเฅเคฐเฅเคเคคเฅ เคธเคฎเคฏ",
+ "startTimePlaceholder": "HH:MM:SS",
+ "startTimezone": "เคชเฅเคฐเคพเคฐเคเคญ เคธเคฎเคฏ เคเฅเคทเฅเคคเฅเคฐ",
+ "title": "เคคเคฟเคฅเคฟเคฏเฅเค เคเฅ เคฌเฅเค เคธเคฎเคฏ",
+ "toolInfo": {
+ "description": "เคตเคฟเคญเคฟเคจเฅเคจ เคธเคฎเคฏ เคเฅเคทเฅเคคเฅเคฐเฅเค เคเฅ เคธเคฎเคฐเฅเคฅเคจ เคเฅ เคธเคพเคฅ, เคฆเฅ เคคเคฟเคฅเคฟเคฏเฅเค เคเคฐ เคธเคฎเคฏเฅเค เคเฅ เคฌเฅเค เคธเคเฅเค เคธเคฎเคฏ เค
เคเคคเคฐ เคเฅ เคเคฃเคจเคพ เคเคฐเฅเคเฅค เคฏเคน เคเฅเคฒ เคตเคฟเคญเคฟเคจเฅเคจ เคเคเคพเคเคฏเฅเค (เคตเคฐเฅเคท, เคฎเคนเฅเคจเฅ, เคฆเคฟเคจ, เคเคเคเฅ, เคฎเคฟเคจเค เคเคฐ เคธเฅเคเคเคก) เคฎเฅเค เคธเคฎเคฏ เค
เคเคคเคฐ เคเคพ เคตเคฟเคธเฅเคคเฅเคค เคตเคฟเคตเคฐเคฃ เคชเฅเคฐเคฆเคพเคจ เคเคฐเคคเคพ เคนเฅเฅค",
+ "title": "เคคเคฟเคฅเคฟเคฏเฅเค เคเฅ เคฌเฅเค เคเคพ เคธเคฎเคฏ เคเฅเคฒเคเฅเคฒเฅเคเคฐ"
+ }
+ },
+ "truncateClockTime": {
+ "description": "เคธเคฎเคฏ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคธเฅเคคเคฐ เคคเค เคเคพเคเฅเคเฅค",
+ "format12Hour": "12 เคเคเคเฅ เคชเฅเคฐเคพเคฐเฅเคช",
+ "format24Hour": "24 เคเคเคเฅ เคชเฅเคฐเคพเคฐเฅเคช",
+ "inputTitle": "เคเคจเคชเฅเค เคธเคฎเคฏ",
+ "printDroppedComponents": "เคเคฟเคฐเฅ เคนเฅเค เคเคเคเฅเค เคเฅ เคชเฅเคฐเคฟเคเค เคเคฐเฅเค",
+ "resultTitle": "เคเคพเคเคพ เคเคฏเคพ เคธเคฎเคฏ",
+ "roundDown": "เคจเฅเคเฅ เคเฅเคฒ เคเคฐเฅเค",
+ "roundUp": "เคเคชเคฐ เคเฅเคฒ เคเคฐเฅเค",
+ "shortDescription": "เคเคกเคผเฅ เคเฅ เคธเคฎเคฏ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคชเคฐเคฟเคถเฅเคฆเฅเคงเคคเคพ เคคเค เคเฅเคเคพ เคเคฐเฅเค",
+ "timeFormat": "เคธเคฎเคฏ เคชเฅเคฐเคพเคฐเฅเคช",
+ "timePadding": "เคธเคฎเคฏ เคชเฅเคกเคฟเคเค",
+ "title": "เคเคกเคผเฅ เคเคพ เคธเคฎเคฏ เคเคพเคเฅเค",
+ "toolInfo": {
+ "title": "{{title}} เคเฅเคฏเคพ เคนเฅ?"
+ },
+ "truncateMinutesAndSeconds": "เคฎเคฟเคจเค เคเคฐ เคธเฅเคเคเคก เคเฅ เคเฅเคเคพ เคเคฐเฅเค",
+ "truncateMinutesAndSecondsDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคเคกเคผเฅ เคเฅ เคธเคฎเคฏ เคธเฅ เคฎเคฟเคจเค เคเคฐ เคธเฅเคเคเคก เคฆเฅเคจเฅเค เคเคเคเฅเค เคเฅ เคนเคเคพ เคฆเฅเคเฅค",
+ "truncateOnlySeconds": "เคเฅเคตเคฒ เคธเฅเคเคเคก เคเคพเคเฅเค",
+ "truncateOnlySecondsDescription": "เคชเฅเคฐเคคเฅเคฏเฅเค เคเคกเคผเฅ เคเฅ เคธเคฎเคฏ เคธเฅ เคธเฅเคเคเคก เคเคเค เคนเคเคพ เคฆเฅเคเฅค",
+ "truncateTo": "เคเคพเคเคจเฅ เคเคพ เคธเฅเคคเคฐ",
+ "truncateToHours": "เคเคเคเฅ",
+ "truncateToMinutes": "เคฎเคฟเคจเค",
+ "truncateToSeconds": "เคธเฅเคเคเคก",
+ "truncationOptions": "เคเคพเคเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "truncationSide": "เคเคพเคเคจเฅ เคเฅ เคคเคฐเคซ",
+ "useZeroPadding": "เคถเฅเคจเฅเคฏ เคชเฅเคกเคฟเคเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
+ "zeroPaddingDescription": "เคธเคญเฅ เคธเคฎเคฏ เคเคเคเฅเค เคเฅ เคนเคฎเฅเคถเคพ เคฆเฅ เค
เคเค เคเฅเคกเคผเคพ เคฐเคเฅเคเฅค",
+ "zeroPrintDescription": "เคเคฟเคฐเคพเค เคเค เคญเคพเคเฅเค เคเฅ เคถเฅเคจเฅเคฏ เคฎเคพเคจ \"00\" เคเฅ เคฐเฅเคช เคฎเฅเค เคชเฅเคฐเคฆเคฐเฅเคถเคฟเคค เคเคฐเฅเคเฅค",
+ "zeroPrintTruncatedParts": "เคถเฅเคจเฅเคฏ-เคฎเฅเคฆเฅเคฐเคฟเคค เคเคพเคเฅ เคเค เคญเคพเค"
+ }
+}
diff --git a/public/locales/hi/translation.json b/public/locales/hi/translation.json
new file mode 100644
index 0000000..84b4bf0
--- /dev/null
+++ b/public/locales/hi/translation.json
@@ -0,0 +1,250 @@
+{
+ "audio": {
+ "changeSpeed": {
+ "description": "เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคชเฅเคฒเฅเคฌเฅเค เคเคคเคฟ เคฌเคฆเคฒเฅเคเฅค เคชเคฟเค เคฌเคจเคพเค เคฐเคเคคเฅ เคนเฅเค เคเคกเคฟเคฏเฅ เคเฅ เคคเฅเคเคผ เคฏเคพ เคงเฅเคฎเคพ เคเคฐเฅเคเฅค",
+ "name": "เคเคกเคฟเคฏเฅ เคเคคเคฟ เคฌเคฆเคฒเฅเค",
+ "shortDescription": "เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเคคเคฟ เคฌเคฆเคฒเฅเค"
+ },
+ "extractAudio": {
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒ เคธเฅ เคเคกเคฟเคฏเฅ เคเฅเคฐเฅเค เคจเคฟเคเคพเคฒเฅเค เคเคฐ เคเคธเฅ เค
เคชเคจเฅ เคเฅเคจเฅ เคนเฅเค เคชเฅเคฐเคพเคฐเฅเคช (เคเคเคธเฅ, เคเคฎเคชเฅ3, เคกเคฌเฅเคฒเฅเคฏเฅเคเคตเฅ) เคฎเฅเค เคเค เค
เคฒเค เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒ เคเฅ เคฐเฅเคช เคฎเฅเค เคธเคนเฅเคเฅเคเฅค",
+ "name": "เคเคกเคฟเคฏเฅ เคจเคฟเคเคพเคฒเฅเค",
+ "shortDescription": "เคตเฅเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค (เคเคฎเคชเฅ4, เคเคฎเคเคตเฅ, เคเคฆเคฟ) เคธเฅ เคเคกเคฟเคฏเฅ เคจเคฟเคเคพเคฒเฅเค เคเคเคธเฅ, เคเคฎเคชเฅ3, เคฏเคพ เคกเคฌเฅเคฒเฅเคฏเฅเคเคตเฅ เคฎเฅเคเฅค"
+ }
+ },
+ "baseFileInput": {
+ "copyFailed": "เคเฅเคชเฅ เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒ: {{error}}",
+ "dropFileHere": "เคฏเคนเคพเค เค
เคชเคจเฅ {{type}} เคกเคพเคฒเฅเค",
+ "fileCopied": "เคซเคผเคพเคเคฒ เคเฅเคชเฅ เคเฅ เคเค",
+ "selectFileDescription": "เคฏเคนเคพเค เคเฅเคฒเคฟเค เคเคฐเฅเค เค
เคชเคจเฅ เคกเคฟเคตเคพเคเคธ เคธเฅ {{type}} เคเฅเคจเคจเฅ เคเฅ เคฒเคฟเค, Ctrl+V เคฆเคฌเคพเคเค เคเฅเคฒเคฟเคชเคฌเฅเคฐเฅเคก เคธเฅ {{type}} เคเคพ เคเคชเคฏเฅเค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค, เคฏเคพ เคกเฅเคธเฅเคเคเฅเคช เคธเฅ เคซเคผเคพเคเคฒ เคเฅ เคเฅเคเคเคเคฐ เคกเคพเคฒเฅเค"
+ },
+ "categories": {
+ "audio": {
+ "description": "เคเคกเคฟเคฏเฅ เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ โ เคตเฅเคกเคฟเคฏเฅ เคธเฅ เคเคกเคฟเคฏเฅ เคจเคฟเคเคพเคฒเฅเค, เคเคกเคฟเคฏเฅ เคเคคเคฟ เคธเคฎเคพเคฏเฅเคเคฟเคค เคเคฐเฅเค, เคเค เคเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคฎเคฐเฅเค เคเคฐเฅเค เคเคฐ เคฌเคนเฅเคค เคเฅเคเฅค",
+ "title": "เคเคกเคฟเคฏเฅ เคเฅเคฒเฅเคธ"
+ },
+ "csv": {
+ "description": "CSV เคซเคผเคพเคเคฒเฅเค เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ - CSV เคเฅ เคตเคฟเคญเคฟเคจเฅเคจ เคชเฅเคฐเคพเคฐเฅเคชเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค, CSV เคกเฅเคเคพ เคฎเฅเค เคนเฅเคฐเคซเฅเคฐ เคเคฐเฅเค, CSV เคธเคเคฐเคเคจเคพ เคเฅ เคฎเคพเคจเฅเคฏ เคเคฐเฅเค, เคเคฐ CSV เคซเคผเคพเคเคฒเฅเค เคเฅ เคเฅเคถเคฒเคคเคพเคชเฅเคฐเฅเคตเค เคธเคเคธเคพเคงเคฟเคค เคเคฐเฅเคเฅค",
+ "title": "CSV เคเฅเคฒเฅเคธ"
+ },
+ "gif": {
+ "description": "GIF เคเคจเคฟเคฎเฅเคถเคจ เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ โ เคชเคพเคฐเคฆเคฐเฅเคถเฅ GIF เคฌเคจเคพเคเค, GIF เคซเฅเคฐเฅเคฎ เคจเคฟเคเคพเคฒเฅเค, GIF เคฎเฅเค เคเฅเคเฅเคธเฅเค เคเฅเคกเคผเฅเค, เคเฅเคฐเฅเคช, เคเฅเคฎเคพเคเค, GIF เคเฅ เคเคฒเคเคพ เคเคฐเฅเค, เคเคฐ เคฌเคนเฅเคค เคเฅเคเฅค",
+ "title": "GIF เคเฅเคฒเฅเคธ"
+ },
+ "image-generic": {
+ "description": "เคเคฟเคคเฅเคฐเฅเค เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ โ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค, เคเคเคพเคฐ เคฌเคฆเคฒเฅเค, เคเฅเคฐเฅเคช เคเคฐเฅเค, JPG เคฎเฅเค เคฌเคฆเคฒเฅเค, เคเฅเคฎเคพเคเค, เคชเฅเคทเฅเค เคญเฅเคฎเคฟ เคนเคเคพเคเค เคเคฐ เคฌเคนเฅเคค เคเฅเคเฅค",
+ "title": "เคเคตเคฟ เคเฅเคฒเฅเคธ"
+ },
+ "json": {
+ "description": "JSON เคกเฅเคเคพ เคธเคเคฐเคเคจเคพเคเค เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ โ JSON เคเคฌเฅเคเฅเคเฅเค เคเฅ เคธเฅเคเคฆเคฐ เคเคฐ เคธเคเคเฅเคทเคฟเคชเฅเคค เคเคฐเฅเค, JSON เคธเคฐเคฃเคฟเคฏเฅเค เคเฅ เคธเคฎเคคเคฒ เคเคฐเฅเค, JSON เคฎเฅเคฒเฅเคฏเฅเค เคเฅ เคธเฅเคเฅเคฐเคฟเคเคเคฟเคซเคพเค เคเคฐเฅเค, เคกเฅเคเคพ เคเคพ เคตเคฟเคถเฅเคฒเฅเคทเคฃ เคเคฐเฅเค, เคเคฐ เคฌเคนเฅเคค เคเฅเค",
+ "title": "JSON เคเฅเคฒเฅเคธ"
+ },
+ "list": {
+ "description": "เคธเฅเคเคฟเคฏเฅเค เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ โ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค, เคเคฒเคเคพ เคเคฐเฅเค, เคธเฅเคเคฟเคฏเฅเค เคเฅ เคฏเคพเคฆเฅเคเฅเคเคฟเค เคเคฐเฅเค, เค
เคฆเฅเคตเคฟเคคเฅเคฏ เคเคฐ เคกเฅเคชเฅเคฒเคฟเคเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคเฅเคเฅเค, เคธเฅเคเฅ เคเคเคเคฎ เคตเคฟเคญเคพเคเค เคฌเคฆเคฒเฅเค, เคเคฐ เคฌเคนเฅเคค เคเฅเคเฅค",
+ "title": "เคธเฅเคเฅ เคเฅเคฒเฅเคธ"
+ },
+ "number": {
+ "description": "เคธเคเคเฅเคฏเคพเคเค เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ โ เคธเคเคเฅเคฏเคพ เค
เคจเฅเคเฅเคฐเคฎ เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค, เคธเคเคเฅเคฏเคพเคเค เคเฅ เคถเคฌเฅเคฆเฅเค เคฎเฅเค เคเคฐ เคถเคฌเฅเคฆเฅเค เคเฅ เคธเคเคเฅเคฏเคพเคเค เคฎเฅเค เคฌเคฆเคฒเฅเค, เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค, เคเฅเคฒ เคเคฐเฅเค, เคธเคเคเฅเคฏเคพเคเค เคเคพ เคเฅเคฃเคจเคเคเคก เคเคฐเฅเค, เคเคฐ เคฌเคนเฅเคค เคเฅเคเฅค",
+ "title": "เคธเคเคเฅเคฏเคพ เคเฅเคฒเฅเคธ"
+ },
+ "pdf": {
+ "description": "PDF เคซเคผเคพเคเคฒเฅเค เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ - PDF เคธเฅ เคเฅเคเฅเคธเฅเค เคจเคฟเคเคพเคฒเฅเค, PDF เคเฅ เค
เคจเฅเคฏ เคชเฅเคฐเคพเคฐเฅเคชเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค, PDF เคฎเฅเค เคนเฅเคฐเคซเฅเคฐ เคเคฐเฅเค, เคเคฐ เคฌเคนเฅเคค เคเฅเคเฅค",
+ "title": "PDF เคเฅเคฒเฅเคธ"
+ },
+ "png": {
+ "description": "PNG เคเคตเคฟเคฏเฅเค เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ โ PNG เคเฅ JPG เคฎเฅเค เคฌเคฆเคฒเฅเค, เคชเคพเคฐเคฆเคฐเฅเคถเฅ PNG เคฌเคจเคพเคเค, PNG เคฐเคเค เคฌเคฆเคฒเฅเค, เคเฅเคฐเฅเคช, เคเฅเคฎเคพเคเค, PNG เคเคพ เคเคเคพเคฐ เคฌเคฆเคฒเฅเค, เคเคฐ เคฌเคนเฅเคค เคเฅเคเฅค",
+ "title": "PNG เคเฅเคฒเฅเคธ"
+ },
+ "seeAll": "เคธเคญเฅ {{title}} เคฆเฅเคเฅเค",
+ "string": {
+ "description": "เคเฅเคเฅเคธเฅเค เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ โ เคเฅเคเฅเคธเฅเค เคเฅ เคเคตเคฟเคฏเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค, เคเฅเคเฅเคธเฅเค เคเฅเคเฅเค เคเคฐ เคฌเคฆเคฒเฅเค, เคเฅเคเฅเคธเฅเค เคเฅ เคเฅเคเคกเคผเฅเค เคฎเฅเค เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค, เคเฅเคเฅเคธเฅเค เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเฅเคกเคผเฅเค, เคเฅเคเฅเคธเฅเค เคฆเฅเคนเคฐเคพเคเค, เคเคฐ เคฌเคนเฅเคค เคเฅเคเฅค",
+ "title": "เคเฅเคเฅเคธเฅเค เคเฅเคฒเฅเคธ"
+ },
+ "time": {
+ "description": "เคธเคฎเคฏ เคเคฐ เคคเคฟเคฅเคฟ เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ โ เคธเคฎเคฏ เค
เคเคคเคฐ เคเฅ เคเคฃเคจเคพ เคเคฐเฅเค, เคธเคฎเคฏ เคเฅเคทเฅเคคเฅเคฐเฅเค เคเฅ เคฌเฅเค เคฌเคฆเคฒเฅเค, เคคเคฟเคฅเคฟเคฏเฅเค เคเฅ เคซเฅเคฐเฅเคฎเฅเค เคเคฐเฅเค, เคคเคฟเคฅเคฟ เค
เคจเฅเคเฅเคฐเคฎ เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค, เคเคฐ เคฌเคนเฅเคค เคเฅเคเฅค",
+ "title": "เคธเคฎเคฏ เคเฅเคฒเฅเคธ"
+ },
+ "try": "{{title}} เคเคเคผเคฎเคพเคเค",
+ "video": {
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ โ เคตเฅเคกเคฟเคฏเฅ เคธเฅ เคซเฅเคฐเฅเคฎ เคจเคฟเคเคพเคฒเฅเค, เคตเฅเคกเคฟเคฏเฅ เคธเฅ GIF เคฌเคจเคพเคเค, เคตเฅเคกเคฟเคฏเฅ เคเฅ เคตเคฟเคญเคฟเคจเฅเคจ เคชเฅเคฐเคพเคฐเฅเคชเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค, เคเคฐ เคฌเคนเฅเคค เคเฅเคเฅค",
+ "title": "เคตเฅเคกเคฟเคฏเฅ เคเฅเคฒเฅเคธ"
+ },
+ "xml": {
+ "description": "XML เคกเฅเคเคพ เคธเคเคฐเคเคจเคพเคเค เคเฅ เคธเคพเคฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเฅเคธ - เคตเฅเคฏเฅเค
เคฐ, เคฌเฅเคฏเฅเคเคฟเคซเคพเคฏเคฐ, เคตเฅเคฒเคฟเคกเฅเคเคฐ เคเคฐ เคฌเคนเฅเคค เคเฅเค",
+ "title": "XML เคเฅเคฒเฅเคธ"
+ }
+ },
+ "csv": {
+ "findIncompleteCsvRecords": {
+ "description": "เคฌเคธ เคจเฅเคเฅ เคซเฅเคฐเฅเคฎ เคฎเฅเค เค
เคชเคจเฅ เคธเฅเคเคธเคตเฅ เคซเคผเคพเคเคฒ เค
เคชเคฒเฅเคก เคเคฐเฅเค เคเคฐ เคฏเคน เคเฅเคฒ เคธเฅเคตเคเคพเคฒเคฟเคค เคฐเฅเคช เคธเฅ เคเคพเคเค เคเคฐเฅเคเคพ เคเคฟ เคเฅเคฏเคพ เคเฅเค เคชเคเคเฅเคคเคฟ เคฏเคพ เคธเฅเคคเคเคญ เคฎเฅเคฒเฅเคฏ เคจเคนเฅเค เคเฅ เคฐเคนเฅ เคนเฅเคเฅค เคเฅเคฒ เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค, เคเคช เคเคจเคชเฅเค เคซเคผเคพเคเคฒ เคชเฅเคฐเคพเคฐเฅเคช เคเฅ เคธเคฎเคพเคฏเฅเคเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเค (เคตเคฟเคญเคพเคเค, เคเคฆเฅเคงเคฐเคฃ เคตเคฐเฅเคฃ, เคเคฐ เคเคฟเคชเฅเคชเคฃเฅ เคตเคฐเฅเคฃ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเฅเค)เฅค เคเคธเคเฅ เค
เคคเคฟเคฐเคฟเคเฅเคค, เคเคช เคเคพเคฒเฅ เคฎเฅเคฒเฅเคฏเฅเค เคเฅ เคเคพเคเค เคธเคเฅเคทเคฎ เคเคฐ เคธเคเคคเฅ เคนเฅเค, เคเคพเคฒเฅ เคชเคเคเฅเคคเคฟเคฏเฅเค เคเฅ เคเฅเคกเคผ เคธเคเคคเฅ เคนเฅเค, เคเคฐ เคเคเคเคชเฅเค เคฎเฅเค เคคเฅเคฐเฅเคเคฟ เคธเคเคฆเฅเคถเฅเค เคเฅ เคธเคเคเฅเคฏเคพ เคชเคฐ เคธเฅเคฎเคพ เคจเคฟเคฐเฅเคงเคพเคฐเคฟเคค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "name": "เค
เคงเฅเคฐเฅ เคธเฅเคเคธเคตเฅ เคฐเคฟเคเฅเคฐเฅเคก เคเฅเคเฅเค",
+ "shortDescription": "เคธเฅเคเคธเคตเฅ เคฎเฅเค เคเคฒเฅเคฆเฅ เคธเฅ เคชเคเคเฅเคคเคฟเคฏเคพเค เคเคฐ เคธเฅเคคเคเคญ เคเฅเคเฅเค เคเฅ เคฎเฅเคฒเฅเคฏ เคเฅ เคฐเคนเฅ เคนเฅเคเฅค"
+ }
+ },
+ "hero": {
+ "brand": "เคเคฎเคจเฅเคเฅเคฒเฅเคธ",
+ "description": "เคเคฎเคจเฅเคเฅเคฒเฅเคธ เคเฅ เคธเคพเคฅ เค
เคชเคจเฅ เคเคคเฅเคชเคพเคฆเคเคคเคพ เคฌเคขเคผเคพเคเค, เคเคฒเฅเคฆเฅ เคเคพเคฎ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เค
เคเคคเคฟเคฎ เคเฅเคฒเคเคฟเค! เคเคตเคฟเคฏเฅเค, เคเฅเคเฅเคธเฅเค, เคธเฅเคเคฟเคฏเฅเค เคเคฐ เคกเฅเคเคพ เคเฅ เคธเคเคชเคพเคฆเคฟเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคนเคเคพเคฐเฅเค เคเคชเคฏเฅเคเคเคฐเฅเคคเคพ-เค
เคจเฅเคเฅเคฒ เคเคชเคฏเฅเคเคฟเคคเคพเคเค เคคเค เคชเคนเฅเคเคเฅเค, เคธเคญเฅ เคธเฅเคงเฅ เค
เคชเคจเฅ เคฌเฅเคฐเคพเคเคเคผเคฐ เคธเฅเฅค",
+ "examples": {
+ "calculateNumberSum": "เคธเคเคเฅเคฏเคพเคเค เคเคพ เคฏเฅเค เคเคฐเฅเค",
+ "changeGifSpeed": "GIF เคเคคเคฟ เคฌเคฆเคฒเฅเค",
+ "compressPng": "PNG เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค",
+ "createTransparentImage": "เคชเคพเคฐเคฆเคฐเฅเคถเฅ เคเคตเคฟ เคฌเคจเคพเคเค",
+ "prettifyJson": "JSON เคธเฅเคเคฆเคฐ เคฌเคจเคพเคเค",
+ "sortList": "เคธเฅเคเฅ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "splitPdf": "PDF เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค",
+ "splitText": "เคเฅเคเฅเคธเฅเค เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค",
+ "trimVideo": "เคตเฅเคกเคฟเคฏเฅ เคเฅเคฐเคฟเคฎ เคเคฐเฅเค"
+ },
+ "searchPlaceholder": "เคธเคญเฅ เคเฅเคฒเฅเคธ เคเฅเคเฅเค",
+ "title": "เคเฅ เคธเคพเคฅ เคเคฒเฅเคฆเฅ เคเคพเคฎ เคเคฐเฅเค"
+ },
+ "inputFooter": {
+ "clear": "เคธเคพเคซเคผ เคเคฐเฅเค",
+ "copyToClipboard": "เคเฅเคฒเคฟเคชเคฌเฅเคฐเฅเคก เคชเคฐ เคเฅเคชเฅ เคเคฐเฅเค",
+ "importFromFile": "เคซเคผเคพเคเคฒ เคธเฅ เคเคฏเคพเคค เคเคฐเฅเค"
+ },
+ "list": {
+ "group": {
+ "description": "เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคธเคฎเฅเคนเคฟเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคฆเฅเคจเคฟเคฏเคพ เคเคพ เคธเคฌเคธเฅ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพเฅค เค
เคชเคจเฅ เคธเฅเคเฅ เคเคจเคชเฅเค เคเคฐเฅเค เคเคฐ เคธเคฎเฅเคนเฅเคเคฐเคฃ เคฎเคพเคจเคฆเคเคก เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเฅเค เคคเคพเคเคฟ เคเคเคเคฎ เคเฅ เคคเคพเคฐเฅเคเคฟเค เคธเคฎเฅเคนเฅเค เคฎเฅเค เคตเฅเคฏเคตเคธเฅเคฅเคฟเคค เคเคฟเคฏเคพ เคเคพ เคธเคเฅเฅค เคกเฅเคเคพ เคเฅ เคตเคฐเฅเคเฅเคเฅเคค เคเคฐเคจเฅ, เคเคพเคจเคเคพเคฐเฅ เคเฅ เคตเฅเคฏเคตเคธเฅเคฅเคฟเคค เคเคฐเคจเฅ, เคฏเคพ เคธเคเคฐเคเคฟเคค เคธเฅเคเคฟเคฏเคพเค เคฌเคจเคพเคจเฅ เคเฅ เคฒเคฟเค เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅเฅค เคเคธเฅเคเคฎ เคตเคฟเคญเคพเคเค เคเคฐ เคตเคฟเคญเคฟเคจเฅเคจ เคธเคฎเฅเคนเฅเคเคฐเคฃ เคตเคฟเคเคฒเฅเคชเฅเค เคเคพ เคธเคฎเคฐเฅเคฅเคจ เคเคฐเคคเคพ เคนเฅเฅค",
+ "name": "เคธเคฎเฅเคน",
+ "shortDescription": "เคธเคพเคฎเคพเคจเฅเคฏ เคเฅเคฃเฅเค เคฆเฅเคตเคพเคฐเคพ เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคธเคฎเฅเคนเคฟเคค เคเคฐเฅเค"
+ },
+ "reverse": {
+ "description": "เคฏเคน เคเค เคธเฅเคชเคฐ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเฅเคฒเคฟเคเฅเคถเคจ เคนเฅ เคเฅ เคธเคญเฅ เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคเคฒเฅเคเฅ เคเฅเคฐเคฎ เคฎเฅเค เคชเฅเคฐเคฟเคเค เคเคฐเคคเฅ เคนเฅเฅค เคเคจเคชเฅเค เคเคเคเคฎ เคเคฟเคธเฅ เคญเฅ เคชเฅเคฐเคคเฅเค เคธเฅ เค
เคฒเค เคเคฟเค เคเคพ เคธเคเคคเฅ เคนเฅเค เคเคฐ เคเคช เคเคฒเคเฅ เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เคตเคฟเคญเคพเคเค เคเฅ เคญเฅ เคฌเคฆเคฒ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "name": "เคเคฒเคเคพ",
+ "shortDescription": "เคเคฒเฅเคฆเฅ เคธเฅ เคธเฅเคเฅ เคเฅ เคเคฒเคเคพ เคเคฐเฅเค"
+ },
+ "sort": {
+ "description": "เคฏเคน เคเค เคธเฅเคชเคฐ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเฅเคฒเคฟเคเฅเคถเคจ เคนเฅ เคเฅ เคธเฅเคเฅ เคฎเฅเค เคเคเคเคฎ เคเฅ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเคคเฅ เคนเฅ เคเคฐ เคเคจเฅเคนเฅเค เคฌเคขเคผเคคเฅ เคฏเคพ เคเคเคคเฅ เคเฅเคฐเคฎ เคฎเฅเค เคตเฅเคฏเคตเคธเฅเคฅเคฟเคค เคเคฐเคคเฅ เคนเฅเฅค เคเคช เคเคเคเคฎ เคเฅ เคตเคฐเฅเคฃเคพเคจเฅเคเฅเคฐเคฎเคฟเค, เคธเคเคเฅเคฏเคพเคคเฅเคฎเค, เคฏเคพ เคเคจเคเฅ เคฒเคเคฌเคพเค เคเฅ เค
เคจเฅเคธเคพเคฐ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคเคช เคกเฅเคชเฅเคฒเคฟเคเฅเค เคเคฐ เคเคพเคฒเฅ เคเคเคเคฎ เคเฅ เคญเฅ เคนเคเคพ เคธเคเคคเฅ เคนเฅเค, เคธเคพเคฅ เคนเฅ เคเคจ เคเคเคเคฎ เคเฅ เคเฅเคฐเคฟเคฎ เคเคฐ เคธเคเคคเฅ เคนเฅเค เคเคฟเคจเคเฅ เคเคพเคฐเฅเค เคเคฐ เคธเคซเฅเคฆ เคธเฅเคฅเคพเคจ เคนเฅเฅค เคเคช เคเคจเคชเฅเค เคธเฅเคเฅ เคเคเคเคฎ เคเฅ เค
เคฒเค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเฅเค เคญเฅ เคตเคฟเคญเคพเคเค เคตเคฐเฅเคฃ เคเคชเคฏเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค เคฏเคพ เคตเฅเคเคฒเฅเคชเคฟเค เคฐเฅเคช เคธเฅ เคเคจเฅเคนเฅเค เค
เคฒเค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคเค เคจเคฟเคฏเคฎเคฟเคค เค
เคญเคฟเคตเฅเคฏเคเฅเคคเคฟ เคเคพ เคเคชเคฏเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคเคธเคเฅ เค
เคคเคฟเคฐเคฟเคเฅเคค, เคเคช เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคเคเคชเฅเค เคธเฅเคเฅ เคเฅ เคฒเคฟเค เคเค เคจเคฏเคพ เคกเคฟเคฒเคฟเคฎเคฟเคเคฐ เคฌเคจเคพ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "name": "เคเฅเคฐเคฎเคฌเคฆเฅเคง",
+ "shortDescription": "เคเคฒเฅเคฆเฅ เคธเฅ เคธเฅเคเฅ เคเฅ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค"
+ }
+ },
+ "navbar": {
+ "buyMeACoffee": "เคฎเฅเคเฅ เคเฅเคซเฅ เคเคฐเฅเคฆเฅเค",
+ "home": "เคนเฅเคฎ",
+ "tools": "เคเฅเคฒเฅเคธ"
+ },
+ "number": {
+ "generate": {
+ "description": "เค
เคชเคจเฅ เคฌเฅเคฐเคพเคเคเคผเคฐ เคฎเฅเค เคชเฅเคฐเฅเคฃเคพเคเคเฅเค เคเฅ เคธเฅเคเฅ เคเฅ เคคเฅเคฐเคเคค เคเคฃเคจเคพ เคเคฐเฅเคเฅค เค
เคชเคจเฅ เคธเฅเคเฅ เคชเฅเคฐเคพเคชเฅเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค, เคฌเคธ เคชเคนเคฒเคพ เคชเฅเคฐเฅเคฃเคพเคเค เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐเฅเค, เคจเฅเคเฅ เคตเคฟเคเคฒเฅเคชเฅเค เคฎเฅเค เคฎเคพเคจ เคเคฐ เคเฅเคฒ เคธเคเคเฅเคฏเคพ เคฌเคฆเคฒเฅเค, เคเคฐ เคฏเคน เคเคชเคฏเฅเคเคฟเคคเคพ เคเคคเคจเฅ เคชเฅเคฐเฅเคฃเคพเคเค เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเคเฅ",
+ "name": "เคธเคเคเฅเคฏเคพเคเค เคเคคเฅเคชเคจเฅเคจ เคเคฐเฅเค",
+ "shortDescription": "เค
เคชเคจเฅ เคฌเฅเคฐเคพเคเคเคผเคฐ เคฎเฅเค เคชเฅเคฐเฅเคฃเคพเคเคเฅเค เคเฅ เคธเฅเคเฅ เคเฅ เคคเฅเคฐเคเคค เคเคฃเคจเคพ เคเคฐเฅเค"
+ },
+ "sum": {
+ "description": "เคฏเคน เคเค เคธเฅเคชเคฐ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเฅเคฒเคฟเคเฅเคถเคจ เคนเฅ เคเฅ เคธเคเคเฅเคฏเคพเคเค เคเฅ เคเฅเคกเคผเคคเฅ เคนเฅเฅค เคเคจเคชเฅเค เคธเคเคเฅเคฏเคพเคเค เคเคฟเคธเฅ เคญเฅ เคชเฅเคฐเคคเฅเค เคธเฅ เค
เคฒเค เคเฅ เคเคพ เคธเคเคคเฅ เคนเฅเค เคเคฐ เคเคช เคเฅเคกเคผเฅ เคเค เคธเคเคเฅเคฏเคพเคเค เคเฅ เคตเคฟเคญเคพเคเค เคเฅ เคญเฅ เคฌเคฆเคฒ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "name": "เคธเคเคเฅเคฏเคพเคเค เคเฅเคกเคผเฅเค",
+ "shortDescription": "เคเคฒเฅเคฆเฅ เคธเฅ เคธเคเคเฅเคฏเคพเคเค เคเฅ เคธเฅเคเฅ เคเฅเคกเคผเฅเค"
+ }
+ },
+ "numericInputWithUnit": {
+ "unit": "เคเคเคพเค"
+ },
+ "pdf": {
+ "compressPdf": {
+ "description": "เคเฅเคธเฅเคเคธเฅเคเฅเคฐเคฟเคชเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคเฅเคฃเคตเคคเฅเคคเคพ เคฌเคจเคพเค เคฐเคเคคเฅ เคนเฅเค เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒ เคเคเคพเคฐ เคเคฎ เคเคฐเฅเค",
+ "name": "เคชเฅเคกเฅเคเคซ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค",
+ "shortDescription": "เค
เคชเคจเฅ เคฌเฅเคฐเคพเคเคเคผเคฐ เคฎเฅเค เคธเฅเคฐเคเฅเคทเคฟเคค เคฐเฅเคช เคธเฅ เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒเฅเค เคเฅ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค"
+ },
+ "mergePdf": {
+ "description": "เคเค เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเค เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคฎเฅเค เคเฅเคกเคผเฅเคเฅค",
+ "name": "เคชเฅเคกเฅเคเคซ เคฎเคฐเฅเค เคเคฐเฅเค",
+ "shortDescription": "เคเค เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเค เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคฎเฅเค เคฎเคฐเฅเค เคเคฐเฅเค"
+ },
+ "pdfToEpub": {
+ "description": "เคฌเฅเคนเคคเคฐ เค-เคฐเฅเคกเคฐ เคธเคเคเคคเคคเคพ เคเฅ เคฒเคฟเค เคชเฅเคกเฅเคเคซ เคฆเคธเฅเคคเคพเคตเฅเคเคผเฅเค เคเฅ เคเคชเฅเคฏเฅเคฌเฅ เคซเคผเคพเคเคฒเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "name": "เคชเฅเคกเฅเคเคซ เคธเฅ เคเคชเฅเคฏเฅเคฌเฅ",
+ "shortDescription": "เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเคชเฅเคฏเฅเคฌเฅ เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเค"
+ },
+ "protectPdf": {
+ "description": "เค
เคชเคจเฅ เคฌเฅเคฐเคพเคเคเคผเคฐ เคฎเฅเค เคธเฅเคฐเคเฅเคทเคฟเคค เคฐเฅเคช เคธเฅ เค
เคชเคจเฅ เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒเฅเค เคฎเฅเค เคชเคพเคธเคตเคฐเฅเคก เคธเฅเคฐเคเฅเคทเคพ เคเฅเคกเคผเฅเค",
+ "name": "เคชเฅเคกเฅเคเคซ เคธเฅเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "shortDescription": "เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒเฅเค เคเฅ เคธเฅเคฐเคเฅเคทเคฟเคค เคฐเฅเคช เคธเฅ เคชเคพเคธเคตเคฐเฅเคก เคธเฅเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค"
+ },
+ "splitPdf": {
+ "description": "เคชเฅเค เคจเคเคฌเคฐ เคฏเคพ เคถเฅเคฐเฅเคฃเคฟเคฏเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒ เคธเฅ เคตเคฟเคถเคฟเคทเฅเค เคชเฅเค เคจเคฟเคเคพเคฒเฅเค (เคเคฆเคพเคนเคฐเคฃ เคเฅ เคฒเคฟเค, 1,5-8)",
+ "name": "เคชเฅเคกเฅเคเคซ เคตเคฟเคญเคพเคเคฟเคค เคเคฐเฅเค",
+ "shortDescription": "เคชเฅเคกเฅเคเคซ เคซเคผเคพเคเคฒ เคธเฅ เคตเคฟเคถเคฟเคทเฅเค เคชเฅเค เคจเคฟเคเคพเคฒเฅเค"
+ }
+ },
+ "resultFooter": {
+ "copy": "เคเฅเคฒเคฟเคชเคฌเฅเคฐเฅเคก เคชเคฐ เคเฅเคชเฅ เคเคฐเฅเค",
+ "download": "เคกเคพเคเคจเคฒเฅเคก"
+ },
+ "string": {
+ "createPalindrome": {
+ "description": "เคเคฟเคธเฅ เคญเฅ เคเฅเคเฅเคธเฅเค เคธเฅ เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคฌเคจเคพเคจเฅ เคเฅ เคฒเคฟเค เคฆเฅเคจเคฟเคฏเคพ เคเคพ เคธเคฌเคธเฅ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพเฅค เคเฅเคเฅเคธเฅเค เคเคจเคชเฅเค เคเคฐเฅเค เคเคฐ เคเคธเฅ เคคเฅเคฐเคเคค เคเค เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคฎเฅเค เคฌเคฆเคฒ เคฆเฅเค เคเฅ เคเคเฅ เคเคฐ เคชเฅเคเฅ เคเค เคเฅเคธเคพ เคชเคขเคผเคคเคพ เคนเฅเฅค เคถเคฌเฅเคฆ เคเฅเคฒเฅเค, เคธเคฎเคฎเคฟเคค เคเฅเคเฅเคธเฅเค เคชเฅเคเคฐเฅเคจ เคฌเคจเคพเคจเฅ, เคฏเคพ เคญเคพเคทเคพเค เคเคฟเคเฅเคเคพเคธเคพเคเค เคเฅ เคเฅเค เคเฅ เคฒเคฟเค เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅเฅค",
+ "name": "เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคฌเคจเคพเคเค",
+ "shortDescription": "เคเคธเคพ เคเฅเคเฅเคธเฅเค เคฌเคจเคพเคเค เคเฅ เคเคเฅ เคเคฐ เคชเฅเคเฅ เคเค เคเฅเคธเคพ เคชเคขเคผเคคเคพ เคนเฅ"
+ },
+ "palindrome": {
+ "description": "เคฏเคน เคเคพเคเคเคจเฅ เคเฅ เคฒเคฟเค เคฆเฅเคจเคฟเคฏเคพ เคเคพ เคธเคฌเคธเฅ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพ เคเคฟ เคเฅเคเฅเคธเฅเค เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคนเฅ เคฏเคพ เคจเคนเฅเคเฅค เคคเฅเคฐเคเคค เคธเคคเฅเคฏเคพเคชเคฟเคค เคเคฐเฅเค เคเคฟ เคเฅเคฏเคพ เคเคชเคเคพ เคเฅเคเฅเคธเฅเค เคเคเฅ เคเคฐ เคชเฅเคเฅ เคเค เคเฅเคธเคพ เคชเคขเคผเคคเคพ เคนเฅเฅค เคถเคฌเฅเคฆ เคชเคนเฅเคฒเคฟเคฏเฅเค, เคญเคพเคทเคพเค เคตเคฟเคถเฅเคฒเฅเคทเคฃ, เคฏเคพ เคธเคฎเคฎเคฟเคค เคเฅเคเฅเคธเฅเค เคชเฅเคเคฐเฅเคจ เคเฅ เคฎเคพเคจเฅเคฏ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅเฅค เคตเคฟเคญเคฟเคจเฅเคจ เคตเคฟเคญเคพเคเคเฅเค เคเคฐ เคฌเคนเฅ-เคถเคฌเฅเคฆ เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคชเคนเคเคพเคจ เคเคพ เคธเคฎเคฐเฅเคฅเคจ เคเคฐเคคเคพ เคนเฅเฅค",
+ "name": "เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ",
+ "shortDescription": "เคเคพเคเคเฅเค เคเคฟ เคเฅเคฏเคพ เคเฅเคเฅเคธเฅเค เคเคเฅ เคเคฐ เคชเฅเคเฅ เคเค เคเฅเคธเคพ เคชเคขเคผเคคเคพ เคนเฅ"
+ },
+ "repeat": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคตเฅเคเคฒเฅเคชเคฟเค เคตเคฟเคญเคพเคเค เคเฅ เคธเคพเคฅ เคฆเคฟเค เคเค เคเฅเคเฅเคธเฅเค เคเฅ เคเค เคฌเคพเคฐ เคฆเฅเคนเคฐเคพเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅเฅค",
+ "name": "เคเฅเคเฅเคธเฅเค เคฆเฅเคนเคฐเคพเคเค",
+ "shortDescription": "เคเฅเคเฅเคธเฅเค เคเฅ เคเค เคฌเคพเคฐ เคฆเฅเคนเคฐเคพเคเค"
+ },
+ "reverse": {
+ "description": "เคเฅเคเฅเคธเฅเค เคเฅ เคเคฒเคเคจเฅ เคเฅ เคฒเคฟเค เคฆเฅเคจเคฟเคฏเคพ เคเคพ เคธเคฌเคธเฅ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพเฅค เคเฅเค เคญเฅ เคเฅเคเฅเคธเฅเค เคเคจเคชเฅเค เคเคฐเฅเค เคเคฐ เคเคธเฅ เคคเฅเคฐเคเคค เคเคฒเคเคพ เคชเฅเคฐเคพเคชเฅเคค เคเคฐเฅเค, เคตเคฐเฅเคฃ เคฆเคฐ เคตเคฐเฅเคฃเฅค เคฆเคฐเฅเคชเคฃ เคเฅเคเฅเคธเฅเค เคฌเคจเคพเคจเฅ, เคชเฅเคฒเคฟเคเคกเฅเคฐเฅเคฎ เคเคพ เคตเคฟเคถเฅเคฒเฅเคทเคฃ เคเคฐเคจเฅ, เคฏเคพ เคเฅเคเฅเคธเฅเค เคชเฅเคเคฐเฅเคจ เคเฅ เคธเคพเคฅ เคเฅเคฒเคจเฅ เคเฅ เคฒเคฟเค เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅเฅค เคเคฒเคเคคเฅ เคธเคฎเคฏ เคธเฅเคฅเคพเคจ เคเคฐ เคตเคฟเคถเฅเคท เคตเคฐเฅเคฃเฅเค เคเฅ เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเคคเคพ เคนเฅเฅค",
+ "name": "เคเคฒเคเคพ",
+ "shortDescription": "เคเคฟเคธเฅ เคญเฅ เคเฅเคเฅเคธเฅเค เคเฅ เคตเคฐเฅเคฃ เคฆเคฐ เคตเคฐเฅเคฃ เคเคฒเคเคพ เคเคฐเฅเค"
+ },
+ "toMorse": {
+ "description": "เคเฅเคเฅเคธเฅเค เคเฅ เคฎเฅเคฐเฅเคธ เคเฅเคก เคฎเฅเค เคฌเคฆเคฒเคจเฅ เคเฅ เคฒเคฟเค เคฆเฅเคจเคฟเคฏเคพ เคเคพ เคธเคฌเคธเฅ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพเฅค เคฌเคพเคเค เคเคฐ เคเคจเคชเฅเค เคซเฅเคฐเฅเคฎ เคฎเฅเค เค
เคชเคจเคพ เคเฅเคเฅเคธเฅเค เคฒเฅเคก เคเคฐเฅเค เคเคฐ เคเคชเคเฅ เคคเฅเคฐเคเคค เคเคเคเคชเฅเค เคเฅเคทเฅเคคเฅเคฐ เคฎเฅเค เคฎเฅเคฐเฅเคธ เคเฅเคก เคฎเคฟเคฒเฅเคเคพเฅค เคถเคเฅเคคเคฟเคถเคพเคฒเฅ, เคฎเฅเคซเฅเคค, เคเคฐ เคคเฅเคเคผเฅค เคเฅเคเฅเคธเฅเค เคฒเฅเคก เคเคฐเฅเค โ เคฎเฅเคฐเฅเคธ เคเฅเคก เคชเฅเคฐเคพเคชเฅเคค เคเคฐเฅเคเฅค",
+ "name": "เคเฅเคเฅเคธเฅเค เคธเฅ เคฎเฅเคฐเฅเคธ",
+ "shortDescription": "เคเฅเคเฅเคธเฅเค เคเฅ เคเคฒเฅเคฆเฅ เคธเฅ เคฎเฅเคฐเฅเคธ เคฎเฅเค เคเคจเคเฅเคก เคเคฐเฅเค"
+ },
+ "uppercase": {
+ "description": "เคเฅเคเฅเคธเฅเค เคเฅ เคฌเคกเคผเฅ เค
เคเฅเคทเคฐเฅเค เคฎเฅเค เคฌเคฆเคฒเคจเฅ เคเฅ เคฒเคฟเค เคฆเฅเคจเคฟเคฏเคพ เคเคพ เคธเคฌเคธเฅ เคธเคฐเคฒ เคฌเฅเคฐเคพเคเคเคผเคฐ-เคเคงเคพเคฐเคฟเคค เคเคชเคฏเฅเคเคฟเคคเคพเฅค เคฌเคธ เค
เคชเคจเคพ เคเฅเคเฅเคธเฅเค เคเคจเคชเฅเค เคเคฐเฅเค เคเคฐ เคฏเคน เคธเฅเคตเคเคพเคฒเคฟเคค เคฐเฅเคช เคธเฅ เคธเคญเฅ เคฌเคกเคผเฅ เค
เคเฅเคทเคฐเฅเค เคฎเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคฟเคค เคนเฅ เคเคพเคเคเคพเฅค เคถเฅเคฐเฅเคทเค เคฌเคจเคพเคจเฅ, เคเฅเคเฅเคธเฅเค เคชเคฐ เคเฅเคฐ เคฆเฅเคจเฅ, เคฏเคพ เคเฅเคเฅเคธเฅเค เคชเฅเคฐเคพเคฐเฅเคช เคเฅ เคฎเคพเคจเคเฅเคเฅเคค เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคฌเคฟเคฒเฅเคเฅเคฒ เคธเคนเฅเฅค เคตเคฟเคญเคฟเคจเฅเคจ เคเฅเคเฅเคธเฅเค เคชเฅเคฐเคพเคฐเฅเคชเฅเค เคเคพ เคธเคฎเคฐเฅเคฅเคจ เคเคฐเคคเคพ เคนเฅ เคเคฐ เคตเคฟเคถเฅเคท เคตเคฐเฅเคฃเฅเค เคเฅ เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเคคเคพ เคนเฅเฅค",
+ "name": "เคฌเคกเคผเฅ เค
เคเฅเคทเคฐ",
+ "shortDescription": "เคเฅเคเฅเคธเฅเค เคเฅ เคฌเคกเคผเฅ เค
เคเฅเคทเคฐเฅเค เคฎเฅเค เคฌเคฆเคฒเฅเค"
+ }
+ },
+ "toolExamples": {
+ "subtitle": "เคเคเคผเคฎเคพเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคฒเคฟเค เคเคฐเฅเค!",
+ "title": "{{title}} เคเคฆเคพเคนเคฐเคฃ"
+ },
+ "toolFileResult": {
+ "copied": "เคซเคผเคพเคเคฒ เคเฅเคชเฅ เคเฅ เคเค",
+ "copyFailed": "เคเฅเคชเฅ เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒ: {{error}}",
+ "loading": "เคฒเฅเคก เคนเฅ เคฐเคนเคพ เคนเฅ... เคเคธเคฎเฅเค เคเฅเค เคธเคฎเคฏ เคฒเค เคธเคเคคเคพ เคนเฅเฅค",
+ "result": "เคชเคฐเคฟเคฃเคพเคฎ"
+ },
+ "toolHeader": {
+ "seeExamples": "เคเคฆเคพเคนเคฐเคฃ เคฆเฅเคเฅเค"
+ },
+ "toolLayout": {
+ "allToolsTitle": "เคธเคญเฅ {{type}}"
+ },
+ "toolMultiFileResult": {
+ "copied": "เคซเคผเคพเคเคฒ เคเฅเคชเฅ เคเฅ เคเค",
+ "copyFailed": "เคเฅเคชเฅ เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒ: {{error}}",
+ "loading": "เคฒเฅเคก เคนเฅ เคฐเคนเคพ เคนเฅ... เคเคธเคฎเฅเค เคเฅเค เคธเคฎเคฏ เคฒเค เคธเคเคคเคพ เคนเฅเฅค",
+ "result": "เคชเคฐเคฟเคฃเคพเคฎ"
+ },
+ "toolMultipleAudioInput": {
+ "inputTitle": "เคเคจเคชเฅเค {{type}}",
+ "noFilesSelected": "เคเฅเค เคซเคผเคพเคเคฒ เคเคฏเคจเคฟเคค เคจเคนเฅเค"
+ },
+ "toolMultiplePdfInput": {
+ "inputTitle": "เคเคจเคชเฅเค {{type}}",
+ "noFilesSelected": "เคเฅเค เคซเคผเคพเคเคฒ เคเคฏเคจเคฟเคค เคจเคนเฅเค"
+ },
+ "toolOptions": {
+ "title": "เคเฅเคฒ เคตเคฟเคเคฒเฅเคช"
+ },
+ "toolTextInput": {
+ "copied": "เคเฅเคเฅเคธเฅเค เคเฅเคชเฅ เคเคฟเคฏเคพ เคเคฏเคพ",
+ "copyFailed": "เคเฅเคชเฅ เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒ: {{error}}",
+ "input": "เคเคจเคชเฅเค เคเฅเคเฅเคธเฅเค",
+ "placeholder": "เคฏเคนเคพเค เค
เคชเคจเคพ เคเฅเคเฅเคธเฅเค เคฆเคฐเฅเค เคเคฐเฅเค..."
+ },
+ "toolTextResult": {
+ "copied": "เคเฅเคเฅเคธเฅเค เคเฅเคชเฅ เคเคฟเคฏเคพ เคเคฏเคพ",
+ "copyFailed": "เคเฅเคชเฅ เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒ: {{error}}",
+ "loading": "เคฒเฅเคก เคนเฅ เคฐเคนเคพ เคนเฅ... เคเคธเคฎเฅเค เคเฅเค เคธเคฎเคฏ เคฒเค เคธเคเคคเคพ เคนเฅเฅค",
+ "result": "เคชเคฐเคฟเคฃเคพเคฎ"
+ }
+}
diff --git a/public/locales/hi/video.json b/public/locales/hi/video.json
new file mode 100644
index 0000000..966aef7
--- /dev/null
+++ b/public/locales/hi/video.json
@@ -0,0 +1,194 @@
+{
+ "changeSpeed": {
+ "defaultMultiplier": "เคกเคฟเคซเคผเฅเคฒเฅเค เคเฅเคฃเค: 2 เคเคพ เค
เคฐเฅเคฅ เคนเฅ 2x เคคเฅเคเคผ",
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคชเฅเคฒเฅเคฌเฅเค เคเคคเคฟ เคฌเคฆเคฒเฅเคเฅค",
+ "factorPlaceholder": "เคเคพเคฐเค (เคเฅเคธเฅ 0.5, 1.5, 2.0)",
+ "formatAvi": "AVI",
+ "formatMov": "MOV",
+ "formatMp4": "MP4",
+ "inputTitle": "เคเคจเคชเฅเค เคตเฅเคกเคฟเคฏเฅ",
+ "newVideoSpeed": "เคจเค เคตเฅเคกเคฟเคฏเฅ เคธเฅเคชเฅเคก",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "preserveAudio": "เคเคกเคฟเคฏเฅ เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "resultTitle": "เคเคคเคฟ เคฌเคฆเคฒเฅ เคเค เคตเฅเคกเคฟเคฏเฅ",
+ "settingSpeed": "เคเคคเคฟ เคธเฅเค เคเคฐเคจเคพ",
+ "shortDescription": "เคตเฅเคกเคฟเคฏเฅ เคชเฅเคฒเฅเคฌเฅเค เคเคคเคฟ เคฌเคฆเคฒเฅเค",
+ "speedFactor": "เคเคคเคฟ เคเคพเคฐเค",
+ "speedOptions": "เคเคคเคฟ เคตเคฟเคเคฒเฅเคช",
+ "title": "เคตเฅเคกเคฟเคฏเฅ เคเคคเคฟ เคฌเคฆเคฒเฅเค",
+ "toolInfo": {
+ "title": "{{title}} เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "compress": {
+ "compressionOptions": "เคธเคเคชเฅเคกเคผเคจ เคตเคฟเคเคฒเฅเคช",
+ "default": "เคเคฒเคคเฅ เคเคฐเคจเคพ",
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒ เคเคเคพเคฐ เคเคฎ เคเคฐเฅเคเฅค",
+ "formatAvi": "AVI",
+ "formatMp4": "MP4",
+ "inputTitle": "เคเคจเคชเฅเค เคตเฅเคกเคฟเคฏเฅ",
+ "loadingText": "เคตเฅเคกเคฟเคฏเฅ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฟเคฏเคพ เคเคพ เคฐเคนเคพ เคนเฅ...",
+ "lossless": "เคฆเฅเคทเคฐเคนเคฟเคค",
+ "outputFormat": "เคเคเคเคชเฅเค เคชเฅเคฐเคพเคฐเฅเคช",
+ "quality": "เคเฅเคฃเคตเคคเฅเคคเคพ (เคธเฅเคเคฐเคเคซ)",
+ "qualityHigh": "เคเคเฅเค",
+ "qualityLow": "เคเคฎ",
+ "qualityMedium": "เคฎเคงเฅเคฏเคฎ",
+ "resolution": "เคฐเคฟเคเคผเฅเคฒเฅเคฏเฅเคถเคจ",
+ "resolution360p": "360p",
+ "resolution480p": "480p",
+ "resolution720p": "720p",
+ "resolutionOriginal": "เคฎเฅเคฒ",
+ "resultTitle": "เคธเคเคชเฅเคกเคผเคฟเคค เคตเฅเคกเคฟเคฏเฅ",
+ "shortDescription": "เคตเคฟเคญเคฟเคจเฅเคจ เคฐเคฟเคเคผเฅเคฒเฅเคฏเฅเคถเคจ เคชเคฐ เคธเฅเคเฅเคฒ เคเคฐเคเฅ เคตเฅเคกเคฟเคฏเฅ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค",
+ "title": "เคตเฅเคกเคฟเคฏเฅ เคธเคเคชเฅเคกเคผเคฟเคค เคเคฐเฅเค",
+ "videoQuality": "เคตเฅเคกเคฟเคฏเฅ เคเฅเคฃเคตเคคเฅเคคเคพ",
+ "worst": "เคฌเคนเฅเคค เคฌเฅเคฐเคพ"
+ },
+ "cropVideo": {
+ "aspectRatio": "เคเคเคพเคฐ เค
เคจเฅเคชเคพเคค",
+ "cropArea": "เคเฅเคฐเฅเคช เคเฅเคทเฅเคคเฅเคฐ",
+ "cropCoordinates": "เคซเคธเคฒ เคจเคฟเคฐเฅเคฆเฅเคถเคพเคเค",
+ "cropMethod": "เคเฅเคฐเฅเคช เคตเคฟเคงเคฟ",
+ "cropOptions": "เคเฅเคฐเฅเคช เคตเคฟเคเคฒเฅเคช",
+ "croppingVideo": "เคตเฅเคกเคฟเคฏเฅ เคเฅเคฐเฅเคช เคเคฐเคจเคพ",
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคธเฅ เค
เคจเคพเคตเคถเฅเคฏเค เคญเคพเค เคนเคเคพเคเคเฅค",
+ "errorBeyondHeight": "เคซเคธเคฒ เคเฅเคทเฅเคคเฅเคฐ เคตเฅเคกเคฟเคฏเฅ เคเฅ เคเคเคเคพเค เคธเฅ เคเคเฅ เคคเค เคซเฅเคฒเคพ เคนเฅเค เคนเฅ ({{height}}เคชเคฟเคเฅเคธเคฒ)",
+ "errorBeyondWidth": "เคซเคธเคฒ เคเฅเคทเฅเคคเฅเคฐ เคตเฅเคกเคฟเคฏเฅ เคเฅ เคเฅเคกเคผเคพเค เคธเฅ เคเคเฅ เคคเค เคซเฅเคฒเคพ เคนเฅเค เคนเฅ ({{width}}เคชเคฟเคเฅเคธเคฒ)",
+ "errorCroppingVideo": "เคตเฅเคกเคฟเคฏเฅ เคเฅเคฐเฅเคช เคเคฐเคจเฅ เคฎเฅเค เคคเฅเคฐเฅเคเคฟ เคนเฅเคเฅค เคเฅเคชเคฏเคพ เคชเฅเคฐเคพเคฎเฅเคเคฐ เคเคฐ เคตเฅเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒ เคเคพเคเคเฅเคเฅค",
+ "errorLoadingDimensions": "เคตเฅเคกเคฟเคฏเฅ เคเคฏเคพเคฎ เคฒเฅเคก เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒ",
+ "errorNonNegativeCoordinates": "X เคเคฐ Y เคจเคฟเคฐเฅเคฆเฅเคถเคพเคเค เคเฅเคฐ-เคเคฃเคพเคคเฅเคฎเค เคนเฅเคจเฅ เคเคพเคนเคฟเค",
+ "errorPositiveDimensions": "เคเฅเคกเคผเคพเค เคเคฐ เคเคเคเคพเค เคงเคจเคพเคคเฅเคฎเค เคนเฅเคจเฅ เคเคพเคนเคฟเค",
+ "height": "เคเคเคเคพเค",
+ "heightPlaceholder": "เคชเคฟเคเฅเคธเฅเคฒ",
+ "inputTitle": "เคเคจเคชเฅเค เคตเฅเคกเคฟเคฏเฅ",
+ "loadVideoForDimensions": "เคเคฏเคพเคฎ เคฆเฅเคเคจเฅ เคเฅ เคฒเคฟเค เคตเฅเคกเคฟเคฏเฅ เคฒเฅเคก เคเคฐเฅเค",
+ "methodAspectRatio": "เคเคเคพเคฐ เค
เคจเฅเคชเคพเคค",
+ "methodManual": "เคฎเฅเคจเฅเค
เคฒ",
+ "ratio16x9": "16:9",
+ "ratio1x1": "1:1",
+ "ratio4x3": "4:3",
+ "resultTitle": "เคเฅเคฐเฅเคช เคเคฟเคฏเคพ เคเคฏเคพ เคตเฅเคกเคฟเคฏเฅ",
+ "shortDescription": "เค
เคตเคพเคเคเคฟเคค เคเฅเคทเฅเคคเฅเคฐเฅเค เคเฅ เคนเคเคพเคจเฅ เคเฅ เคฒเคฟเค เคตเฅเคกเคฟเคฏเฅ เคเฅ เคเฅเคฐเฅเคช เคเคฐเฅเค",
+ "title": "เคตเฅเคกเคฟเคฏเฅ เคเฅเคฐเฅเคช เคเคฐเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคตเฅเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคเฅ เคเฅเคฐเฅเคช เคเคฐเคเฅ เค
เคตเคพเคเคเคฟเคค เคเฅเคทเฅเคคเฅเคฐเฅเค เคเฅ เคนเคเคพเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช X, Y เคจเคฟเคฐเฅเคฆเฅเคถเคพเคเค เคเคฐ เคเฅเคกเคผเคพเค, เคเคเคเคพเค เคเฅ เคเคฏเคพเคฎ เคจเคฟเคฐเฅเคงเคพเคฐเคฟเคค เคเคฐเคเฅ เคเฅเคฐเฅเคช เคเฅเคทเฅเคคเฅเคฐ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "title": "เคตเฅเคกเคฟเคฏเฅ เคเฅเคฐเฅเคช เคเคฐเฅเค"
+ },
+ "videoDimensions": "เคตเฅเคกเคฟเคฏเฅ เคเคฏเคพเคฎ: {{width}} ร {{height}} เคชเคฟเคเฅเคธเฅเคฒ",
+ "videoInformation": "เคตเฅเคกเคฟเคฏเฅ เคเคพเคจเคเคพเคฐเฅ",
+ "width": "เคเฅเคกเคผเคพเค",
+ "widthPlaceholder": "เคชเคฟเคเฅเคธเฅเคฒ",
+ "xCoordinate": "X (เคฌเคพเคเค)",
+ "xPlaceholder": "เคชเคฟเคเฅเคธเฅเคฒ",
+ "xPosition": "X เคธเฅเคฅเคฟเคคเคฟ",
+ "yCoordinate": "Y (เคเคชเคฐ)",
+ "yPlaceholder": "เคชเคฟเคเฅเคธเฅเคฒ",
+ "yPosition": "Y เคธเฅเคฅเคฟเคคเคฟ"
+ },
+ "flip": {
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคเฅ เคเฅเคทเฅเคคเคฟเค เคฏเคพ เคฒเคเคฌเคตเคค เคฐเฅเคช เคธเฅ เคซเฅเคฒเคฟเคช เคเคฐเฅเคเฅค",
+ "directionBoth": "เคฆเฅเคจเฅเค",
+ "directionHorizontal": "เคเฅเคทเฅเคคเคฟเค",
+ "directionVertical": "เคฒเคเคฌเคตเคค",
+ "flipDirection": "เคซเฅเคฒเคฟเคช เคฆเคฟเคถเคพ",
+ "flipOptions": "เคซเฅเคฒเคฟเคช เคตเคฟเคเคฒเฅเคช",
+ "flippingVideo": "เคซเคผเฅเคฒเคฟเคชเคฟเคเค เคตเฅเคกเคฟเคฏเฅ",
+ "horizontalLabel": "เคเฅเคทเฅเคคเคฟเค (เคฆเคฐเฅเคชเคฃ)",
+ "inputTitle": "เคเคจเคชเฅเค เคตเฅเคกเคฟเคฏเฅ",
+ "orientation": "เค
เคญเคฟเคตเคฟเคจเฅเคฏเคพเคธ",
+ "preserveAudio": "เคเคกเคฟเคฏเฅ เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "resultTitle": "เคซเฅเคฒเคฟเคช เคเคฟเคฏเคพ เคเคฏเคพ เคตเฅเคกเคฟเคฏเฅ",
+ "shortDescription": "เคตเฅเคกเคฟเคฏเฅ เคเฅ เคเฅเคทเฅเคคเคฟเค เคฏเคพ เคฒเคเคฌเคตเคค เคฐเฅเคช เคธเฅ เคซเคผเฅเคฒเคฟเคช เคเคฐเฅเค",
+ "title": "เคตเฅเคกเคฟเคฏเฅ เคซเฅเคฒเคฟเคช เคเคฐเฅเค",
+ "verticalLabel": "เคเคฐเฅเคงเฅเคตเคพเคงเคฐ (เคเคฒเฅเคเคพ)"
+ },
+ "gif": {
+ "changeSpeed": {
+ "delayPlaceholder": "เคฎเคฟเคฒเฅเคธเฅเคเคเคก",
+ "description": "GIF เคเคจเคฟเคฎเฅเคเฅเคก เคซเคผเคพเคเคฒเฅเค เคเฅ เคเคคเคฟ เคฌเคฆเคฒเฅเคเฅค",
+ "factorPlaceholder": "เคเคพเคฐเค (เคเฅเคธเฅ 0.5, 1.5, 2.0)",
+ "frameDelay": "เคซเฅเคฐเฅเคฎ เคตเคฟเคฒเคเคฌ",
+ "inputTitle": "เคเคจเคชเฅเค GIF",
+ "resultTitle": "เคเคคเคฟ เคฌเคฆเคฒเฅ เคเค GIF",
+ "shortDescription": "GIF เคเคจเฅเคฎเฅเคถเคจ เคเฅ เคเคคเคฟ เคฌเคฆเคฒเฅเค",
+ "speedFactor": "เคเคคเคฟ เคเคพเคฐเค",
+ "speedOptions": "เคเคคเคฟ เคตเคฟเคเคฒเฅเคช",
+ "title": "GIF เคเคคเคฟ เคฌเคฆเคฒเฅเค"
+ }
+ },
+ "loop": {
+ "countPlaceholder": "เคธเคเคเฅเคฏเคพ",
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคเฅ เคฒเฅเคช เคฎเฅเค เคเคฒเคพเคเคเฅค",
+ "durationPlaceholder": "เคธเฅเคเคเคก",
+ "fadeDuration": "เคซเฅเคก เค
เคตเคงเคฟ",
+ "fadeTransition": "เคซเฅเคก เคธเคเคเฅเคฐเคฎเคฃ",
+ "inputTitle": "เคเคจเคชเฅเค เคตเฅเคกเคฟเคฏเฅ",
+ "loopCount": "เคฒเฅเคช เคเฅ เคธเคเคเฅเคฏเคพ",
+ "loopInfinitely": "เค
เคจเคเคค เคฒเฅเคช",
+ "loopOptions": "เคฒเฅเคช เคตเคฟเคเคฒเฅเคช",
+ "loopingVideo": "เคชเคพเคถเคจ เคตเฅเคกเคฟเคฏเฅ",
+ "loops": "เคเฅเคฐเฅเค",
+ "numberOfLoops": "เคฒเฅเคชเฅเค เคเฅ เคธเคเคเฅเคฏเคพ",
+ "resultTitle": "เคฒเฅเคช เคตเฅเคกเคฟเคฏเฅ",
+ "shortDescription": "เคฒเฅเคชเคฟเคเค เคตเฅเคกเคฟเคฏเฅ เคซเคผเคพเคเคฒเฅเค เคฌเคจเคพเคเค",
+ "title": "เคตเฅเคกเคฟเคฏเฅ เคฒเฅเคช เคเคฐเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ เคฎเฅเคฒ เคตเฅเคกเคฟเคฏเฅ เคเฅ เคเค เคฌเคพเคฐ เคฆเฅเคนเคฐเคพเคเคฐ เคเค เคฒเฅเคชเคฟเคเค เคตเฅเคกเคฟเคฏเฅ เคฌเคจเคพเคจเฅ เคเฅ เคธเฅเคตเคฟเคงเคพ เคฆเฅเคคเคพ เคนเฅเฅค เคเคช เคฏเคน เคญเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเค เคเคฟ เคตเฅเคกเคฟเคฏเฅ เคเฅ เคเคฟเคคเคจเฅ เคฌเคพเคฐ เคฒเฅเคช เคเคฟเคฏเคพ เคเคพเคจเคพ เคเคพเคนเคฟเคเฅค",
+ "title": "{{title}} เคเฅเคฏเคพ เคนเฅ?"
+ }
+ },
+ "rotate": {
+ "180Degrees": "180ยฐ (เคเคฒเฅเคเคพ)",
+ "270Degrees": "270ยฐ (90ยฐ เคตเคพเคฎเคพเคตเคฐเฅเคค)",
+ "90Degrees": "90ยฐ เคฆเคเฅเคทเคฟเคฃเคพเคตเคฐเฅเคค",
+ "angle180": "180 เคกเคฟเคเฅเคฐเฅ",
+ "angle270": "270 เคกเคฟเคเฅเคฐเฅ",
+ "angle90": "90 เคกเคฟเคเฅเคฐเฅ",
+ "customAngle": "เคเคธเฅเคเคฎ เคเฅเคฃ",
+ "customAnglePlaceholder": "เคกเคฟเคเฅเคฐเฅ",
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคเฅเคฃ เคธเฅ เคเฅเคฎเคพเคเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค เคตเฅเคกเคฟเคฏเฅ",
+ "preserveAudio": "เคเคกเคฟเคฏเฅ เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "resultTitle": "เคเฅเคฎเคพเคฏเคพ เคเคฏเคพ เคตเฅเคกเคฟเคฏเฅ",
+ "rotatingVideo": "เคเฅเคฎเคคเคพ เคนเฅเค เคตเฅเคกเคฟเคฏเฅ",
+ "rotation": "ROTATION",
+ "rotationAngle": "เคเฅเคฎเคพเคจเฅ เคเคพ เคเฅเคฃ",
+ "rotationOptions": "เคเฅเคฎเคพเคจเฅ เคเฅ เคตเคฟเคเคฒเฅเคช",
+ "shortDescription": "เคตเฅเคกเคฟเคฏเฅ เคเฅ เคจเคฟเคฐเฅเคฆเคฟเคทเฅเค เคกเคฟเคเฅเคฐเฅ เคคเค เคเฅเคฎเคพเคเค",
+ "title": "เคตเฅเคกเคฟเคฏเฅ เคเฅเคฎเคพเคเค"
+ },
+ "trim": {
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคธเฅ เค
เคจเคพเคตเคถเฅเคฏเค เคญเคพเค เคนเคเคพเคเคเฅค",
+ "endPlaceholder": "เคธเฅเคเคเคก",
+ "endTime": "เค
เคเคคเคฟเคฎ เคธเคฎเคฏ",
+ "inputTitle": "เคเคจเคชเฅเค เคตเฅเคกเคฟเคฏเฅ",
+ "preserveAudio": "เคเคกเคฟเคฏเฅ เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "resultTitle": "เคเฅเคฐเคฟเคฎ เคเคฟเคฏเคพ เคเคฏเคพ เคตเฅเคกเคฟเคฏเฅ",
+ "shortDescription": "เค
เคตเคพเคเคเคฟเคค เค
เคจเฅเคญเคพเคเฅเค เคเฅ เคนเคเคพเคเคฐ เคตเฅเคกเคฟเคฏเฅ เคเฅเคฐเคฟเคฎ เคเคฐเฅเค",
+ "startPlaceholder": "เคธเฅเคเคเคก",
+ "startTime": "เคถเฅเคฐเฅเคเคคเฅ เคธเคฎเคฏ",
+ "timestamps": "เคฎเฅเคนเคฐ",
+ "title": "เคตเฅเคกเคฟเคฏเฅ เคเฅเคฐเคฟเคฎ เคเคฐเฅเค",
+ "trimOptions": "เคเฅเคฐเคฟเคฎ เคตเคฟเคเคฒเฅเคช"
+ },
+ "videoToGif": {
+ "conversionOptions": "เคฐเฅเคชเคพเคเคคเคฐเคฃ เคตเคฟเคเคฒเฅเคช",
+ "description": "เคตเฅเคกเคฟเคฏเฅ เคเฅ GIF เคเคจเคฟเคฎเฅเคเฅเคก เคซเคผเคพเคเคฒ เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "frameRate": "เคซเฅเคฐเฅเคฎ เคฆเคฐ",
+ "frameRatePlaceholder": "FPS",
+ "height": "เคเคเคเคพเค",
+ "heightPlaceholder": "เคชเคฟเคเฅเคธเฅเคฒ",
+ "inputTitle": "เคเคจเคชเฅเค เคตเฅเคกเคฟเคฏเฅ",
+ "quality": "เคเฅเคฃเคตเคคเฅเคคเคพ",
+ "qualityHigh": "เคเคเฅเค",
+ "qualityLow": "เคเคฎ",
+ "qualityMedium": "เคฎเคงเฅเคฏเคฎ",
+ "resize": "เคเคเคพเคฐ เคฌเคฆเคฒเฅเค",
+ "resultTitle": "GIF เคซเคผเคพเคเคฒ",
+ "shortDescription": "เคตเฅเคกเคฟเคฏเฅ เคเฅ เคเคจเคฟเคฎเฅเคเฅเคก GIF เคฎเฅเค เคฌเคฆเคฒเฅเค",
+ "title": "เคตเฅเคกเคฟเคฏเฅ เคธเฅ GIF",
+ "width": "เคเฅเคกเคผเคพเค",
+ "widthPlaceholder": "เคชเคฟเคเฅเคธเฅเคฒ"
+ }
+}
diff --git a/public/locales/hi/xml.json b/public/locales/hi/xml.json
new file mode 100644
index 0000000..bdc1b5b
--- /dev/null
+++ b/public/locales/hi/xml.json
@@ -0,0 +1,62 @@
+{
+ "xmlBeautifier": {
+ "description": "XML เคเฅ เคธเฅเคเคฆเคฐ เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฌเคฆเคฒเฅเคเฅค",
+ "formattingOptions": "เคซเฅเคฐเฅเคฎเฅเคเคฟเคเค เคตเคฟเคเคฒเฅเคช",
+ "indentCharacter": "เคเคเคกเฅเคเค เคตเคฐเฅเคฃ",
+ "indentSize": "เคเคเคกเฅเคเค เคเคเคพเคฐ",
+ "indentation": "เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค XML",
+ "preserveWhitespace": "เคธเคซเฅเคฆ เคธเฅเคฅเคพเคจ เคธเคเคฐเคเฅเคทเคฟเคค เคเคฐเฅเค",
+ "removeComments": "เคเคฟเคชเฅเคชเคฃเคฟเคฏเคพเค เคนเคเคพเคเค",
+ "resultTitle": "เคธเฅเคเคฆเคฐ XML",
+ "shortDescription": "XML เคเฅเคก เคเฅ เคชเฅเคฐเคพเคฐเฅเคชเคฟเคค เคเคฐ เคธเฅเคถเฅเคญเคฟเคค เคเคฐเฅเค",
+ "sizePlaceholder": "เคเคเคพเคฐ",
+ "sortAttributes": "เคตเคฟเคถเฅเคทเคคเคพเคเค เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
+ "space": "เคธเฅเคชเฅเคธ",
+ "tab": "เคเฅเคฌ",
+ "title": "XML เคธเฅเคเคฆเคฐ เคฌเคจเคพเคเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเคชเคเคฐเคฃ เคเคชเคเฅ XML เคกเฅเคเคพ เคเฅ เคเคเคฟเคค เคเคเคกเฅเคเคเฅเคถเคจ เคเคฐ เคธเฅเคชเฅเคธเคฟเคเค เคเฅ เคธเคพเคฅ เคซเฅเคฐเฅเคฎเฅเค เคเคฐเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅ, เคเคฟเคธเคธเฅ เคฏเคน เค
เคงเคฟเค เคชเค เคจเฅเคฏ เคเคฐ เคเคพเคฎ เคเคฐเคจเฅ เคฎเฅเค เคเคธเคพเคจ เคนเฅ เคเคพเคคเคพ เคนเฅเฅค",
+ "title": "XML เคธเฅเคเคฆเคฐ เคฌเคจเคพเคเค"
+ },
+ "useSpaces": "เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
+ "useSpacesDescription": "เคฐเคฟเคเฅเคค เคธเฅเคฅเคพเคจ เคเฅ เคธเคพเคฅ เคเคเคเคชเฅเค เคเคเคกเฅเคเค เคเคฐเฅเค",
+ "useTabs": "เคเฅเคฌ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
+ "useTabsDescription": "เคเฅเคฌ เคเฅ เคธเคพเคฅ เคเคเคเคชเฅเค เคเคเคกเฅเคเค เคเคฐเฅเค."
+ },
+ "xmlValidator": {
+ "allowCDATA": "CDATA เค
เคจเฅเคฎเคคเคฟ เคฆเฅเค",
+ "allowComments": "เคเคฟเคชเฅเคชเคฃเคฟเคฏเคพเค เค
เคจเฅเคฎเคคเคฟ เคฆเฅเค",
+ "description": "XML เคธเฅเคเฅเคฐเคฟเคเค เคเฅ เคตเฅเคงเคคเคพ เคเคพเคเคเฅเคเฅค",
+ "inputTitle": "เคเคจเคชเฅเค XML",
+ "placeholder": "XML เคเฅ เคฏเคนเคพเค เคเคฟเคชเคเคพเคเค เคฏเคพ เคเคฏเคพเคค เคเคฐเฅเค...",
+ "resultTitle": "เคฎเคพเคจเฅเคฏเคคเคพ เคชเคฐเคฟเคฃเคพเคฎ",
+ "shortDescription": "เคคเฅเคฐเฅเคเคฟเคฏเฅเค เคเฅ เคฒเคฟเค XML เคเฅเคก เคฎเคพเคจเฅเคฏ เคเคฐเฅเค",
+ "showErrorDetails": "เคคเฅเคฐเฅเคเคฟ เคตเคฟเคตเคฐเคฃ เคฆเคฟเคเคพเคเค",
+ "showLineNumbers": "เคชเคเคเฅเคคเคฟ เคธเคเคเฅเคฏเคพเคเค เคฆเคฟเคเคพเคเค",
+ "strictMode": "เคธเคเฅเคค เคฎเฅเคก",
+ "title": "XML เคฎเคพเคจเฅเคฏ เคเคฐเฅเค",
+ "toolInfo": {
+ "description": "เคฏเคน เคเฅเคฒ เคเคชเคเฅ XML เคธเคฟเคเคเฅเคเฅเคธ เคเคฐ เคธเคเคฐเคเคจเคพ เคเฅ เคธเคคเฅเคฏเคพเคชเคฟเคค เคเคฐเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅเฅค เคฏเคน เคเคพเคเคเคคเคพ เคนเฅ เคเคฟ XML เคธเคนเฅ เคขเคเค เคธเฅ เคฌเคจเคพ เคนเฅ เคฏเคพ เคจเคนเฅเค เคเคฐ เคเคฟเคธเฅ เคญเฅ เคธเคฎเคธเฅเคฏเคพ เคเฅ เคฒเคฟเค เคตเคฟเคธเฅเคคเฅเคค เคคเฅเคฐเฅเคเคฟ เคธเคเคฆเฅเคถ เคชเฅเคฐเคฆเคพเคจ เคเคฐเคคเคพ เคนเฅเฅค",
+ "title": "XML เคฎเคพเคจเฅเคฏ เคเคฐเฅเค"
+ },
+ "validationOptions": "เคฎเคพเคจเฅเคฏเคคเคพ เคตเคฟเคเคฒเฅเคช"
+ },
+ "xmlViewer": {
+ "collapseAll": "เคธเคญเฅ เคธเคเคเฅเคทเคฟเคชเฅเคค เคเคฐเฅเค",
+ "description": "XML เคเฅ เคชเฅเคกเคผ เคธเคเคฐเคเคจเคพ เคฎเฅเค เคฆเฅเคเฅเคเฅค",
+ "expandAll": "เคธเคญเฅ เคตเคฟเคธเฅเคคเคพเคฐเคฟเคค เคเคฐเฅเค",
+ "highlightSyntax": "เคธเคฟเคเคเฅเคเฅเคธ เคนเคพเคเคฒเคพเคเค เคเคฐเฅเค",
+ "inputTitle": "เคเคจเคชเฅเค XML",
+ "lineNumbers": "เคชเคเคเฅเคคเคฟ เคธเคเคเฅเคฏเคพเคเค",
+ "resultTitle": "XML เคชเฅเคกเคผ",
+ "showAttributes": "เคตเคฟเคถเฅเคทเคคเคพเคเค เคฆเคฟเคเคพเคเค",
+ "showTextNodes": "เคเฅเคเฅเคธเฅเค เคจเฅเคก เคฆเคฟเคเคพเคเค",
+ "title": "XML เคตเฅเคฏเฅเค
เคฐ",
+ "toolInfo": {
+ "description": "เคฏเคน เคเคชเคเคฐเคฃ เคเคชเคเฅ XML เคกเฅเคเคพ เคเฅ เคชเคฆเคพเคจเฅเคเฅเคฐเคฎเคฟเคค เคตเฅเคเฅเคท เคชเฅเคฐเคพเคฐเฅเคช เคฎเฅเค เคฆเฅเคเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคฆเฅเคคเคพ เคนเฅ, เคเคฟเคธเคธเฅ XML เคฆเคธเฅเคคเคพเคตเฅเคเคผเฅเค เคเฅ เคธเคเคฐเคเคจเคพ เคเคพ เคชเคคเคพ เคฒเคเคพเคจเคพ เคเคฐ เคธเคฎเคเคจเคพ เคเคธเคพเคจ เคนเฅ เคเคพเคคเคพ เคนเฅเฅค",
+ "title": "XML เคตเฅเคฏเฅเค
เคฐ"
+ },
+ "viewerOptions": "เคตเฅเคฏเฅเค
เคฐ เคตเคฟเคเคฒเฅเคช"
+ }
+}
diff --git a/public/locales/ja/audio.json b/public/locales/ja/audio.json
new file mode 100644
index 0000000..052e15c
--- /dev/null
+++ b/public/locales/ja/audio.json
@@ -0,0 +1,42 @@
+{
+ "changeSpeed": {
+ "description": "ใชใผใใฃใชใใกใคใซใฎๅ็้ๅบฆใๅคๆดใใพใใใใใใ็ถญๆใใชใใใใชใผใใฃใชใฎๅ็้ๅบฆใไธใใใไธใใใใงใใพใใ",
+ "inputTitle": "ๅ
ฅๅใชใผใใฃใช",
+ "newAudioSpeed": "ๆฐใใใชใผใใฃใช้ๅบฆ",
+ "outputFormat": "ๅบๅๅฝขๅผ",
+ "resultTitle": "็ทจ้ใใใใชใผใใฃใช",
+ "settingSpeed": "้ๅบฆ่จญๅฎ",
+ "shortDescription": "ใชใผใใฃใชใใกใคใซใฎ้ๅบฆใๅคๆดใใ",
+ "speedDescription": "ใใใฉใซใใฎไนๆฐ: 2ใฏ2ๅ้ใๆๅณใใพใ",
+ "title": "ใชใผใใฃใช้ๅบฆใๅคๆดใใ",
+ "toolInfo": {
+ "title": "ไฝใงใใ {{title}}๏ผ"
+ }
+ },
+ "extractAudio": {
+ "description": "ใใใช ใใกใคใซใใใชใผใใฃใช ใใฉใใฏใๆฝๅบใใพใใ",
+ "extractingAudio": "ใชใผใใฃใชใฎๆฝๅบ",
+ "inputTitle": "ๅ
ฅๅใใใช",
+ "outputFormat": "ๅบๅๅฝขๅผ",
+ "outputFormatDescription": "ๆฝๅบใใใชใผใใฃใชใฎๅฝขๅผใ้ธๆใใพใใ",
+ "resultTitle": "ๆฝๅบใใใ้ณๅฃฐ",
+ "shortDescription": "ใใใช ใใกใคใซ (MP4ใMOV ใชใฉ) ใใใชใผใใฃใชใ AACใMP3ใใพใใฏ WAV ใซๆฝๅบใใพใใ",
+ "title": "ใใใชใใใชใผใใฃใชใๆฝๅบใใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใฐใๅ็ปใใกใคใซใใ้ณๅฃฐใใฉใใฏใๆฝๅบใงใใพใใAACใMP3ใWAVใชใฉใๆงใ
ใช้ณๅฃฐๅฝขๅผใใ้ธๆใงใใพใใ",
+ "title": "ไฝใงใใ {{title}}๏ผ"
+ }
+ },
+ "mergeAudio": {
+ "description": "่คๆฐใฎใชใผใใฃใช ใใกใคใซใ้ ็ชใซ้ฃ็ตใใฆ 1 ใคใฎใชใผใใฃใช ใใกใคใซใซ็ตๅใใพใใ",
+ "longDescription": "ใใฎใใผใซใไฝฟใใฐใ่คๆฐใฎใชใผใใฃใชใใกใคใซใใขใใใญใผใ้ ใซ้ฃ็ตใใ1ใคใฎใใกใคใซใซใพใจใใใใจใใงใใพใใใใใใญใฃในใใฎใปใฐใกใณใใ้ณๆฅฝใใฉใใฏใใใฎไปๆงใ
ใชใชใผใใฃใชใใกใคใซใ็ตๅใใใฎใซๆ้ฉใงใใMP3ใAACใWAVใชใฉใๆงใ
ใชใชใผใใฃใชๅฝขๅผใซๅฏพๅฟใใฆใใพใใ",
+ "shortDescription": "่คๆฐใฎใชใผใใฃใช ใใกใคใซใ 1 ใคใซ็ตๅใใพใ (MP3ใAACใWAV)ใ",
+ "title": "ใชใผใใฃใชใ็ตๅ"
+ },
+ "trim": {
+ "description": "้ๅงๆ้ใจ็ตไบๆ้ใๆๅฎใใฆใใชใผใใฃใช ใใกใคใซใใซใใใใใณใใชใใณใฐใใ็นๅฎใฎใปใฐใกใณใใๆฝๅบใใพใใ",
+ "longDescription": "ใใฎใใผใซใไฝฟใใฐใ้ๅงๆ้ใจ็ตไบๆ้ใๆๅฎใใฆใชใผใใฃใชใใกใคใซใใใชใใณใฐใงใใพใใ้ทใใชใผใใฃใชใใกใคใซใใ็นๅฎใฎใปใฐใกใณใใๆฝๅบใใใใไธ่ฆใช้จๅใๅ้คใใใใ็ญใใฏใชใใใไฝๆใใใใงใใพใใMP3ใAACใWAVใชใฉใๆงใ
ใชใชใผใใฃใชๅฝขๅผใซๅฏพๅฟใใฆใใพใใใใใใญใฃในใ็ทจ้ใ้ณๆฅฝๅถไฝใใใฎไปใใใใใชใผใใฃใช็ทจ้ใฎใใผใบใซๆ้ฉใงใใ",
+ "shortDescription": "ใชใผใใฃใช ใใกใคใซใใใชใใณใฐใใฆ็นๅฎใฎๆ้ใปใฐใกใณใใๆฝๅบใใพใ (MP3ใAACใWAV)ใ",
+ "title": "ใชใผใใฃใชใใใชใ ใใ"
+ }
+}
diff --git a/public/locales/ja/csv.json b/public/locales/ja/csv.json
new file mode 100644
index 0000000..2a845b7
--- /dev/null
+++ b/public/locales/ja/csv.json
@@ -0,0 +1,114 @@
+{
+ "changeCsvSeparator": {
+ "description": "CSVใใกใคใซใฎๅบๅใๆๅญใๅคๆดใใพใใใซใณใใใปใใณใญใณใใฟใใใซในใฟใ ๅบๅใๆๅญใชใฉใใใพใใพใชCSVๅฝขๅผ้ใงๅคๆใงใใพใใ",
+ "shortDescription": "CSVใใกใคใซใฎๅบๅใๆๅญใๅคๆดใใ",
+ "title": "CSVใปใใฌใผใฟใผใฎๅคๆด"
+ },
+ "csvRowsToColumns": {
+ "description": "ใใฎใใผใซใฏใCSV๏ผใซใณใๅบๅใๅค๏ผใใกใคใซใฎ่กใๅใซๅคๆใใพใใๅ
ฅๅCSVใใๆฐดๅนณๆนๅใฎ่กใ1่กใใคๆฝๅบใใ90ๅบฆๅ่ปขใใใฆใใซใณใใงๅบๅใใใๅ็ดๆนๅใฎๅใจใใฆๅบๅใใพใใ', longDescription: 'ใใฎใใผใซใฏใCSV๏ผใซใณใๅบๅใๅค๏ผใใกใคใซใฎ่กใๅใซๅคๆใใพใใไพใใฐใๅ
ฅๅCSVใใผใฟใ6่กใฎๅ ดๅใๅบๅใฏ6ๅใซใชใใ่กใฎ่ฆ็ด ใฏไธใใไธใธไธฆในใใใพใใๆดๅฝขๅผใฎCSVใงใฏใๅ่กใฎๅคใฎๆฐใฏๅใใงใใใใ ใใ่กใซใใฃใผใซใใๆฌ ่ฝใใฆใใๅ ดๅใฏใใใญใฐใฉใ ใไฟฎๆญฃใใพใใๆฌ ่ฝใใผใฟใ็ฉบ่ฆ็ด ใงๅใใใใใmissingใใใ?ใใใxใใชใฉใฎใซในใฟใ ่ฆ็ด ใง็ฝฎใๆใใใใ้ธๆใงใใพใใๅคๆใใญใปในไธญใใใผใซใฏCSVใใกใคใซใใ็ฉบ่ก๏ผ่กจ็คบๆ
ๅ ฑใฎใชใ่ก๏ผใใณใกใณใใชใฉใฎไธ่ฆใชๆ
ๅ ฑใๅ้คใใพใใใใผใซใใณใกใณใใๆญฃใใ่ญๅฅใงใใใใใซใใชใใทใงใณใง่ก้ ญใฎใณใกใณใ้ๅง่จๅทใๆๅฎใงใใพใใใใฎ่จๅทใฏ้ๅธธใใใใทใฅใ#ใใพใใฏใใใซในใฉใใทใฅใ//ใใงใใCSV-abulous!",
+ "longDescription": "ใใฎใใผใซใฏใCSV๏ผใซใณใๅบๅใๅค๏ผใใกใคใซใฎ่กใๅใซๅคๆใใพใใไพใใฐใๅ
ฅๅCSVใใผใฟใ6่กใฎๅ ดๅใๅบๅใฏ6ๅใซใชใใ่กใฎ่ฆ็ด ใฏไธใใไธใซไธฆในใใใพใใๆดๅฝขๅผใฎCSVใงใฏใๅ่กใฎๅคใฎๆฐใฏๅใใงใใใใ ใใ่กใซใใฃใผใซใใๆฌ ่ฝใใฆใใๅ ดๅใฏใใใญใฐใฉใ ใไฟฎๆญฃใใๅฉ็จๅฏ่ฝใชใชใใทใงใณใใ้ธๆใงใใพใใๆฌ ่ฝใใผใฟใ็ฉบใฎ่ฆ็ด ใงๅใใใใๆฌ ่ฝใใผใฟใใซในใฟใ ่ฆ็ด ใง็ฝฎใๆใใพใใ",
+ "shortDescription": "CSV ใฎ่กใๅใซๅคๆใใพใใ",
+ "title": "CSVใฎ่กใๅใซๅคๆใใ"
+ },
+ "csvToJson": {
+ "columnSeparator": "ๅๅบๅใๆๅญ๏ผไพ๏ผ, ; \\t๏ผ",
+ "commentSymbol": "ใณใกใณใ่จๅท๏ผไพ๏ผ#๏ผ",
+ "conversionOptions": "ๅคๆใชใใทใงใณ",
+ "description": "ๅบๅใๆๅญใๅผ็จ็ฌฆใๅบๅใใฉใผใใใใชใฉใฎใซในใฟใใคใบๅฏ่ฝใชใชใใทใงใณใไฝฟ็จใใฆใCSVใใกใคใซใJSONๅฝขๅผใซๅคๆใใพใใใใใใผใใณใกใณใใๅ็ใชๅๅคๆใใตใใผใใใพใใ",
+ "dynamicTypes": "ๅ็ๅ",
+ "dynamicTypesDescription": "ๆฐๅคใจใใผใซๅคใ่ชๅ็ใซๅคๆใใ",
+ "errorParsing": "CSV ่งฃๆใจใฉใผ: {{error}}",
+ "fieldQuote": "ใใฃใผใซใๅผ็จ็ฌฆ๏ผไพ๏ผ \"๏ผ",
+ "inputCsvFormat": "ๅ
ฅๅCSVๅฝขๅผ",
+ "inputTitle": "ๅ
ฅๅCSV",
+ "resultTitle": "ๅบๅJSON",
+ "shortDescription": "CSV ใใผใฟใ JSON ๅฝขๅผใซๅคๆใใพใใ",
+ "skipEmptyLines": "็ฉบ่กใในใญใใ",
+ "skipEmptyLinesDescription": "ๅ
ฅๅCSVๅ
ใฎ็ฉบ่กใ็ก่ฆใใ",
+ "title": "CSVใJSONใซๅคๆใใ",
+ "useHeaders": "ใใใใผใไฝฟ็จใใ",
+ "useHeadersDescription": "ๆๅใฎ่กใๅใใใใผใจใใฆๆฑใ"
+ },
+ "csvToTsv": {
+ "description": "ไปฅไธใฎใใฉใผใ ใซCSVใใกใคใซใใขใใใญใผใใใใจใ่ชๅ็ใซTSVใใกใคใซใซๅคๆใใใพใใใใผใซใฎใชใใทใงใณใงใฏใๅ
ฅๅCSVๅฝขๅผใใซในใฟใใคใบใงใใพใใใใฃใผใซใๅบๅใๆๅญใๅผ็จ็ฌฆใใณใกใณใ่จๅทใๆๅฎใใใใ็ฉบใฎCSV่กใในใญใใใใใใCSVใฎๅใใใใผใไฟๆใใใใฉใใใ้ธๆใใใใงใใพใใ",
+ "longDescription": "ใใฎใใผใซใฏใใซใณใๅบๅใๅค๏ผCSV๏ผใใผใฟใใฟใๅบๅใๅค๏ผTSV๏ผใใผใฟใซๅคๆใใพใใCSVใจTSVใฏใฉใกใใ่กจๅฝขๅผใฎใใผใฟใไฟๅญใใไธ่ฌ็ใชใใกใคใซๅฝขๅผใงใใใๅคใๅบๅใๅบๅใๆๅญใ็ฐใชใใพใใCSVใงใฏใซใณใ๏ผ",
+ "shortDescription": "CSV ใใผใฟใ TSV ๅฝขๅผใซๅคๆใใพใใ",
+ "title": "CSVใTSVใซๅคๆใใ"
+ },
+ "csvToXml": {
+ "description": "ใซในใฟใใคใบๅฏ่ฝใชใชใใทใงใณใไฝฟ็จใใฆใCSV ใใกใคใซใ XML ๅฝขๅผใซๅคๆใใพใใ",
+ "shortDescription": "CSV ใใผใฟใ XML ๅฝขๅผใซๅคๆใใพใใ",
+ "title": "CSVใXMLใซๅคๆใใ"
+ },
+ "csvToYaml": {
+ "description": "ไธ่จใฎใใฉใผใ ใซCSVใใกใคใซใใขใใใญใผใใใใ ใใงใ่ชๅ็ใซYAMLใใกใคใซใซๅคๆใใใพใใใใผใซใชใใทใงใณใงใฏใใใฃใผใซใๅบๅใๆๅญใใใฃใผใซใๅผ็จ็ฌฆใใณใกใณใๆๅญใๆๅฎใใฆใใซในใฟใ CSVๅฝขๅผใซๅฏพๅฟใใใใใจใใงใใพใใใใใซใๅบๅYAMLๅฝขๅผใจใใฆใCSVใใใใผใไฟๆใใๅฝขๅผใจCSVใใใใผใ้คๅคใใๅฝขๅผใ้ธๆใงใใพใใ",
+ "longDescription": "ใใฎใใผใซใฏใCSV๏ผใซใณใๅบๅใๅค๏ผใใผใฟใYAML๏ผYet Another Markup Language๏ผใใผใฟใซๅคๆใใพใใCSVใฏใ่กใจๅใงๆงๆใใใ่กๅใฎใใใชใใผใฟๅใ่กจใใใใซไฝฟ็จใใใใทใณใใซใช่กจๅฝขๅผใงใใไธๆนใYAMLใฏใใ้ซๅบฆใชๅฝขๅผ๏ผๅฎ้ใซใฏJSONใฎในใผใใผใปใใ๏ผใงใใใใทใชใขใซๅใฎใใใซไบบ้ใ่ชญใฟใใใใใผใฟใไฝๆใใใชในใใ่พๆธใใในใใใใใชใใธใงใฏใใใตใใผใใใฆใใพใใใใฎใใญใฐใฉใ ใฏใใใพใใพใชๅ
ฅๅCSVๅฝขๅผใใตใใผใใใฆใใพใใๅ
ฅๅใใผใฟใฏใใซใณใๅบๅใ๏ผใใใฉใซใ๏ผใใปใใณใญใณๅบๅใใใใคใๅบๅใใใพใใฏๅ
จใ็ฐใชใๅบๅใๆๅญใไฝฟ็จใงใใพใใใชใใทใงใณใงใใใผใฟใงไฝฟ็จใใๆญฃ็ขบใชๅบๅใๆๅญใๆๅฎใงใใพใใๅๆงใซใใชใใทใงใณใงใฏใCSVใใฃใผใซใใๅฒใใใใซไฝฟ็จใใใๅผ็จ็ฌฆๆๅญ๏ผใใใฉใซใใฏไบ้ๅผ็จ็ฌฆ๏ผใๆๅฎใงใใพใใใพใใใชใใทใงใณใงใณใกใณใ่จๅทใๆๅฎใใใใจใซใใใใณใกใณใใงๅงใพใ่กใในใญใใใใใใจใใงใใพใใใใใซใใใไธ่ฆใช่กใในใญใใใใฆใใผใฟใๆด็ใงใใพใใCSVใYAMLใซๅคๆใใใซใฏใ2ใคใฎๆนๆณใใใใพใใๆๅใฎๆนๆณใฏใCSVใฎๅ่กใYAMLใชในใใซๅคๆใใพใใ2็ช็ฎใฎๆนๆณใฏใCSVใฎๆๅใฎ่กใใใใใใผใๆฝๅบใใใใใใฎใใใใผใซๅบใฅใใฆใญใผใๆใคYAMLใชใใธใงใฏใใไฝๆใใพใใYAMLๆง้ ใฎใคใณใใณใใซไฝฟ็จใใในใใผในใฎๆฐใๆๅฎใใใใจใงใๅบๅYAMLๅฝขๅผใใซในใฟใใคใบใใใใจใใงใใพใใ้ๅคๆใใคใพใYAMLใใCSVใธใฎๅคๆใๅฟ
่ฆใชๅ ดๅใฏใYAMLใใCSVใธใฎๅคๆใใผใซใใๅฉ็จใใ ใใใCSVๅคๆใฏใพใใซ่ณ้ซใงใ๏ผ",
+ "shortDescription": "CSV ใใกใคใซใ YAML ใใกใคใซใซใใฐใใๅคๆใใพใใ",
+ "title": "CSVใYAMLใซๅคๆใใ"
+ },
+ "findIncompleteCsvRecords": {
+ "checkingOptions": "ใชใใทใงใณใฎ็ขบ่ช",
+ "commentCharacterDescription": "ใณใกใณใ่กใฎ้ๅงใ็คบใๆๅญใๅ
ฅๅใใพใใใใฎ่จๅทใงๅงใพใ่กใฏในใญใใใใใพใใ",
+ "csvInputOptions": "CSVๅ
ฅๅใชใใทใงใณ",
+ "csvSeparatorDescription": "CSV ๅ
ฅๅใใกใคใซๅ
ใฎๅใๅบๅใใใใซไฝฟ็จใใๆๅญใๅ
ฅๅใใพใใ",
+ "deleteLinesWithNoData": "ใใผใฟใฎใชใ่กใๅ้คใใ",
+ "deleteLinesWithNoDataDescription": "CSV ๅ
ฅๅใใกใคใซใใ็ฉบใฎ่กใๅ้คใใพใใ",
+ "description": "ไปฅไธใฎใใฉใผใ ใซCSVใใกใคใซใใขใใใญใผใใใใ ใใงใใใฎใใผใซใฏ่กใพใใฏๅใซๆฌ ๆๅคใใชใใใฉใใใ่ชๅ็ใซใใงใใฏใใพใใใใผใซใฎใชใใทใงใณใงใฏใๅ
ฅๅใใกใคใซใฎๅฝขๅผ๏ผๅบๅใๆๅญใๅผ็จ็ฌฆใใณใกใณใๆๅญใฎๆๅฎ๏ผใ่ชฟๆดใงใใพใใใใใซใ็ฉบๅคใฎใใงใใฏใๆๅนใซใใใใ็ฉบ่กใในใญใใใใใใๅบๅๆใฎใจใฉใผใกใใปใผใธใฎๆฐใซๅถ้ใ่จญๅฎใใใใใใใจใใงใใพใใ",
+ "findEmptyValues": "็ฉบใฎๅคใ่ฆใคใใ",
+ "findEmptyValuesDescription": "็ฉบใฎ CSV ใใฃใผใซใใซ้ขใใใกใใปใผใธใ่กจ็คบใใพใ (ใใใใฏๆฌ ่ฝใใใใฃใผใซใใงใฏใชใใไฝใๅซใพใใฆใใชใใใฃใผใซใใงใ)ใ",
+ "inputTitle": "ๅ
ฅๅCSV",
+ "limitNumberOfMessages": "ใกใใปใผใธๆฐใๅถ้ใใ",
+ "messageLimitDescription": "ๅบๅใใใใกใใปใผใธๆฐใฎๅถ้ใ่จญๅฎใใพใใ",
+ "quoteCharacterDescription": "CSV ๅ
ฅๅใใฃใผใซใใๅผ็จใใใใใซไฝฟ็จใใๅผ็จ็ฌฆๆๅญใๅ
ฅๅใใพใใ",
+ "resultTitle": "CSVในใใผใฟใน",
+ "shortDescription": "CSV ๅ
ใงๅคใๆฌ ่ฝใใฆใใ่กใจๅใใใฐใใ่ฆใคใใพใใ",
+ "title": "ไธๅฎๅ
จใชCSVใฌใณใผใใ่ฆใคใใ",
+ "toolInfo": {
+ "title": "ไฝใงใใ {{title}}๏ผ"
+ }
+ },
+ "insertCsvColumns": {
+ "appendColumns": "ๅใ่ฟฝๅ ใใ",
+ "commentCharacterDescription": "ใณใกใณใ่กใฎ้ๅงใ็คบใๆๅญใๅ
ฅๅใใพใใใใฎ่จๅทใงๅงใพใ่กใฏในใญใใใใใพใใ",
+ "csvOptions": "CSVใชใใทใงใณ",
+ "csvSeparator": "CSVใปใใฌใผใฟใผ",
+ "csvToInsert": "ๆฟๅ
ฅใใCSV",
+ "csvToInsertDescription": "CSVใซๆฟๅ
ฅใใใๅใ1ใคไปฅไธๅ
ฅๅใใฆใใ ใใใๅๅบๅใใซไฝฟ็จใใๆๅญใฏใCSVๅ
ฅๅใใกใคใซๅ
ใฎๆๅญใจๅใใงใใๅฟ
่ฆใใใใพใใๆณจ๏ผ็ฉบ็ฝ่กใฏ็ก่ฆใใใพใใ",
+ "customFillDescription": "ๅ
ฅๅ CSV ใใกใคใซใไธๅฎๅ
จ (ๅคใๆฌ ่ฝใใฆใใ) ใชๅ ดๅใฏใใฌใณใผใใซ็ฉบใฎใใฃใผใซใใพใใฏใซในใฟใ ใทใณใใซใ่ฟฝๅ ใใฆใๆดๅฝขๅผใฎ CSV ใไฝๆใใพใใ?",
+ "customFillValueDescription": "ใใฎใซในใฟใ ๅคใไฝฟ็จใใฆใไธ่ถณใใฆใใใใฃใผใซใใๅ
ฅๅใใพใใ(ไธ่จใฎใใซในใฟใ ๅคใใขใผใใงใฎใฟๆฉ่ฝใใพใใ)",
+ "customPosition": "ใซในใฟใ ไฝ็ฝฎ",
+ "customPositionOptionsDescription": "CSV ใใกใคใซใซๅใๆฟๅ
ฅใใๆนๆณใ้ธๆใใพใใ",
+ "description": "ๆๅฎใใใไฝ็ฝฎใซ CSV ใใผใฟใซๆฐใใๅใ่ฟฝๅ ใใพใใ",
+ "fillWithCustomValues": "้ข็จ้กใๅ
ฅๅใใ",
+ "fillWithEmptyValues": "็ฉบใฎๅคใๅ
ฅๅใใ",
+ "headerName": "ใใใใผๅ",
+ "headerNameDescription": "ๅพใใซๅใๆฟๅ
ฅใใๅใฎใใใใผใ",
+ "inputTitle": "ๅ
ฅๅCSV",
+ "insertingPositionDescription": "CSV ใใกใคใซๅ
ใฎๅใๆฟๅ
ฅใใๅ ดๆใๆๅฎใใพใใ",
+ "position": "ไฝ็ฝฎ",
+ "positionOptions": "ใใธใทใงใณใชใใทใงใณ",
+ "prependColumns": "ๅใๅ
้ ญใซ่ฟฝๅ ใใ",
+ "quoteCharDescription": "CSV ๅ
ฅๅใใฃใผใซใใๅผ็จใใใใใซไฝฟ็จใใๅผ็จ็ฌฆๆๅญใๅ
ฅๅใใพใใ",
+ "resultTitle": "CSVๅบๅ",
+ "rowNumberDescription": "ๅพใใซๅใๆฟๅ
ฅใใๅใฎ็ชๅทใ",
+ "separatorDescription": "CSV ๅ
ฅๅใใกใคใซๅ
ใฎๅใๅบๅใใใใซไฝฟ็จใใๆๅญใๅ
ฅๅใใพใใ",
+ "shortDescription": "CSV ใใกใคใซๅ
ใฎไปปๆใฎๅ ดๆใซ 1 ใคไปฅไธใฎๆฐใใๅใใใฐใใๆฟๅ
ฅใใพใใ",
+ "title": "CSVๅใๆฟๅ
ฅใใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟ็จใใใจใCSVใใผใฟใฎๆๅฎใใไฝ็ฝฎใซๆฐใใๅใๆฟๅ
ฅใงใใพใใใใใใผๅใพใใฏๅ็ชๅทใซๅบใฅใใฆใไปปๆใฎไฝ็ฝฎใซๅใ่ฟฝๅ ใ่ฟฝๅ ใใพใใฏๆฟๅ
ฅใงใใพใใ",
+ "title": "CSVๅใฎๆฟๅ
ฅ"
+ }
+ },
+ "swapCsvColumns": {
+ "description": "ไปฅไธใฎใใฉใผใ ใซCSVใใกใคใซใใขใใใญใผใใใๅ
ฅใๆฟใใใๅใๆๅฎใใใ ใใงใใใผใซใฏๅบๅใใกใคใซๅ
ใงๆๅฎใใใๅใฎไฝ็ฝฎใ่ชๅ็ใซๅคๆดใใพใใใใผใซใฎใชใใทใงใณใงใฏใๅ
ฅใๆฟใใใๅใฎไฝ็ฝฎใๅๅใๆๅฎใงใใใปใใไธๅฎๅ
จใชใใผใฟใไฟฎๆญฃใใใใ็ฉบใฎใฌใณใผใใใณใกใณใใขใฆใใใใใฌใณใผใใๅ้คใใใใใใใจใใงใใพใใ",
+ "longDescription": "ใใฎใใผใซใฏใCSVใใผใฟใฎๅใฎไฝ็ฝฎใๅ
ฅใๆฟใใใใจใงใใผใฟใๅๆงๆใใพใใๅใๅ
ฅใๆฟใใใใจใงใ้ ป็นใซไฝฟ็จใใใใผใฟใใพใจใใฆ้
็ฝฎใใใใๅ
้ ญใซ้
็ฝฎใใใใใใใจใงใใใผใฟใฎๆฏ่ผใ็ทจ้ใๅฎนๆใซใชใใCSVใใกใคใซใฎ่ชญใฟใใใใๅไธใใพใใไพใใฐใๆๅใฎๅใๆๅพใฎๅใจๅ
ฅใๆฟใใใใ2็ช็ฎใฎๅใ3็ช็ฎใฎๅใจๅ
ฅใๆฟใใใใใใใจใใงใใพใใๅใฎไฝ็ฝฎใซๅบใฅใใฆๅใๅ
ฅใๆฟใใใซใฏใ",
+ "shortDescription": "CSV ๅใไธฆในๆฟใใพใใ",
+ "title": "CSVๅใฎๅ
ฅใๆฟใ"
+ },
+ "transposeCsv": {
+ "description": "ไปฅไธใฎใใฉใผใ ใซCSVใใกใคใซใใขใใใญใผใใใใ ใใงใใใฎใใผใซใ่ชๅ็ใซCSVใ่ปข็ฝฎใใพใใใใผใซใฎใชใใทใงใณใงใฏใCSVๅ
ใฎใณใกใณใ่กใฎๅ
้ ญๆๅญใๆๅฎใใฆๅ้คใงใใพใใใพใใCSVใไธๅฎๅ
จ๏ผๆฌ ๆๅค๏ผใชๅ ดๅใฏใๆฌ ๆๅคใ็ฉบๆๅญใพใใฏไปปๆใฎๆๅญใซ็ฝฎใๆใใใใจใใงใใพใใ",
+ "longDescription": "ใใฎใใผใซใฏใใซใณใๅบๅใๅค๏ผCSV๏ผใ่ปข็ฝฎใใพใใCSVใใใผใฟใฎ่กๅใจใใฆๆฑใใใในใฆใฎ่ฆ็ด ใไธปๅฏพ่ง็ทใๆใใงๅ่ปขใใพใใๅบๅใซใฏๅ
ฅๅใจๅใCSVใใผใฟใๅซใพใใพใใใใในใฆใฎ่กใๅใซใชใใใในใฆใฎๅใ่กใซใชใใพใใ่ปข็ฝฎๅพใCSVใใกใคใซใฎๆฌกๅ
ใฏ้ใซใชใใพใใใใจใใฐใๅ
ฅๅใใกใคใซใซ4ๅ3่กใใใๅ ดๅใๅบๅใใกใคใซใฏ3ๅ4่กใซใชใใพใใๅคๆไธญใซใใใญใฐใฉใ ใฏไธ่ฆใช่กใฎใใผใฟใๅ้คใใไธๅฎๅ
จใชใใผใฟใไฟฎๆญฃใใพใใๅ
ทไฝ็ใซใฏใใใผใซใฏใชใใทใงใณใง่จญๅฎใงใใ็นๅฎใฎๆๅญใงๅงใพใใในใฆใฎ็ฉบใฎใฌใณใผใใจใณใกใณใใ่ชๅ็ใซๅ้คใใพใใใใใซใCSVใใผใฟใ็ ดๆใพใใฏๅคฑใใใๅ ดๅใใฆใผใใฃใชใใฃใฏใชใใทใงใณใงๆๅฎใงใใ็ฉบใฎใใฃใผใซใใพใใฏใซในใฟใ ใใฃใผใซใใงใใกใคใซใ่ฃๅฎใใพใใCSV-abulous!",
+ "shortDescription": "CSV ใใกใคใซใใใฐใใ่ปข็ฝฎใใพใใ",
+ "title": "CSV่ปข็ฝฎ"
+ }
+}
diff --git a/public/locales/ja/image.json b/public/locales/ja/image.json
new file mode 100644
index 0000000..26c5547
--- /dev/null
+++ b/public/locales/ja/image.json
@@ -0,0 +1,98 @@
+{
+ "changeColors": {
+ "description": "ไธ็",
+ "shortDescription": "็ปๅๅ
ใฎ่ฒใ็ด ๆฉใๅ
ฅใๆฟใใ",
+ "title": "็ปๅใฎ่ฒใๅคๆดใใ"
+ },
+ "changeOpacity": {
+ "description": "็ปๅใฎ้ๆๅบฆใ็ฐกๅใซ่ชฟๆดใงใใพใใ็ปๅใใขใใใญใผใใใในใฉใคใใผใไฝฟใฃใฆ0๏ผๅฎๅ
จใซ้ๆ๏ผใใ1๏ผๅฎๅ
จใซไธ้ๆ๏ผใฎ้ใงๅธๆใฎไธ้ๆๅบฆใ่จญๅฎใใๅคๆดใใ็ปๅใใใฆใณใญใผใใใใ ใใงใใ",
+ "shortDescription": "็ปๅใฎ้ๆๅบฆใ่ชฟๆดใใ",
+ "title": "็ปๅใฎไธ้ๆๅบฆใๅคๆดใใ"
+ },
+ "compress": {
+ "description": "ๅ่ณชใ็ถญๆใใชใใ็ปๅใใกใคใซใฎใตใคใบใ็ธฎๅฐใใพใใ",
+ "inputTitle": "ๅ
ฅๅ็ปๅ",
+ "resultTitle": "ๅง็ธฎ็ปๅ",
+ "shortDescription": "้ฉๅใชๅ่ณชใ็ถญๆใใชใใ็ปๅใๅง็ธฎใใฆใใกใคใซ ใตใคใบใ็ธฎๅฐใใพใใ",
+ "title": "็ปๅใๅง็ธฎ"
+ },
+ "compressPng": {
+ "description": "ใใใฏPNG็ปๅใๅง็ธฎใใใใญใฐใฉใ ใงใใPNG็ปๅใๅ
ฅๅใจใชใขใซ่ฒผใไปใใใจใใใญใฐใฉใ ใใใใซๅง็ธฎใใๅบๅใจใชใขใซ็ตๆใ่กจ็คบใใพใใใชใใทใงใณใงใฏใๅง็ธฎใฌใใซใ่ชฟๆดใใใใๅง็ธฎๅใฎ็ปๅใใกใคใซใตใคใบใจๆฐใใ็ปๅใใกใคใซใตใคใบใ็ขบ่ชใใใใงใใพใใ",
+ "shortDescription": "PNGใ็ด ๆฉใๅง็ธฎใใ",
+ "title": "PNGใๅง็ธฎใใ"
+ },
+ "convertJgpToPng": {
+ "description": "JPG็ปๅใPNGใซ็ด ๆฉใๅคๆใงใใพใใๅทฆๅดใฎใจใใฃใฟใซPNG็ปๅใใคใณใใผใใใใ ใใงใใ",
+ "shortDescription": "JPG็ปๅใPNGใซ็ด ๆฉใๅคๆ",
+ "title": "JPGใPNGใซๅคๆใใ"
+ },
+ "convertToJpg": {
+ "description": "ใใพใใพใช็ปๅๅฝขๅผ (PNGใGIFใTIFใPSDใSVGใWEBPใHEICใRAW) ใใใซในใฟใใคใบๅฏ่ฝใชๅ่ณชใจ่ๆฏ่ฒใฎ่จญๅฎใง JPG ใซๅคๆใใพใใ",
+ "shortDescription": "ๅ่ณช็ฎก็ใใชใใ็ปๅใJPGใซๅคๆใใ",
+ "title": "็ปๅใJPGใซๅคๆใใ"
+ },
+ "createTransparent": {
+ "description": "ไธ็",
+ "shortDescription": "็ปๅใ็ด ๆฉใ้ๆใซใใ",
+ "title": "้ๆใชPNGใไฝๆใใ"
+ },
+ "crop": {
+ "description": "็ปๅใใใชใใณใฐใใฆไธ่ฆใช้จๅใๅ้คใใพใใ",
+ "inputTitle": "ๅ
ฅๅ็ปๅ",
+ "resultTitle": "ๅใๆใใใ็ปๅ",
+ "shortDescription": "็ปๅใ็ด ๆฉใๅใๅใใพใใ",
+ "title": "็ปๅใใใชใใณใฐ"
+ },
+ "editor": {
+ "description": "ๅใๆใใๅ่ปขใๆณจ้ใ่ฒ่ชฟๆดใ้ใใใฎ่ฟฝๅ ใชใฉใ้ซๅบฆใช็ปๅ็ทจ้ใใผใซใๅใใ้ซๅบฆใช็ปๅใจใใฃใฟใผใใใญไปๆงใฎใใผใซใไฝฟใฃใฆใใใฉใฆใถไธใง็ดๆฅ็ปๅใ็ทจ้ใงใใพใใ",
+ "shortDescription": "้ซๅบฆใชใใผใซใจๆฉ่ฝใง็ปๅใ็ทจ้ใใ",
+ "title": "็ปๅใจใใฃใฟ"
+ },
+ "imageToText": {
+ "description": "ๅ
ๅญฆๆๅญ่ช่ญ (OCR) ใไฝฟ็จใใฆ็ปๅ (JPGใPNG) ใใใใญในใใๆฝๅบใใพใใ",
+ "shortDescription": "OCR ใไฝฟ็จใใฆ็ปๅใใใใญในใใๆฝๅบใใพใใ",
+ "title": "็ปๅใใใใญในใใธ๏ผOCR๏ผ"
+ },
+ "qrCode": {
+ "description": "URLใใใญในใใ้ปๅญใกใผใซใ้ป่ฉฑใSMSใWiFiใvCard ใชใฉใใใพใใพใชใใผใฟ ใฟใคใใฎ QR ใณใผใใ็ๆใใพใใ",
+ "shortDescription": "ใใพใใพใชใใผใฟๅฝขๅผใซๅใใใฆใซในใฟใใคใบใใใ QR ใณใผใใไฝๆใใพใใ",
+ "title": "QRใณใผใใธใงใใฌใผใฟใผ"
+ },
+ "removeBackground": {
+ "description": "ไธ็",
+ "shortDescription": "็ปๅใใ่ๆฏใ่ชๅ็ใซๅ้คใใ",
+ "title": "็ปๅใใ่ๆฏใๅ้คใใ"
+ },
+ "resize": {
+ "description": "็ปๅใใใพใใพใชๅฏธๆณใซๅใใใฆใตใคใบๅคๆดใใพใใ",
+ "dimensionType": "ใใฃใกใณใทใงใณใฟใคใ",
+ "heightDescription": "้ซใ๏ผใใฏใปใซๅไฝ๏ผ",
+ "inputTitle": "ๅ
ฅๅ็ปๅ",
+ "maintainAspectRatio": "ใขในใใฏใๆฏใ็ถญๆ",
+ "maintainAspectRatioDescription": "็ปๅใฎๅ
ใฎใขในใใฏใๆฏใ็ถญๆใใพใใ",
+ "percentage": "ใใผใปใณใใผใธ",
+ "percentageDescription": "ๅ
ใฎใตใคใบใฎๅฒๅ๏ผไพ๏ผๅๅใฎใตใคใบใฎๅ ดๅใฏ 50ใ2 ๅใฎใตใคใบใฎๅ ดๅใฏ 200๏ผ",
+ "resizeByPercentage": "ใใผใปใณใใผใธใงใตใคใบใๅคๆดใใ",
+ "resizeByPercentageDescription": "ๅ
ใฎใตใคใบใฎใใผใปใณใใผใธใๆๅฎใใฆใตใคใบใๅคๆดใใพใใ",
+ "resizeByPixels": "ใใฏใปใซๅไฝใงใตใคใบๅคๆด",
+ "resizeByPixelsDescription": "ใใฏใปใซๅไฝใงๅฏธๆณใๆๅฎใใฆใตใคใบใๅคๆดใใพใใ",
+ "resizeMethod": "ใตใคใบๅคๆดๆนๆณ",
+ "resultTitle": "ใตใคใบๅคๆดใใใ็ปๅ",
+ "setHeight": "้ซใใฎ่จญๅฎ",
+ "setHeightDescription": "้ซใใใใฏใปใซๅไฝใงๆๅฎใใใขในใใฏใๆฏใซๅบใฅใใฆๅน
ใ่จ็ฎใใพใใ",
+ "setWidth": "ๅน
ใ่จญๅฎใใ",
+ "setWidthDescription": "ๅน
ใใใฏใปใซๅไฝใงๆๅฎใใใขในใใฏใๆฏใซๅบใฅใใฆ้ซใใ่จ็ฎใใพใใ",
+ "shortDescription": "็ปๅใฎใตใคใบใ็ฐกๅใซๅคๆดใงใใพใใ",
+ "title": "็ปๅใฎใตใคใบๅคๆด",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใฐใJPGใPNGใSVGใGIF็ปๅใฎใตใคใบใๅคๆดใงใใพใใใใฏใปใซๅไฝใพใใฏใใผใปใณใใผใธใงใตใคใบใๆๅฎใใๅ
ใฎใขในใใฏใๆฏใ็ถญๆใใใชใใทใงใณใ็จๆใใใฆใใพใใ",
+ "title": "็ปๅใฎใตใคใบๅคๆด"
+ },
+ "widthDescription": "ๅน
๏ผใใฏใปใซๅไฝ๏ผ"
+ },
+ "rotate": {
+ "description": "ๆๅฎใใใ่งๅบฆใง็ปๅใๅ่ปขใใพใใ",
+ "shortDescription": "็ปๅใ็ฐกๅใซๅ่ปขใใพใใ",
+ "title": "็ปๅใๅ่ปขใใ"
+ }
+}
diff --git a/public/locales/ja/json.json b/public/locales/ja/json.json
new file mode 100644
index 0000000..c929d56
--- /dev/null
+++ b/public/locales/ja/json.json
@@ -0,0 +1,62 @@
+{
+ "escapeJson": {
+ "description": "JSONๆๅญๅๅ
ใฎ็นๆฎๆๅญใใจในใฑใผใใใพใใJSONใใผใฟใ้ฉๅใซใจในใฑใผใใใใๅฝขๅผใซๅคๆใใฆใๅฎๅ
จใช่ปข้ใไฟๅญใๅฎ็พใใพใใ",
+ "shortDescription": "JSONๅ
ใฎ็นๆฎๆๅญใใจในใฑใผใใใ",
+ "title": "JSON ใฎใจในใฑใผใ"
+ },
+ "jsonToXml": {
+ "description": "JSONใใผใฟใXMLๅฝขๅผใซๅคๆใใพใใๆง้ ๅใใใJSONใชใใธใงใฏใใๆดๅฝขๅผใฎXMLใใญใฅใกใณใใซๅคๆใใพใใ",
+ "shortDescription": "JSONใXMLๅฝขๅผใซๅคๆใใ",
+ "title": "JSONใใXMLใธ"
+ },
+ "minify": {
+ "description": "JSON ใใไธ่ฆใช็ฉบ็ฝใใในใฆๅ้คใใพใใ",
+ "inputTitle": "ๅ
ฅๅJSON",
+ "resultTitle": "็ธฎๅฐใใใJSON",
+ "shortDescription": "็ฉบ็ฝใๅ้คใใฆJSONใ็ธฎๅฐใใ",
+ "title": "JSONใ็ธฎๅฐใใ",
+ "toolInfo": {
+ "description": "JSONใฎ็ธฎๅฐใจใฏใJSONใใผใฟใฎๅฆฅๅฝๆงใ็ถญๆใใชใใใไธ่ฆใช็ฉบ็ฝๆๅญใใในใฆๅ้คใใใใญใปในใงใใใใใซใฏใJSONใๆญฃใใ่งฃๆใใใใใซไธ่ฆใชในใใผในใๆน่กใใคใณใใณใใชใฉใๅซใพใใพใใ็ธฎๅฐใซใใJSONใใผใฟใฎใตใคใบใ็ธฎๅฐใใใใใผใฟๆง้ ใจๅคใฏๅ
จใๅใใพใพใไฟๅญใจ่ปข้ใฎๅน็ใๅไธใใพใใ",
+ "title": "JSON ใฎ็ธฎๅฐใจใฏไฝใงใใ?"
+ }
+ },
+ "prettify": {
+ "description": "้ฉๅใชใคใณใใณใใจในใใผในใไฝฟ็จใใฆ JSON ใใใฉใผใใใใใพใใ",
+ "indentation": "ใคใณใใณใ",
+ "inputTitle": "ๅ
ฅๅJSON",
+ "resultTitle": "ๆดๅฝขใใใJSON",
+ "shortDescription": "JSON ใณใผใใใใฉใผใใใใใฆ็พใใใใ",
+ "title": "JSONใ็พใใใใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟ็จใใใจใJSON ใใผใฟใ้ฉๅใชใคใณใใณใใจในใใผในใงใใฉใผใใใใงใใใใใ่ชญใฟใใใใๆไฝใใใใใชใใพใใ",
+ "title": "JSONใ็พใใใใ"
+ },
+ "useSpaces": "ในใใผในใไฝฟ็จใใ",
+ "useSpacesDescription": "ในใใผในใงๅบๅใใคใณใใณใใใ",
+ "useTabs": "ใฟใใไฝฟ็จใใ",
+ "useTabsDescription": "ๅบๅใใฟใใงใคใณใใณใใใพใใ"
+ },
+ "stringify": {
+ "description": "JavaScriptใชใใธใงใฏใใJSONๆๅญๅๅฝขๅผใซๅคๆใใพใใใใผใฟๆง้ ใJSONๆๅญๅใซใทใชใขใซๅใใฆไฟๅญใพใใฏ่ปข้ใใพใใ",
+ "shortDescription": "ใชใใธใงใฏใใJSONๆๅญๅใซๅคๆใใ",
+ "title": "JSONใๆๅญๅๅใใ"
+ },
+ "tsvToJson": {
+ "description": "TSV๏ผใฟใๅบๅใๅค๏ผใใผใฟใJSONๅฝขๅผใซๅคๆใใพใใ่กจๅฝขๅผใฎใใผใฟใๆง้ ๅใใใJSONใชใใธใงใฏใใซๅคๆใใพใใ",
+ "shortDescription": "TSVใJSONๅฝขๅผใซๅคๆใใ",
+ "title": "TSVใใJSONใธ"
+ },
+ "validateJson": {
+ "description": "JSON ใๆๅนใใคๆดๅฝขๅผใงใใใใฉใใใ็ขบ่ชใใพใใ",
+ "inputTitle": "ๅ
ฅๅJSON",
+ "invalidJson": "โ {{error}}",
+ "resultTitle": "ๆค่จผ็ตๆ",
+ "shortDescription": "JSONใณใผใใฎใจใฉใผใๆค่จผใใ",
+ "title": "JSONใๆค่จผใใ",
+ "toolInfo": {
+ "description": "JSON๏ผJavaScript Object Notation๏ผใฏ่ปฝ้ใชใใผใฟไบคๆๅฝขๅผใงใใJSONๆค่จผใฏใใใผใฟใฎๆง้ ใJSONๆจๆบใซๆบๆ ใใฆใใใใจใ็ขบ่ชใใพใใๆๅนใชJSONใชใใธใงใฏใใซใฏใไปฅไธใฎ่ฆ็ด ใๅฟ
่ฆใงใใ- ใใญใใใฃๅใไบ้ๅผ็จ็ฌฆใงๅฒใพใใฆใใใ- ไธญๆฌๅผง{}ใ้ฉๅใซใใฉใณในใใใฆใใใ- ๆๅพใฎใญใผใจๅคใฎใใขใฎๅพใซใซใณใใไปใใฆใใชใใ- ใชใใธใงใฏใใจ้
ๅใ้ฉๅใซใในใใใใฆใใใใใฎใใผใซใฏๅ
ฅๅใใใJSONใๆค่จผใใไธ่ฌ็ใชใจใฉใผใ็นๅฎใใฆไฟฎๆญฃใใใใใฎใใฃใผใใใใฏใๆไพใใพใใ",
+ "title": "JSON ๆค่จผใจใฏไฝใงใใ?"
+ },
+ "validJson": "โ
ๆๅนใชJSON"
+ }
+}
diff --git a/public/locales/ja/list.json b/public/locales/ja/list.json
new file mode 100644
index 0000000..2858790
--- /dev/null
+++ b/public/locales/ja/list.json
@@ -0,0 +1,208 @@
+{
+ "duplicate": {
+ "concatenate": "้ฃ็ต",
+ "concatenateDescription": "ใณใใผใ้ฃ็ตใใ๏ผใใงใใฏใๅคใใจใใขใคใใ ใ็นใไบคใใใใพใ๏ผ",
+ "copyDescription": "ใณใใผๆฐ๏ผ็ซฏๆฐใๅฏ๏ผ",
+ "description": "ใชในใใขใคใใ ใ่ค่ฃฝใใใใใฎใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใชในใใๅ
ฅๅใใ่ค่ฃฝๆกไปถใๆๅฎใใใ ใใงใใขใคใใ ใฎใณใใผใไฝๆใงใใพใใใใผใฟใฎๆกๅผตใใในใใ็นฐใ่ฟใใใฟใผใณใฎไฝๆใซๆ้ฉใงใใ",
+ "duplicationOptions": "่ค่ฃฝใชใใทใงใณ",
+ "examples": {
+ "fractional": {
+ "description": "ใใฎไพใงใฏใใชในใใๅฐๆฐ้จๆฐใง่ค่ฃฝใใๆนๆณใ็คบใใพใใ",
+ "title": "้จๅ็ใช่ค่ฃฝ"
+ },
+ "interweave": {
+ "description": "ใใฎไพใงใฏใ้
็ฎใ้ฃ็ตใใใฎใงใฏใชใ็นใไบคใใๆนๆณใ็คบใใพใใ",
+ "title": "็นใไบคใใใขใคใใ "
+ },
+ "reverse": {
+ "description": "ใใฎไพใงใฏใใชในใใ้ใฎ้ ๅบใง่ค่ฃฝใใๆนๆณใ็คบใใพใใ",
+ "title": "้่ค่ฃฝ"
+ },
+ "simple": {
+ "description": "ใใฎไพใงใฏใๅ่ชใฎใชในใใ่ค่ฃฝใใๆนๆณใ็คบใใพใใ",
+ "title": "ๅ็ดใช่ค่ฃฝ"
+ }
+ },
+ "inputTitle": "ๅ
ฅๅใชในใ",
+ "joinSeparatorDescription": "้่คใใใชในใใ็ตๅใใใใใฎๅบๅใๆๅญ",
+ "resultTitle": "้่คใชในใ",
+ "reverse": "้่กใใ",
+ "reverseDescription": "้่คใใใขใคใใ ใๅ
ใซๆปใ",
+ "shortDescription": "ๆๅฎใใๆกไปถใงใชในใ้
็ฎใ่ค่ฃฝใใ",
+ "splitByRegex": "ๆญฃ่ฆ่กจ็พใงๅๅฒ",
+ "splitBySymbol": "ใทใณใใซใงๅๅฒ",
+ "splitOptions": "ๅๅฒใชใใทใงใณ",
+ "splitSeparatorDescription": "ใชในใใๅๅฒใใใใใฎๅบๅใๆๅญ",
+ "title": "้่ค",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใจใใชในใๅ
ใฎ้
็ฎใ่ค่ฃฝใงใใพใใ่ค่ฃฝใใๆฐ๏ผๅฐๆฐ็นไปฅไธใๅซใ๏ผใๆๅฎใใใใ้
็ฎใ้ฃ็ตใใใ็นใไบคใใใใๅถๅพกใใใใ่ค่ฃฝใใ้
็ฎใๅ่ปขใใใใใใใใจใๅฏ่ฝใงใใ็นฐใ่ฟใใใฟใผใณใฎไฝๆใใในใใใผใฟใฎ็ๆใใใใใฏไบๆธฌๅฏ่ฝใชๅ
ๅฎนใฎใชในใๆกๅผตใชใฉใซไพฟๅฉใงใใ",
+ "title": "ใชในใใฎ้่ค"
+ }
+ },
+ "findMostPopular": {
+ "description": "ใชในใๅ
ใงๆใไบบๆฐใฎใใใขใคใใ ใ่ฆใคใใใใใฎใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใชในใใๅ
ฅๅใใใ ใใงใๆใ้ ป็นใซ่กจ็คบใใใใขใคใใ ใ็ฌๆใซ่กจ็คบใใพใใใใผใฟๅๆใใใฌใณใใฎ็นๅฎใๅ
ฑ้่ฆ็ด ใฎ็บ่ฆใซๆ้ฉใงใใ",
+ "shortDescription": "ๆใ้ ป็นใซ็บ็ใใใขใคใใ ใ่ฆใคใใ",
+ "title": "ๆใไบบๆฐใฎใใใใฎใๆขใ"
+ },
+ "findUnique": {
+ "caseSensitiveItems": "ๅคงๆๅญใจๅฐๆๅญใๅบๅฅใใ้
็ฎ",
+ "caseSensitiveItemsDescription": "ๅคงๆๅญใจๅฐๆๅญใ็ฐใชใ้
็ฎใใชในใๅ
ใฎไธๆใฎ่ฆ็ด ใจใใฆๅบๅใใพใใ",
+ "delimiterDescription": "ๅบๅใ่จๅทใพใใฏๆญฃ่ฆ่กจ็พใ่จญๅฎใใพใใ",
+ "description": "ใชในใๅ
ใฎไธๆใฎ้
็ฎใ่ฆใคใใใใใฎใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใชในใใๅ
ฅๅใใใจใ้่คใ้คใใใในใฆใฎไธๆใฎๅคใ็ฌๆใซๅๅพใใใพใใใใผใฟใฎใฏใชใผใใณใฐใ้่ค้คๅปใใพใใฏ็ฐใชใ่ฆ็ด ใฎๆค็ดขใซๆ้ฉใงใใ",
+ "findAbsolutelyUniqueItems": "็ตถๅฏพใซใฆใใผใฏใชใขใคใใ ใ่ฆใคใใ",
+ "findAbsolutelyUniqueItemsDescription": "ใชในใใฎ้
็ฎใฎใใกใๅไธใฎใณใใผๅ
ใซๅญๅจใใใใฎใ ใใ่กจ็คบใใพใใ",
+ "inputListDelimiter": "ๅ
ฅๅใชในใๅบๅใๆๅญ",
+ "inputTitle": "ๅ
ฅๅใชในใ",
+ "outputListDelimiter": "ๅบๅใชในใๅบๅใๆๅญ",
+ "resultTitle": "ใฆใใผใฏใชใขใคใใ ",
+ "shortDescription": "ใชในใๅ
ใฎใฆใใผใฏใชใขใคใใ ใ่ฆใคใใ",
+ "skipEmptyItems": "็ฉบใฎ้
็ฎใในใญใใ",
+ "skipEmptyItemsDescription": "ๅบๅใซ็ฉบใฎใชในใ้
็ฎใๅซใใชใใงใใ ใใใ",
+ "title": "ใฆใใผใฏใชใใฎใ่ฆใคใใ",
+ "trimItems": "ใชในใ้
็ฎใใใชใ ใใ",
+ "trimItemsDescription": "้
็ฎใๆฏ่ผใใๅใซๅ
้ ญใจๆซๅฐพใฎในใใผในใๅ้คใใพใใ",
+ "uniqueItemOptions": "ใฆใใผใฏใชใขใคใใ ใชใใทใงใณ"
+ },
+ "group": {
+ "deleteEmptyItems": "็ฉบใฎใขใคใใ ใๅ้คใใ",
+ "deleteEmptyItemsDescription": "็ฉบใฎ้
็ฎใฏ็ก่ฆใใใฐใซใผใใซๅซใใพใใใ",
+ "description": "ใชในใ้
็ฎใใฐใซใผใๅใใใใใฎใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใชในใใๅ
ฅๅใใใฐใซใผใๅใฎๆกไปถใๆๅฎใใใ ใใงใ้
็ฎใ่ซ็็ใชใฐใซใผใใซๆด็ใงใใพใใใใผใฟใฎๅ้กใๆ
ๅ ฑใฎๆด็ใๆง้ ๅใใใใชในใใฎไฝๆใซๆ้ฉใงใใใซในใฟใ ใปใใฌใผใฟใผใจๆงใ
ใชใฐใซใผใๅใชใใทใงใณใใตใใผใใใฆใใพใใ",
+ "emptyItemsAndPadding": "็ฉบใฎ้
็ฎใจใใใฃใณใฐ",
+ "groupNumberDescription": "ใฐใซใผใๅ
ใฎใขใคใใ ๆฐ",
+ "groupSeparatorDescription": "ใฐใซใผใๅบๅใๆๅญ",
+ "groupSizeAndSeparators": "ใฐใซใผใใตใคใบใจๅบๅใ",
+ "inputItemSeparator": "ๅ
ฅๅ้
็ฎใปใใฌใผใฟใผ",
+ "inputTitle": "ๅ
ฅๅใชในใ",
+ "itemSeparatorDescription": "้
็ฎๅบๅใๆๅญ",
+ "leftWrapDescription": "ใฐใซใผใใฎๅทฆๆใ่ฟใ่จๅทใ",
+ "padNonFullGroups": "้ใใซใฐใซใผใใฎใใใฃใณใฐ",
+ "padNonFullGroupsDescription": "ใใฃใฑใใงใชใใฐใซใผใใใซในใฟใ ้
็ฎใงๅใใพใ (ไปฅไธใซๅ
ฅๅ)ใ",
+ "paddingCharDescription": "ใใฎๆๅญใพใใฏ้
็ฎใไฝฟ็จใใฆใๅฎๅ
จใงใชใใฐใซใผใใๅใ่พผใฟใพใใ",
+ "resultTitle": "ใฐใซใผใๅใใใใขใคใใ ",
+ "rightWrapDescription": "ใฐใซใผใใฎๅณๆใ่ฟใ่จๅทใ",
+ "shortDescription": "ๅ
ฑ้ใฎใใญใใใฃใงใชในใ้
็ฎใใฐใซใผใๅใใ",
+ "splitOperators": {
+ "regex": {
+ "description": "ๅ
ฅๅใชในใ้
็ฎใๆญฃ่ฆ่กจ็พใงๅบๅใใพใใ",
+ "title": "ๆญฃ่ฆ่กจ็พใไฝฟ็จใใฆๅๅฒใใ"
+ },
+ "symbol": {
+ "description": "ๅ
ฅๅใชในใ้
็ฎใๆๅญใงๅบๅใใพใใ",
+ "title": "ๅๅฒใซใทใณใใซใไฝฟ็จใใ"
+ }
+ },
+ "splitSeparatorDescription": "ๅบๅใ่จๅทใพใใฏๆญฃ่ฆ่กจ็พใ่จญๅฎใใพใใ",
+ "title": "ใฐใซใผใ"
+ },
+ "reverse": {
+ "description": "ใใใฏใใในใฆใฎใชในใ้
็ฎใ้้ ใซ่กจ็คบใใใ้ๅธธใซใทใณใใซใชใใฉใฆใถใใผในใฎใขใใชใฑใผใทใงใณใงใใๅ
ฅๅ้
็ฎใฏไปปๆใฎ่จๅทใงๅบๅใใใจใใงใใ้้ ใซ่กจ็คบใใใชในใ้
็ฎใฎๅบๅใๆๅญใๅคๆดใใใใจใใงใใพใใ",
+ "inputTitle": "ๅ
ฅๅใชในใ",
+ "itemSeparator": "ใขใคใใ ใปใใฌใผใฟใผ",
+ "itemSeparatorDescription": "ๅบๅใ่จๅทใพใใฏๆญฃ่ฆ่กจ็พใ่จญๅฎใใพใใ",
+ "outputListOptions": "ๅบๅใชในใใชใใทใงใณ",
+ "outputSeparatorDescription": "ๅบๅใชในใ้
็ฎใฎใปใใฌใผใฟใผใ",
+ "resultTitle": "้ใชในใ",
+ "shortDescription": "ใชในใใ็ด ๆฉใ้้ ใซใใ",
+ "splitOperators": {
+ "regex": {
+ "description": "ๅ
ฅๅใชในใ้
็ฎใๆญฃ่ฆ่กจ็พใงๅบๅใใพใใ",
+ "title": "ๆญฃ่ฆ่กจ็พใไฝฟ็จใใฆๅๅฒใใ"
+ },
+ "symbol": {
+ "description": "ๅ
ฅๅใชในใ้
็ฎใๆๅญใงๅบๅใใพใใ",
+ "title": "ๅๅฒใซใทใณใใซใไฝฟ็จใใ"
+ }
+ },
+ "splitterMode": "ในใใชใใฟใผใขใผใ",
+ "title": "้่กใใ",
+ "toolInfo": {
+ "description": "ใใฎใฆใผใใฃใชใใฃใไฝฟใใฐใใชในใๅ
ใฎ้
็ฎใฎ้ ๅบใ้ใซใใใใจใใงใใพใใใใฎใฆใผใใฃใชใใฃใฏใพใๅ
ฅๅใชในใใๅใ
ใฎ้
็ฎใซๅๅฒใใๆๅพใฎ้
็ฎใใๆๅใฎ้
็ฎใพใงๅๅพฉๅฆ็ใ่กใใๅๅพฉๅฆ็ไธญใซๅ้
็ฎใๅบๅใซๅบๅใใพใใๅ
ฅๅใชในใใซใฏใๆฐๅญใๆๅญๅใๅ่ชใๆ็ซ ใชใฉใใใญในใใใผใฟใจใใฆ่กจ็พใงใใใใใใใใฎใๅซใใใใจใใงใใพใใๅ
ฅๅ้
็ฎใฎๅบๅใๆๅญใซใฏๆญฃ่ฆ่กจ็พใไฝฟ็จใงใใพใใไพใใฐใๆญฃ่ฆ่กจ็พ /[;,]/ ใไฝฟ็จใใใจใใซใณใๅบๅใใพใใฏใปใใณใญใณๅบๅใใฎ้
็ฎใไฝฟ็จใงใใพใใๅ
ฅๅใชในใใจๅบๅใชในใใฎ้
็ฎใฎๅบๅใๆๅญใฏใใชใใทใงใณใงใซในใฟใใคใบใงใใพใใใใใฉใซใใงใฏใๅ
ฅๅใชในใใจๅบๅใชในใใฎไธกๆนใใซใณใๅบๅใใงใใใพใใซใชในใใฎ็ด ๆดใใใ๏ผ",
+ "title": "ใชในใใชใใผใตใผใจใฏไฝใงใใ?"
+ }
+ },
+ "rotate": {
+ "description": "ใชในใ้
็ฎใๅ่ปขใใใใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใชในใใๅ
ฅๅใใๅ่ปข้ใๆๅฎใใใจใๆๅฎใใๆฐใ ใ้
็ฎใ็งปๅใงใใพใใใใผใฟๆไฝใๅพช็ฐใทใใใใชในใใฎไธฆในๆฟใใซๆ้ฉใงใใ",
+ "shortDescription": "ใชในใ้
็ฎใๆๅฎใใใไฝ็ฝฎใงๅ่ปขใใ",
+ "title": "ๅ่ปข"
+ },
+ "shuffle": {
+ "delimiterDescription": "ๅบๅใ่จๅทใพใใฏๆญฃ่ฆ่กจ็พใ่จญๅฎใใพใใ",
+ "description": "ใชในใ้
็ฎใใทใฃใใใซใใใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใชในใใๅ
ฅๅใใใจใ้
็ฎใใฉใณใใ ใช้ ๅบใงไธฆใใ ใฉใณใใ ใใผใธใงใณใ็ฌๆใซไฝๆใใใพใใใใฉใจใใฃ่ฑใใชใชในใใฎไฝๆใใฉใณใใ ๆงใฎใในใใ้ ๅบไปใใใใใใผใฟใฎๆททๅใชใฉใซๆ้ฉใงใใ",
+ "inputListSeparator": "ๅ
ฅๅใชในใใปใใฌใผใฟใผ",
+ "inputTitle": "ๅ
ฅๅใชในใ",
+ "joinSeparatorDescription": "ใฉใณใใ ๅใใใใชในใใงใฏใใฎๅบๅใๆๅญใไฝฟ็จใใพใใ",
+ "outputLengthDescription": "ใใใ ใใฎๆฐใฎใฉใณใใ ใขใคใใ ใๅบๅใใ",
+ "resultTitle": "ใทใฃใใใซใใใใชในใ",
+ "shortDescription": "ใชในใ้
็ฎใฎ้ ๅบใใฉใณใใ ใซใใ",
+ "shuffledListLength": "ใทใฃใใใซใชในใใฎ้ทใ",
+ "shuffledListSeparator": "ใทใฃใใใซใชในใใปใใฌใผใฟใผ",
+ "title": "ใทใฃใใใซ"
+ },
+ "sort": {
+ "caseSensitive": "ๅคงๆๅญใจๅฐๆๅญใๅบๅฅใใไธฆในๆฟใ",
+ "caseSensitiveDescription": "ๅคงๆๅญใจๅฐๆๅญใๅฅใ
ใซไธฆในๆฟใใพใใๆ้ ใชในใใงใฏใๅคงๆๅญใๅฐๆๅญใใใๅใซ่กจ็คบใใใพใใ๏ผใขใซใใกใใใ้ ใฎไธฆในๆฟใใขใผใใงใฎใฟๆฉ่ฝใใพใใ๏ผ",
+ "description": "ใชในใ้
็ฎใไธฆในๆฟใใใใใฎใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใชในใใๅ
ฅๅใใไธฆในๆฟใๆกไปถใๆๅฎใใใใจใงใ้
็ฎใๆ้ ใพใใฏ้้ ใซไธฆในๆฟใใใใจใใงใใพใใใใผใฟใฎๆด็ใใใญในใๅฆ็ใ้ ๅบไปใใชในใใฎไฝๆใซๆ้ฉใงใใ",
+ "inputItemSeparator": "ๅ
ฅๅ้
็ฎใปใใฌใผใฟใผ",
+ "inputTitle": "ๅ
ฅๅใชในใ",
+ "joinSeparatorDescription": "ใใฎ่จๅทใฏใใฝใผใใใใใชในใๅ
ใฎ้
็ฎ้ใฎ็ตๅๅญใจใใฆไฝฟ็จใใพใใ",
+ "orderDescription": "ไธฆในๆฟใ้ ๅบใ้ธๆใใพใใ",
+ "orderOptions": {
+ "decreasing": "้้ ",
+ "increasing": "ๆ้ "
+ },
+ "removeDuplicates": "้่คใๅ้คใใ",
+ "removeDuplicatesDescription": "้่คใใใชในใ้
็ฎใๅ้คใใพใใ",
+ "resultTitle": "ใฝใผใใใใใชในใ",
+ "shortDescription": "ใชในใ้
็ฎใๆๅฎใใใ้ ๅบใงไธฆในๆฟใใ",
+ "sortMethod": "ใฝใผใๆนๆณ",
+ "sortMethodDescription": "ไธฆในๆฟใๆนๆณใ้ธๆใใพใใ",
+ "sortOptions": {
+ "alphabetic": "ใขใซใใกใใใ้ ใซไธฆในๆฟใ",
+ "length": "้ทใใงไธฆในๆฟใ",
+ "numeric": "ๆฐๅค้ ใซไธฆในๆฟใใ"
+ },
+ "sortedItemProperties": "ไธฆในๆฟใใใใใขใคใใ ใฎใใญใใใฃ",
+ "splitOperators": {
+ "regex": {
+ "description": "ๅ
ฅๅใชในใ้
็ฎใๆญฃ่ฆ่กจ็พใงๅบๅใใพใใ",
+ "title": "ๆญฃ่ฆ่กจ็พใไฝฟ็จใใฆๅๅฒใใ"
+ },
+ "symbol": {
+ "description": "ๅ
ฅๅใชในใ้
็ฎใๆๅญใงๅบๅใใพใใ",
+ "title": "ๅๅฒใซใทใณใใซใไฝฟ็จใใ"
+ }
+ },
+ "splitSeparatorDescription": "ๅบๅใ่จๅทใพใใฏๆญฃ่ฆ่กจ็พใ่จญๅฎใใพใใ",
+ "title": "้ธๅฅ"
+ },
+ "truncate": {
+ "description": "ใชในใใๅใๆจใฆใใใใฎใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใชในใใๅ
ฅๅใใไฟๆใใใขใคใใ ใฎๆๅคงๆฐใๆๅฎใใพใใใใผใฟๅฆ็ใใชในใ็ฎก็ใใณใณใใณใใฎ้ทใๅถ้ใชใฉใซๆ้ฉใงใใ",
+ "shortDescription": "ใชในใใๆๅฎใใใ้
็ฎๆฐใซๅใๆจใฆใ",
+ "title": "ๅใๆจใฆ"
+ },
+ "unwrap": {
+ "description": "ใชในใ้
็ฎใๅฑ้ใใใใใฎใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใๅฑ้ใใใใชในใใๅ
ฅๅใใๅฑ้ๆกไปถใๆๅฎใใใใจใงใๆด็ใใใ้
็ฎใใใฉใใๅใงใใพใใใใผใฟๅฆ็ใใใญในใๆไฝใๆง้ ๅใชในใใใใฎใณใณใใณใๆฝๅบใซๆ้ฉใงใใ",
+ "shortDescription": "ๆง้ ๅใใใๅฝขๅผใใใชในใ้
็ฎใใขใณใฉใใใใ",
+ "title": "ใฉใใใ่งฃ้ค"
+ },
+ "wrap": {
+ "description": "ๅใชในใ้
็ฎใฎๅๅพใซใใญในใใ่ฟฝๅ ใใพใใ",
+ "inputTitle": "ๅ
ฅๅใชในใ",
+ "joinSeparatorDescription": "ใฉใใใใใใชในใใ็ตๅใใใใใฎใปใใฌใผใฟใผ",
+ "leftTextDescription": "ๅ้
็ฎใฎๅใซ่ฟฝๅ ใใใใญในใ",
+ "removeEmptyItems": "็ฉบใฎใขใคใใ ใๅ้คใใ",
+ "resultTitle": "ใฉใใใใใใชในใ",
+ "rightTextDescription": "ๅ้
็ฎใฎๅพใซ่ฟฝๅ ใใใใญในใ",
+ "shortDescription": "ๆๅฎใใๆกไปถใงใชในใ้
็ฎใๅฒใ",
+ "splitByRegex": "ๆญฃ่ฆ่กจ็พใงๅๅฒ",
+ "splitBySymbol": "ใทใณใใซใงๅๅฒ",
+ "splitOptions": "ๅๅฒใชใใทใงใณ",
+ "splitSeparatorDescription": "ใชในใใๅๅฒใใใใใฎๅบๅใๆๅญ",
+ "title": "ๅ
ใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใจใใชในใๅ
ใฎๅ้
็ฎใฎๅๅพใซใใญในใใ่ฟฝๅ ใงใใพใใๅทฆๅณใซ็ฐใชใใใญในใใๆๅฎใใใใใชในใใฎๅฆ็ๆนๆณใๅถๅพกใใใใงใใพใใใชในใ้
็ฎใซๅผ็จ็ฌฆใๆฌๅผงใใใฎไปใฎๆธๅผใ่ฟฝๅ ใใใใใใพใใพใชๅฝขๅผใซๅใใใฆใใผใฟใๆบๅใใใใๆง้ ๅใใญในใใไฝๆใใใใใใฎใซๅฝน็ซใกใพใใ",
+ "title": "ใชในใใฎๆใ่ฟใ"
+ },
+ "wrapOptions": "ใฉใใใชใใทใงใณ"
+ }
+}
diff --git a/public/locales/ja/number.json b/public/locales/ja/number.json
new file mode 100644
index 0000000..7e7b1c2
--- /dev/null
+++ b/public/locales/ja/number.json
@@ -0,0 +1,89 @@
+{
+ "arithmeticSequence": {
+ "commonDifferenceDescription": "็จ่ช้ใฎๅ
ฑ้ๅทฎ็ฐ๏ผd๏ผ",
+ "description": "ใซในใฟใใคใบๅฏ่ฝใชใใฉใกใผใฟใไฝฟ็จใใฆ็ฎ่กใทใผใฑใณในใ็ๆใใพใใ",
+ "firstTermDescription": "ๆฐๅใฎๆๅใฎ้
(aโ)",
+ "numberOfTermsDescription": "็ๆใใ้
ใฎๆฐ (n)",
+ "outputFormat": "ๅบๅๅฝขๅผ",
+ "resultTitle": "็ๆใใใใทใผใฑใณใน",
+ "separatorDescription": "็จ่ช้ใฎๅบๅใๆๅญ",
+ "sequenceParameters": "ใทใผใฑใณในใใฉใกใผใฟ",
+ "shortDescription": "็ญๅทฎๆฐๅใ็ๆใใ",
+ "title": "็ญๅทฎๆฐๅ",
+ "toolInfo": {
+ "description": "็ญๅทฎๆฐๅใจใฏใ้ฃ็ถใใๅ้
ใฎๅทฎใไธๅฎใงใใๆฐๅใงใใใใฎไธๅฎๅทฎใฏๅ
ฌๅทฎใจๅผใฐใใพใใๆๅใฎ้
(aโ) ใจๅ
ฌๅทฎ (d) ใไธใใใใใฐใๅ้
ใฏๅใฎ้
ใซๅ
ฌๅทฎใๅ ใใใใจใงๆฑใใใใพใใ",
+ "title": "็ญๅทฎๆฐๅใจใฏไฝใงใใ?"
+ }
+ },
+ "generate": {
+ "arithmeticSequenceOption": "็ญๅทฎๆฐๅใชใใทใงใณ",
+ "description": "ใซในใฟใใคใบๅฏ่ฝใชใใฉใกใผใฟใไฝฟ็จใใฆๆฐๅคใฎใทใผใฑใณในใ็ๆใใพใใ",
+ "numberOfElementsDescription": "ใทใผใฑใณในๅ
ใฎ่ฆ็ด ใฎๆฐใ",
+ "resultTitle": "็ๆใใใ็ชๅท",
+ "separator": "ใปใใฌใผใฟใผ",
+ "separatorDescription": "็ญๅทฎๆฐๅๅ
ใฎ่ฆ็ด ใใใฎๆๅญใงๅบๅใใพใใ",
+ "shortDescription": "ๆๅฎใใใ็ฏๅฒๅ
ใงไนฑๆฐใ็ๆใใ",
+ "startSequenceDescription": "ใใฎ็ชๅทใใใทใผใฑใณในใ้ๅงใใพใใ",
+ "stepDescription": "ๅ่ฆ็ด ใใใฎ้ใ ใๅขๅ ใใพใ",
+ "title": "็ๆใใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟ็จใใใจใใซในใฟใใคใบๅฏ่ฝใชใใฉใกใผใฟใไฝฟ็จใใฆๆฐๅคๅใ็ๆใงใใพใใ้ๅงๅคใในใใใใตใคใบใ่ฆ็ด ๆฐใๆๅฎใงใใพใใ",
+ "title": "ๆฐๅญใ็ๆใใ"
+ }
+ },
+ "ohmsLaw": {
+ "description": "้ปๅงใ้ปๆตใๆตๆใ่จ็ฎใใพใ",
+ "longDescription": "ใใฎ่จ็ฎๆฉใฏใใชใผใ ใฎๆณๅ๏ผV = I ร R๏ผใ็จใใฆใไปใฎ2ใคใฎ้ปๆฐใใฉใกใผใฟใๆข็ฅใฎๅ ดๅใ3ใคใฎ้ปๆฐใใฉใกใผใฟใฎใใใใใๆฑบๅฎใใพใใใชใผใ ใฎๆณๅใฏใ้ปๅง๏ผV๏ผใ้ปๆต๏ผI๏ผใๆตๆ๏ผR๏ผใฎ้ขไฟใ่จ่ฟฐใใ้ปๆฐๅทฅๅญฆใฎๅบๆฌๅ็ใงใใใใฎใใผใซใฏใ้ปๅญๅทฅๅญฆๆๅฅฝๅฎถใ้ปๆฐๆ่ก่
ใใใใฆๅ่ทฏ่จญ่จใซๅใ็ตใๅญฆ็ใซใจใฃใฆใ้ปๆฐ่จญ่จใซใใใๆช็ฅใฎๅคใ็ด ๆฉใ่งฃใใใใซไธๅฏๆฌ ใงใใ",
+ "shortDescription": "ใชใผใ ใฎๆณๅใไฝฟใฃใฆ้ปๆฐๅ่ทฏใฎ้ปๅงใ้ปๆตใๆตๆใ่จ็ฎใใ",
+ "title": "ใชใผใ ใฎๆณๅ"
+ },
+ "slackline": {
+ "description": "ในใฉใใฏใฉใคใณใฎๅผตๅใ่จ็ฎใใ",
+ "longDescription": "ใใฎ่จ็ฎๆฉใฏใญใผใใฎไธญๅคฎใซ่ท้ใใใใใใจใๆณๅฎใใฆใใพใ",
+ "shortDescription": "ในใฉใใฏใฉใคใณใ็ฉๅนฒใใญใผใใฎใใใใใฎๅผตๅใ่จ็ฎใใพใใใใใใ ใใๅฎๅ
จใฎใใใซใใใซ้ ผใใชใใงใใ ใใใ",
+ "title": "ในใฉใใฏใฉใคใณใฎๅผตๅ"
+ },
+ "sphereArea": {
+ "description": "็ใฎ้ข็ฉ",
+ "longDescription": "ใใฎ่จ็ฎๆฉใฏใA = 4ฯrยฒใจใใๅ
ฌๅผใ็จใใฆ็ใฎ่กจ้ข็ฉใ่จ็ฎใใพใใๅๅพใๅ
ฅๅใใฆ่กจ้ข็ฉใๆฑใใใใจใใ่กจ้ข็ฉใๅ
ฅๅใใฆๅฟ
่ฆใชๅๅพใ่จ็ฎใใใใจใใงใใพใใใใฎใใผใซใฏใๅนพไฝๅญฆใๅญฆใถๅญฆ็ใ็ไฝใๆฑใใจใณใธใใขใใใใฆ็้ขใซ้ขใใ่จ็ฎใ่กใๅฟ
่ฆใใใใในใฆใฎไบบใซใจใฃใฆไพฟๅฉใงใใ",
+ "shortDescription": "็ใฎๅๅพใซๅบใฅใใฆ็ใฎ่กจ้ข็ฉใ่จ็ฎใใ",
+ "title": "็ใฎ้ข็ฉ"
+ },
+ "sphereVolume": {
+ "description": "็ใฎไฝ็ฉ",
+ "longDescription": "ใใฎ่จ็ฎๆฉใฏใV = (4/3)ฯrยณใจใใๅ
ฌๅผใ็จใใฆ็ใฎไฝ็ฉใ่จ็ฎใใพใใๅๅพใพใใฏ็ดๅพใๅ
ฅๅใใฆไฝ็ฉใๆฑใใใใจใใไฝ็ฉใๅ
ฅๅใใฆๅฟ
่ฆใชๅๅพใๆฑใใใใจใใงใใพใใใใฎใใผใซใฏใ็ฉ็ๅญฆใๅทฅๅญฆใ่ฃฝ้ ๆฅญใชใฉใฎๅ้ใง็ไฝใๆฑใๅญฆ็ใใจใณใธใใขใๅฐ้ๅฎถใซใจใฃใฆ้ๅธธใซๅฝน็ซใกใพใใ",
+ "shortDescription": "ๅๅพใพใใฏ็ดๅพใไฝฟ็จใใฆ็ใฎไฝ็ฉใ่จ็ฎใใ",
+ "title": "็ใฎไฝ็ฉ"
+ },
+ "sum": {
+ "description": "ๆฐๅคใชในใใฎๅ่จใ่จ็ฎใใพใใๆฐๅคใใซใณใใพใใฏๆน่กใงๅบๅใฃใฆๅ
ฅๅใใใจใๅ่จใๆฑใใใใพใใ",
+ "extractionTypes": {
+ "delimiter": {
+ "description": "ใใใงๆฐๅคๅบๅใใใซในใฟใใคใบใใพใใ(ใใใฉใซใใงใฏๆน่กใงใใ)",
+ "title": "ๆฐๅคๅบๅใๆๅญ"
+ },
+ "smart": {
+ "description": "ๅ
ฅๅๅ
ใฎๆฐๅญใ่ชๅๆคๅบใใพใใ",
+ "title": "ในใใผใใตใ "
+ }
+ },
+ "inputTitle": "ๅ
ฅๅ",
+ "numberExtraction": "็ชๅทๆฝๅบ",
+ "printRunningSum": "็ดฏ่จใๅฐๅท",
+ "printRunningSumDescription": "่จ็ฎใใใๅ่จใๆฎต้็ใซ่กจ็คบใใพใใ",
+ "resultTitle": "ๅ่จ",
+ "runningSum": "็ดฏ่จ",
+ "shortDescription": "ๆฐๅญใฎๅ่จใ่จ็ฎใใ",
+ "title": "ๅ",
+ "toolInfo": {
+ "description": "ใใใฏใ่คๆฐใฎๆฐๅคใฎๅ่จใ่จ็ฎใใใใใฎใใฉใฆใถใใผในใฎใชใณใฉใคใณใฆใผใใฃใชใใฃใงใใๆฐๅคใฏใใซใณใใในใใผในใใพใใฏๆน่กใๅซใไปปๆใฎๆๅญใงๅบๅใฃใฆๅ
ฅๅใงใใพใใใพใใๅ่จใใใๆฐๅคใๅซใใใญในใใใผใฟใ่ฒผใไปใใใ ใใงใใฆใผใใฃใชใใฃใใใใใฎๆฐๅคใๆฝๅบใใๅ่จใ่จ็ฎใใพใใ",
+ "title": "ๆฐๅคๅ่จ่จ็ฎๆฉใจใฏไฝใงใใ?"
+ }
+ },
+ "voltageDropInWire": {
+ "description": "2ๅฐไฝใฑใผใใซใฎๅพๅพฉ้ปๅงใจ้ปๅๆๅคฑใ่จ็ฎใใพใ",
+ "longDescription": "ใใฎ่จ็ฎๆฉใฏใ2่ฏ้ปๆฐใฑใผใใซใซใใใ้ปๅง้ไธใจ้ปๅๆๅคฑใ่จ็ฎใใใฎใซๅฝน็ซใกใพใใใฑใผใใซใฎ้ทใใ้ป็ทใฒใผใธ๏ผๆญ้ข็ฉ๏ผใๆ่ณชใฎๆตๆ็ใ้ปๆตใฎๆตใใ่ๆ
ฎใใพใใใใฎใใผใซใฏใๅพๅพฉใฎ้ปๅง้ไธใใฑใผใใซใฎ็ทๆตๆใใใใฆ็ฑใจใใฆๆถ่ฒปใใใ้ปๅใ่จ็ฎใใพใใใใใฏใ้ปๆฐๆ่ก่
ใ้ปๆฐๆๅธซใใใใฆ่ถฃๅณใง้ปๆฐใทในใใ ใ่จญ่จใใ้ใซใ่ฒ ่ทใซใใใ้ปๅงใฌใใซใ่จฑๅฎน็ฏๅฒๅ
ใซ็ถญๆใใใใใใซใใ้ใซ็นใซๅฝน็ซใกใพใใ",
+ "shortDescription": "้ทใใๆ่ณชใ้ปๆตใซๅบใฅใใฆ้ปๆฐใฑใผใใซใฎ้ปๅง้ไธใจ้ปๅๆๅคฑใ่จ็ฎใใพใ",
+ "title": "ใฑใผใใซใฎๅพๅพฉ้ปๅง้ไธ"
+ }
+}
diff --git a/public/locales/ja/pdf.json b/public/locales/ja/pdf.json
new file mode 100644
index 0000000..3f0e3a6
--- /dev/null
+++ b/public/locales/ja/pdf.json
@@ -0,0 +1,113 @@
+{
+ "compressPdf": {
+ "compressedFileSize": "ๅง็ธฎใใกใคใซใตใคใบ",
+ "compressingPdf": "PDF ใๅง็ธฎใใฆใใพใ...",
+ "compressionLevel": "ๅง็ธฎใฌใใซ",
+ "compressionSettings": "ๅง็ธฎ่จญๅฎ",
+ "description": "Ghostscriptใไฝฟ็จใใฆๅ่ณชใ็ถญๆใใชใใPDFใใกใคใซใฎใตใคใบใ็ธฎๅฐใใ",
+ "errorCompressingPdf": "PDF ใฎๅง็ธฎใซๅคฑๆใใพใใ: {{error}}",
+ "errorReadingPdf": "PDFใใกใคใซใฎ่ชญใฟๅใใซๅคฑๆใใพใใใๆๅนใชPDFใงใใใใจใ็ขบ่ชใใฆใใ ใใใ",
+ "fileSize": "ๅ
ใฎใใกใคใซใตใคใบ",
+ "highCompression": "้ซๅง็ธฎ",
+ "highCompressionDescription": "ๅคๅฐใฎๅ่ณชไฝไธใไผดใใใกใคใซใตใคใบใๆๅคง้ใซๅๆธ",
+ "inputTitle": "ๅ
ฅๅPDF",
+ "lowCompression": "ไฝๅง็ธฎ",
+ "lowCompressionDescription": "ๅ่ณชใฎไฝไธใๆๅฐ้ใซๆใใชใใใใกใคใซใตใคใบใใใใใซๅๆธ",
+ "mediumCompression": "ไธญๅง็ธฎ",
+ "mediumCompressionDescription": "ใใกใคใซใตใคใบใจๅ่ณชใฎใใฉใณใน",
+ "pages": "ใใผใธๆฐ",
+ "resultTitle": "ๅง็ธฎPDF",
+ "shortDescription": "ใใฉใฆใถใงPDFใใกใคใซใๅฎๅ
จใซๅง็ธฎ",
+ "title": "PDFใๅง็ธฎ"
+ },
+ "editor": {
+ "description": "ๆณจ้ใใใฉใผใ ๅ
ฅๅใใใคใฉใคใใใจใฏในใใผใๆฉ่ฝใๅใใ้ซๅบฆใชPDFใจใใฃใฟใผใใใญในใๆฟๅ
ฅใๆ็ปใใใคใฉใคใใ็ฝฒๅใใใฉใผใ ๅ
ฅๅใชใฉใฎใใญไปๆงใฎใใผใซใไฝฟใฃใฆใใใฉใฆใถๅ
ใง็ดๆฅPDFใ็ทจ้ใงใใพใใ",
+ "shortDescription": "้ซๅบฆใชๆณจ้ใ็ฝฒๅใ็ทจ้ใใผใซใงPDFใ็ทจ้",
+ "title": "PDFใจใใฃใฟใผ"
+ },
+ "merge": {
+ "inputTitle": "ๅ
ฅๅPDF",
+ "loadingText": "ใใผใธใฎๆฝๅบ",
+ "resultTitle": "็ตๅใใPDFใๅบๅใใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใฐใ่คๆฐใฎPDFใใกใคใซใ1ใคใฎๆๆธใซ็ตๅใใใใจใใงใใพใใ็ตๅใใใPDFใใกใคใซใใขใใใญใผใใใใ ใใงใๅ
ฅๅใใกใคใซใฎใในใฆใฎใใผใธใ1ใคใฎPDFๆๆธใซ็ตๅใใใพใใ",
+ "title": "Merge PDF ใใผใซใฎไฝฟใๆน"
+ }
+ },
+ "mergePdf": {
+ "description": "่คๆฐใฎ PDF ใใกใคใซใ 1 ใคใฎใใญใฅใกใณใใซ็ตๅใใพใใ",
+ "inputTitle": "ๅ
ฅๅPDF",
+ "mergingPdfs": "PDFใฎ็ตๅ",
+ "pdfOptions": "PDFใชใใทใงใณ",
+ "resultTitle": "็ตๅใใใPDF",
+ "shortDescription": "่คๆฐใฎPDFใใกใคใซใ1ใคใฎๆๆธใซ็ตๅใใ",
+ "sortByFileName": "ใใกใคใซๅใงไธฆในๆฟใ",
+ "sortByFileNameDescription": "PDFใใใกใคใซๅใฎใขใซใใกใใใ้ ใซไธฆในๆฟใใ",
+ "sortByUploadOrder": "ใขใใใญใผใ้ ใซไธฆในๆฟใ",
+ "sortByUploadOrderDescription": "PDFใใขใใใญใผใใใใ้ ๅบใงไฟๅญใใ",
+ "title": "PDFใ็ตๅ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใฐใ่คๆฐใฎPDFใใกใคใซใ1ใคใฎๆๆธใซ็ตๅใงใใพใใPDFใใกใคใซใฎไธฆใณ้ ใๆๅฎใใใจใใใผใซใๆๅฎใใ้ ๅบใง็ตๅใใพใใ",
+ "title": "PDFใใกใคใซใฎ็ตๅ"
+ }
+ },
+ "pdfToEpub": {
+ "description": "PDFๆๆธใEPUBใใกใคใซใซๅคๆใใฆใ้ปๅญๆธ็ฑใชใผใใผใจใฎไบๆๆงใ้ซใใพใใ', icon: 'material-symbols:import-contacts', components: lazy(() => import('./index')), keywords: ['pdf', 'epub', 'convert', 'ebook'], path: 'pdf-to-epub', i18n: { name: 'pdf:pdfToEpub.title', description: 'pdf:pdfToEpub.description",
+ "shortDescription": "PDFใใกใคใซใEPUBๅฝขๅผใซๅคๆใใ",
+ "title": "PDFใใEPUBใธ"
+ },
+ "pdfToPng": {
+ "description": "PDF ใใญใฅใกใณใใ PNG ใใใซใซๅคๆใใพใใ",
+ "longDescription": "PDFใใขใใใญใผใใใใจใใใฉใฆใถๅ
ใงๅใใผใธใ้ซ็ป่ณชใฎPNG็ปๅใซๅคๆใงใใพใใใใฎใใผใซใฏใใใธใฅใขใซใณใณใใณใใฎๆฝๅบใๅใ
ใฎใใผใธใฎๅ
ฑๆใซๆ้ฉใงใใใใผใฟใฏใขใใใญใผใใใใใใในใฆใญใผใซใซใงๅฎ่กใใใพใใ",
+ "shortDescription": "PDFใPNG็ปๅใซๅคๆใใ",
+ "title": "PDFใใPNGใธ"
+ },
+ "protectPdf": {
+ "description": "ใใฉใฆใถใงๅฎๅ
จใซPDFใใกใคใซใซใในใฏใผใไฟ่ญทใ่ฟฝๅ ใใพใ",
+ "shortDescription": "PDFใใกใคใซใใในใฏใผใใงๅฎๅ
จใซไฟ่ญทใใ",
+ "title": "PDFใไฟ่ญทใใ"
+ },
+ "rotatePdf": {
+ "allPagesWillBeRotated": "ๅ
จใฆ {{count}} ใใผใธใๅ่ปขใใพใ",
+ "angleOptions": {
+ "clockwise90": "90ยฐๆ่จๅใ",
+ "counterClockwise270": "270ยฐ๏ผๅๆ่จๅใ90ยฐ๏ผ",
+ "upsideDown180": "180ยฐ๏ผไธไธ้ใใพ๏ผ"
+ },
+ "applyToAllPages": "ใในใฆใฎใใผใธใซ้ฉ็จ",
+ "description": "PDF ใใญใฅใกใณใๅ
ใฎใใผใธใๅ่ปขใใพใใ",
+ "inputTitle": "ๅ
ฅๅPDF",
+ "longDescription": "PDFใใผใธใฎๅใใ90ๅบฆใ180ๅบฆใใพใใฏ270ๅบฆๅ่ปขใใฆๅคๆดใงใใพใใในใญใฃใณใในใไฟฎๆญฃใใใใๅฐๅท็จใฎPDFใๆบๅใใใใใ้ใซไพฟๅฉใงใใ",
+ "pageRangesDescription": "ใใผใธ็ชๅทใพใใฏ็ฏๅฒใใณใณใใงๅบๅใฃใฆๅ
ฅๅใใฆใใ ใใ๏ผไพ๏ผ1,3,5-7๏ผ",
+ "pageRangesPlaceholder": "ไพ๏ผ1.5-8",
+ "pagesWillBeRotated": "{{count}} ใใผใธ{{count !== 1 ? 's' : ''}} ๅ่ปขใใพใ",
+ "pdfPageCount": "PDFใซใฏ {{count}} ใใผใธ{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "ๅ่ปขใใPDF",
+ "rotatingPages": "ใใผใธใฎๅ่ปข",
+ "rotationAngle": "ๅ่ปข่งๅบฆ",
+ "rotationSettings": "ๅ่ปข่จญๅฎ",
+ "shortDescription": "PDFๆๆธใฎใใผใธใๅ่ปขใใ",
+ "title": "PDFใๅ่ปข",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใจใPDFๆๆธๅ
ใฎใใผใธใๅ่ปขใงใใพใใใในใฆใฎใใผใธใๅ่ปขใใใใจใใ็นๅฎใฎใใผใธใๆๅฎใใฆๅ่ปขใใใใใจใใงใใพใใๅ่ปข่งๅบฆใฏใๆ่จๅใ90ๅบฆใ180ๅบฆ๏ผไธไธๅ่ปข๏ผใใพใใฏๅๆ่จๅใ90ๅบฆ๏ผ270ๅบฆ๏ผใใ้ธๆใงใใพใใ็นๅฎใฎใใผใธใๅ่ปขใใใใซใฏใใใในใฆใฎใใผใธใซ้ฉ็จใใฎใใงใใฏใๅคใใใใผใธ็ชๅทใพใใฏใใผใธ็ฏๅฒใใซใณใใงๅบๅใฃใฆๅ
ฅๅใใพใ๏ผไพ๏ผ1,3,5-7๏ผใ",
+ "title": "PDFๅ่ปขใใผใซใฎไฝฟใๆน"
+ }
+ },
+ "splitPdf": {
+ "description": "PDF ใใญใฅใกใณใใใ็นๅฎใฎใใผใธใๆฝๅบใใพใใ",
+ "extractingPages": "ใใผใธใฎๆฝๅบ",
+ "inputTitle": "ๅ
ฅๅPDF",
+ "pageExtractionPreview": "{{count}} ใใผใธ{{count !== 1 ? 's' : ''}} ๆฝๅบใใใพใ",
+ "pageRangesDescription": "ใใผใธ็ชๅทใพใใฏ็ฏๅฒใใณใณใใงๅบๅใฃใฆๅ
ฅๅใใฆใใ ใใ๏ผไพ๏ผ1,3,5-7๏ผ",
+ "pageRangesPlaceholder": "ไพ๏ผ1.5-8",
+ "pageSelection": "ใใผใธ้ธๆ",
+ "pdfPageCount": "PDFใซใฏ {{count}} ใใผใธ{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "ๆฝๅบใใใPDF",
+ "shortDescription": "PDFใใกใคใซใใ็นๅฎใฎใใผใธใๆฝๅบใใ",
+ "title": "PDFใๅๅฒ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใจใPDFๆๆธใใ็นๅฎใฎใใผใธใๆฝๅบใงใใพใใๆฝๅบใใใใผใธใฏใๅใ
ใฎใใผใธใพใใฏใใผใธ็ฏๅฒใงๆๅฎใงใใพใใ",
+ "title": "PDFใๅๅฒ"
+ }
+ }
+}
diff --git a/public/locales/ja/string.json b/public/locales/ja/string.json
new file mode 100644
index 0000000..897f312
--- /dev/null
+++ b/public/locales/ja/string.json
@@ -0,0 +1,261 @@
+{
+ "base64": {
+ "decode": "Base64ใใณใผใ",
+ "description": "Base64 ใจใณใณใผใใฃใณใฐใไฝฟ็จใใฆใใญในใใใจใณใณใผใใพใใฏใใณใผใใใพใใ",
+ "encode": "Base64ใจใณใณใผใ",
+ "inputTitle": "ๅ
ฅๅใใผใฟ",
+ "optionsTitle": "Base64ใชใใทใงใณ",
+ "resultTitle": "็ตๆ",
+ "shortDescription": "Base64 ใไฝฟ็จใใฆใใผใฟใใจใณใณใผใใพใใฏใใณใผใใใพใใ",
+ "title": "Base64 ใจใณใณใผใ/ใใณใผใ",
+ "toolInfo": {
+ "description": "Base64ใฏใASCIIๆๅญๅๅฝขๅผใฎใใผใฟใๅบๆฐ64ใฎ่กจ็พใซๅคๆใใฆ่กจ็พใใใจใณใณใผใๆนๅผใงใใๆๅญๅใฎใจใณใณใผใใซใไฝฟ็จใงใใพใใใใใญในใใใผใฟใๆฑใใใใซ่จญ่จใใใใกใใฃใขใงไผ้ใใใใคใใชใใผใฟใฎใจใณใณใผใใซใใไฝฟ็จใใใพใใ",
+ "title": "Base64 ใจใฏไฝใงใใ?"
+ }
+ },
+ "censor": {
+ "description": "ใใญในใๅ
ใฎๅ่ชใๆค้ฒใใใใใฎใฆใผใใฃใชใใฃใงใใๅทฆๅดใฎๅ
ฅๅใใฉใผใ ใซใใญในใใๅ
ฅๅใใใชใใทใงใณใงไธ้ฉๅใชๅ่ชใใในใฆๆๅฎใใใจใๅบๅ้ ๅใซๆค้ฒใใใใใญในใใๅณๅบงใซ่กจ็คบใใใพใใ\", longDescription: 'ใใฎใชใณใฉใคใณใใผใซใไฝฟใใฐใใใใใใใญในใๅ
ใฎ็นๅฎใฎๅ่ชใๆค้ฒใงใใพใใไธ่ฆใชๅ่ช๏ผ็ฝตใ่จ่ใ็งๅฏใฎ่จ่ใชใฉ๏ผใฎใชในใใๆๅฎใใใจใใใญใฐใฉใ ใใใใใไปฃๆฟๅ่ชใซ็ฝฎใๆใใๅฎๅ
จใซ่ชญใใใใญในใใไฝๆใใพใใๅ่ชใฏใใชใใทใงใณใฎ่คๆฐ่กใใญในใใใฃใผใซใใซ1่กใซใคใ1ๅ่ชใใคๅ
ฅๅใใใใจใงๆๅฎใงใใพใใ', ใญใผใฏใผใ: ['text', 'censor', 'words', 'characters'], ใณใณใใผใใณใ: lazy(() => import('./index')), i18n: { name: 'string:censor.title', description: 'string:censor.description",
+ "shortDescription": "ไธ้ฉๅใชๅ่ชใใใใซใในใฏใใใใๅฅใฎๅ่ชใซ็ฝฎใๆใใพใใ",
+ "title": "ใใญในใๆค้ฒ"
+ },
+ "createPalindrome": {
+ "description": "ใใใใใใญในใใใๅๆใไฝๆใงใใใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใใญในใใๅ
ฅๅใใใจใๅๅพใฉใกใใใ่ชญใใงใๅใๅๆใซ็ฌๆใซๅคๆใใใพใใ่จ่้ใณใๅฏพ็งฐ็ใชใใญในใใใฟใผใณใฎไฝๆใ่จ่ช็ๅฅฝๅฅๅฟใฎๆขๆฑใชใฉใซๆ้ฉใงใใ",
+ "shortDescription": "ๅๅพใฉใกใใใ่ชญใใงใๅใใใญในใใไฝๆใใ",
+ "title": "ๅๆใไฝๆใใ"
+ },
+ "extractSubstring": {
+ "description": "ใใญในใใใ้จๅๆๅญๅใๆฝๅบใงใใใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใใญในใใๅ
ฅๅใใ้ๅงไฝ็ฝฎใจ็ตไบไฝ็ฝฎใๆๅฎใใใ ใใงใๅฟ
่ฆใช้จๅใๆฝๅบใงใใพใใใใผใฟๅฆ็ใใใญในใๅๆใใใใใฏๅคงใใชใใญในใใใญใใฏใใ็นๅฎใฎใณใณใใณใใๆฝๅบใใใฎใซๆ้ฉใงใใ",
+ "shortDescription": "ๆๅฎใใไฝ็ฝฎใฎ้ใฎใใญในใใฎไธ้จใๆฝๅบใใ",
+ "title": "้จๅๆๅญๅใฎๆฝๅบ"
+ },
+ "join": {
+ "blankLinesAndTrailingSpaces": "็ฉบ็ฝ่กใจๆซๅฐพใฎในใใผใน",
+ "deleteBlankDescription": "ใใญในใ ใทใณใใซใฎใชใ่กใๅ้คใใพใใ",
+ "deleteBlankTitle": "็ฉบ็ฝ่กใๅ้คใใ",
+ "deleteTrailingDescription": "่กๆซใฎในใใผในใจใฟใใๅ้คใใพใใ",
+ "deleteTrailingTitle": "ๆซๅฐพใฎในใใผในใๅ้ค",
+ "description": "ใซในใฟใใคใบๅฏ่ฝใชใปใใฌใผใฟใผใไฝฟ็จใใฆใใญในใ้จๅใ็ตๅใใพใใ",
+ "inputTitle": "ใใญในใใใผใน",
+ "joinCharacterDescription": "ใใญในใใฎๆญ็ใ้ฃ็ตใใ่จๅทใ(ใใใฉใซใใงใฏในใใผใน)",
+ "joinCharacterPlaceholder": "ใญใฃใฉใฏใฟใผใๅๅ ใใใ",
+ "resultTitle": "็ตๅใใญในใ",
+ "shortDescription": "ๆๅฎใใๅบๅใๆๅญใงใใญในใ่ฆ็ด ใ็ตๅใใ",
+ "textMergedOptions": "ใใญในใ็ตๅใชใใทใงใณ",
+ "title": "ใใญในใใ็ตๅ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใฐใใใญในใใฎไธ้จใ็ตๅใงใใพใใๆน่กใงๅบๅใใใใใญในใๅคใฎใชในใใๅใๅใใใใใใ็ตๅใใพใใ็ตๅๅพใฎใใญในใใฎๅ้จๅใฎ้ใซๆฟๅ
ฅใใๆๅญใ่จญๅฎใงใใพใใใพใใใในใฆใฎ็ฉบ่กใ็ก่ฆใใใในใฆใฎ่กๆซใฎในใใผในใจใฟใใๅ้คใใใใจใใงใใพใใTextabulous๏ผ",
+ "title": "ใใญในใใธใงใคใใผใจใฏไฝใงใใ?"
+ }
+ },
+ "palindrome": {
+ "description": "ใใญในใใๅๆใงใใใใฉใใใใใงใใฏใใใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใใญในใใๅๅพใฉใกใใใ่ชญใใงใๅใใใฉใใใ็ฌๆใซๆค่จผใใพใใๅ่ชใใบใซใ่จ่ชๅๆใๅฏพ็งฐ็ใชใใญในใใใฟใผใณใฎๆค่จผใซๆ้ฉใงใใๆงใ
ใชๅบๅใๆๅญใจ่คๆฐๅ่ชใฎๅๆๆคๅบใซๅฏพๅฟใใฆใใพใใ",
+ "shortDescription": "ใใญในใใๅๅพใงๅใ่ชญใฟๆนใใใฆใใใ็ขบ่ชใใ",
+ "title": "ๅๆ"
+ },
+ "passwordGenerator": {
+ "avoidAmbiguous": "ใใใพใใชๆๅญ๏ผiใIใlใ0ใO๏ผใฏ้ฟใใฆใใ ใใ",
+ "description": "้ทใใจๆๅญ็จฎใใซในใฟใใคใบๅฏ่ฝใชใๅฎๅ
จใชใฉใณใใ ใในใฏใผใใ็ๆใใพใใๅฐๆๅญใๅคงๆๅญใๆฐๅญใ็นๆฎๆๅญใใ้ธๆใงใใพใใ่ชญใฟใใใใๅไธใใใใใใใใใพใใชๆๅญใ้ฟใใใชใใทใงใณใ็จๆใใใฆใใพใใ",
+ "includeLowercase": "ๅฐๆๅญ๏ผa๏ฝz๏ผใๅซใใ",
+ "includeNumbers": "ๆฐๅญใๅซใใ๏ผ0๏ฝ9๏ผ",
+ "includeSymbols": "็นๆฎๆๅญใๅซใใ",
+ "includeUppercase": "ๅคงๆๅญ๏ผA๏ฝZ๏ผใๅซใใ",
+ "lengthDesc": "ใในใฏใผใใฎ้ทใ",
+ "lengthPlaceholder": "ไพ๏ผ12",
+ "optionsTitle": "ใในใฏใผใใชใใทใงใณ",
+ "resultTitle": "็ๆใใใใในใฏใผใ",
+ "shortDescription": "ใซในใฟใ ใชใใทใงใณใงๅฎๅ
จใชใฉใณใใ ใในใฏใผใใ็ๆใใ",
+ "title": "ใในใฏใผใใธใงใใฌใผใฟใผ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใฏใ้ธๆใใๆกไปถใซๅบใฅใใฆๅฎๅ
จใชใฉใณใใ ใในใฏใผใใ็ๆใใพใใ้ทใใใซในใฟใใคใบใใใใๆงใ
ใชๆๅญ็จฎใๅซใใใ้คๅคใใใใ่ชญใฟใใใใๅไธใใใใใใซๆๆงใชๆๅญใ้ฟใใใใใใใจใใงใใพใใใขใซใฆใณใใใขใใชใฑใผใทใงใณใใใฎไปใใใใใปใญใฅใชใใฃใใผใบใซๅฏพๅฟใใๅผทๅใชใในใฏใผใใฎไฝๆใซๆ้ฉใงใใ",
+ "title": "ใในใฏใผใใธใงใใฌใผใฟใซใคใใฆ"
+ }
+ },
+ "quote": {
+ "allowDoubleQuotation": "ไบ้ๅผ็จ็ฌฆใ่จฑๅฏใใ",
+ "description": "ใซในใฟใใคใบๅฏ่ฝใชใชใใทใงใณใไฝฟ็จใใฆใใญในใใๅผ็จ็ฌฆใงๅฒใฟใพใใ",
+ "inputTitle": "ๅ
ฅๅใใญในใ",
+ "leftQuoteDescription": "ๅทฆๅผ็จๆๅญ",
+ "processAsMultiLine": "่คๆฐ่กใใญในใใจใใฆๅฆ็",
+ "quoteEmptyLines": "็ฉบ่กใๅผ็จใใ",
+ "quoteOptions": "ๅผ็จใชใใทใงใณ",
+ "resultTitle": "ๅผ็จใใญในใ",
+ "rightQuoteDescription": "ๅณๅผ็จ็ฌฆๆๅญ",
+ "shortDescription": "ใใพใใพใชในใฟใคใซใงใใญในใใๅผ็จ็ฌฆใงๅฒใ",
+ "title": "ใใญในใๅผ็จ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใจใใใญในใใๅผ็จ็ฌฆใงๅฒใใใจใใงใใพใใๆงใ
ใชๅผ็จ็ฌฆๆๅญใ้ธๆใใใใ่คๆฐ่กใใญในใใๆฑใฃใใใ็ฉบ่กใฎๅฆ็ๆนๆณใๅถๅพกใใใใงใใพใใใใญใฐใฉใใณใฐ็จใฎใใญในใใฎไฝๆใใใผใฟใฎๆธๅผ่จญๅฎใในใฟใคใชใใทใฅใชใใญในใใฎไฝๆใซๅฝน็ซใกใพใใ",
+ "title": "ใใญในใๅผ็จ"
+ }
+ },
+ "randomizeCase": {
+ "description": "ใใญในใใฎๅคงๆๅญใจๅฐๆๅญใใฉใณใใ ๅใใใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใใญในใใๅ
ฅๅใใใจใๅคงๆๅญใจๅฐๆๅญใใฉใณใใ ใซใฉใณใใ ใซๅคๆใใใพใใใฆใใผใฏใชใใญในใใจใใงใฏใใฎไฝๆใๅคงๆๅญใจๅฐๆๅญใฎๅบๅฅใฎใในใใๅคๆงใชใใญในใใใฟใผใณใฎ็ๆใซๆ้ฉใงใใ",
+ "shortDescription": "ใใญในใๅ
ใฎๅคงๆๅญใจๅฐๆๅญใใฉใณใใ ใซใใ",
+ "title": "ใฑใผในใใฉใณใใ ๅ"
+ },
+ "removeDuplicateLines": {
+ "description": "ๅทฆๅดใฎๅ
ฅๅใใฉใผใ ใซใใญในใใ่ชญใฟ่พผใใจใๅบๅใจใชใขใซ้่ค่กใฎใชใใใญในใใ็ฌๆใซ่กจ็คบใใใพใใๅผทๅใ็กๆใใใใฆ้ซ้ใใใญในใ่กใฎ่ชญใฟ่พผใฟ โ ้่ค่กใฎใชใใใญในใ่กใๅๅพ",
+ "shortDescription": "ใใญในใใใ้่ค่กใใในใฆ็ด ๆฉใๅ้คใใพใ",
+ "title": "้่ค่กใๅ้คใใ"
+ },
+ "repeat": {
+ "delimiterDescription": "ๅบๅใณใใผใฎๅบๅใๆๅญใ",
+ "delimiterPlaceholder": "ใใชใใฟ",
+ "description": "ใซในใฟใใคใบๅฏ่ฝใชใปใใฌใผใฟใผใไฝฟ็จใใฆใใญในใใ่คๆฐๅ็นฐใ่ฟใใพใใ",
+ "inputTitle": "ๅ
ฅๅใใญในใ",
+ "numberPlaceholder": "็ชๅท",
+ "repeatAmountDescription": "็นฐใ่ฟใๅๆฐใ",
+ "repetitionsDelimiter": "็นฐใ่ฟใๅบๅใๆๅญ",
+ "resultTitle": "็นฐใ่ฟใใใญในใ",
+ "shortDescription": "ใใญในใใ่คๆฐๅ็นฐใ่ฟใ",
+ "textRepetitions": "ใใญในใใฎ็นฐใ่ฟใ",
+ "title": "ใใญในใใฎ็นฐใ่ฟใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟ็จใใใจใใชใใทใงใณใฎๅบๅใๆๅญใไฝฟ็จใใฆใ็นๅฎใฎใใญในใใ่คๆฐๅ็นฐใ่ฟใใใจใใงใใพใใ",
+ "title": "ใใญในใใฎ็นฐใ่ฟใ"
+ }
+ },
+ "reverse": {
+ "description": "ไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใใญในใๅ่ปขใฆใผใใฃใชใใฃใไปปๆใฎใใญในใใๅ
ฅๅใใใจใๆๅญใใจใซ็ฌๆใซๅ่ปขใใพใใ้กๆๅญใฎไฝๆใๅๆใฎ่งฃๆใใใญในใใใฟใผใณใฎๆไฝใซๆ้ฉใงใใๅ่ปขๆใซในใใผในใจ็นๆฎๆๅญใฏไฟๆใใใพใใ",
+ "inputTitle": "ๅ่ปขใใใใญในใ",
+ "processMultiLine": "่คๆฐ่กใใญในใใๅฆ็ใใ",
+ "processMultiLineDescription": "ๅ่กใฏ็ฌ็ซใใฆๅ่ปขใใใพใ",
+ "resultTitle": "ๅ่ปขใใญในใ",
+ "reversalOptions": "ๅ่ปขใชใใทใงใณ",
+ "shortDescription": "ใใญในใใๆๅญใใจใซๅ่ปขใใพใ",
+ "skipEmptyLines": "็ฉบ่กใในใญใใใใ",
+ "skipEmptyLinesDescription": "ๅบๅใใ็ฉบ่กใฏๅ้คใใใพใ",
+ "title": "้่กใใ",
+ "trimWhitespace": "็ฉบ็ฝใใใชใ ใใ",
+ "trimWhitespaceDescription": "ๅ่กใฎๅ
้ ญใจๆซๅฐพใฎ็ฉบ็ฝใๅ้คใใพใ"
+ },
+ "rot13": {
+ "description": "ROT13 ๆๅทใไฝฟ็จใใฆใใญในใใใจใณใณใผใใพใใฏใใณใผใใใพใใ",
+ "inputTitle": "ๅ
ฅๅใใญในใ",
+ "resultTitle": "ROT13ใฎ็ตๆ",
+ "shortDescription": "ROT13 ๆๅทใไฝฟ็จใใฆใใญในใใใจใณใณใผใใพใใฏใใณใผใใใพใใ",
+ "title": "ROT13 ใจใณใณใผใ/ใใณใผใ",
+ "toolInfo": {
+ "description": "ROT13๏ผ13ๆกๅ่ปข๏ผใฏใๆๅญใใขใซใใกใใใใฎ13็ช็ฎใฎๆๅญใซ็ฝฎใๆใใใทใณใใซใชๆๅญ็ฝฎๆๆๅทใงใใROT13ใฏใๅคไปฃใญใผใใง้็บใใใใทใผใถใผๆๅทใฎ็นๆฎใชใฑใผในใงใใ่ฑ่ชใฎใขใซใใกใใใใฏ26ๆๅญใงใใใใใROT13ใฏใทใผใถใผๆๅทใฎ้ใงใใใใคใพใROT13ใๅ
ใซๆปใใซใฏๅใใขใซใดใชใบใ ใ้ฉ็จใใใใจใณใณใผใใจใใณใผใใซๅใๆไฝใไฝฟ็จใใใใจใใงใใพใใ",
+ "title": "ROT13ใจใฏไฝใงใใ?"
+ }
+ },
+ "rotate": {
+ "description": "ใใญในใๅ
ใฎๆๅญใๆๅฎใใใไฝ็ฝฎใ ใๅ่ปขใใพใใ",
+ "inputTitle": "ๅ
ฅๅใใญในใ",
+ "processAsMultiLine": "่คๆฐ่กใใญในใใจใใฆๅฆ็ใใ๏ผๅ่กใๅๅฅใซๅ่ปขใใ๏ผ",
+ "resultTitle": "ๅ่ปขใใใใญในใ",
+ "rotateLeft": "ๅทฆใซๅ่ปข",
+ "rotateRight": "ๅณใซๅ่ปข",
+ "rotationOptions": "ๅ่ปขใชใใทใงใณ",
+ "shortDescription": "ใใญในใๅ
ใฎๆๅญใไฝ็ฝฎใซใใฃใฆใทใใใใพใใ",
+ "stepDescription": "ใญใผใใผใทใงใณใใใใธใทใงใณใฎๆฐ",
+ "title": "ใใญในใใๅ่ปขใใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟ็จใใใจใๆๅญๅๅ
ใฎๆๅญใๆๅฎใใๆฐใ ใๅ่ปขใใใใใจใใงใใพใใๅทฆใพใใฏๅณใซๅ่ปขใใใใ่คๆฐ่กใฎใใญในใใๅ่กใใจใซๅ่ปขใใใฆๅฆ็ใใใใงใใพใใๆๅญๅใฎๅ่ปขใฏใๅ็ดใชใใญในใๅคๆใใใฟใผใณใฎไฝๆใๅบๆฌ็ใชๆๅทๅๆ่กใฎๅฎ่ฃ
ใซๅฝน็ซใกใพใใ",
+ "title": "ๅผฆใฎๅ่ปข"
+ }
+ },
+ "split": {
+ "charAfterChunkDescription": "ๅใใฃใณใฏใฎๅพใฎๆๅญ",
+ "charBeforeChunkDescription": "ๅใใฃใณใฏใฎๅใฎๆๅญ",
+ "chunksDescription": "ๅบๅๅ
ใฎๅใ้ทใใฎใใฃใณใฏใฎๆฐใ",
+ "chunksTitle": "ใใฃใณใฏใฎๆฐใไฝฟ็จใใ",
+ "description": "ไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใใญในใๅๅฒใฆใผใใฃใชใใฃใงใใใใญในใใๅ
ฅๅใใๅบๅใๆๅญใๆๅฎใใใ ใใง่คๆฐใฎ้จๅใซๅๅฒใงใใพใใใใผใฟๅฆ็ใใใญในใๆไฝใใพใใฏๅคงใใชใใญในใใใญใใฏใใ็นๅฎใฎใณใณใใณใใๆฝๅบใใใฎใซๆ้ฉใงใใ",
+ "lengthDescription": "ๅๅบๅใใฃใณใฏใซ้
็ฝฎใใใใทใณใใซใฎๆฐใ",
+ "lengthTitle": "้ทใใไฝฟใฃใฆๅๅฒใใ",
+ "outputSeparatorDescription": "ๅๅฒใใใใใฃใณใฏใฎ้ใซๆฟๅ
ฅใใใๆๅญใ(ใใใฉใซใใงใฏๆน่กๆๅญ \"\\n\" ใงใใ)",
+ "outputSeparatorOptions": "ๅบๅใปใใฌใผใฟใผใชใใทใงใณ",
+ "regexDescription": "ใใญในใใ่คๆฐใฎ้จๅใซๅๅฒใใใใใซไฝฟ็จใใใๆญฃ่ฆ่กจ็พใ\n(ใใใฉใซใใงใฏ่คๆฐใฎในใใผใน)",
+ "regexTitle": "ๆญฃ่ฆ่กจ็พใไฝฟ็จใใฆๅๅฒใใ",
+ "resultTitle": "ใใญในใ้จๅ",
+ "shortDescription": "ใปใใฌใผใฟใไฝฟ็จใใฆใใญในใใ่คๆฐใฎ้จๅใซๅๅฒใใ",
+ "splitSeparatorOptions": "ๅๅฒๅบๅใใชใใทใงใณ",
+ "symbolDescription": "ใใญในใใๅๅฒใใใใใซไฝฟ็จใใใๆๅญใ\n(ใใใฉใซใใฏในใใผใน)",
+ "symbolTitle": "ๅๅฒใซใทใณใใซใไฝฟ็จใใ",
+ "title": "ในใใชใใ"
+ },
+ "statistic": {
+ "characterFrequencyAnalysis": "ๆๅญ้ ปๅบฆๅๆ",
+ "characterFrequencyAnalysisDescription": "ๅๆๅญใใใญในใใซไฝๅๅบ็พใใใใๆฐใใ",
+ "delimitersOptions": "ๅบๅใๆๅญใชใใทใงใณ",
+ "description": "ใใญในใใๅๆใใๅ
ๆฌ็ใช็ตฑ่จใ็ๆใใพใใ",
+ "includeEmptyLines": "็ฉบ่กใๅซใใ",
+ "includeEmptyLinesDescription": "่กๆฐใๆฐใใใจใใซ็ฉบ็ฝ่กใๅซใใ",
+ "inputTitle": "ๅ
ฅๅใใญในใ",
+ "resultTitle": "ใใญในใ็ตฑ่จ",
+ "sentenceDelimitersDescription": "ใใชใใฎ่จ่ชใงๆใๅบๅใใใใซไฝฟ็จใใใซในใฟใ ๆๅญ๏ผใณใณใใงๅบๅใ๏ผใๅ
ฅๅใใใใใใใฉใซใใฎๅ ดๅใฏ็ฉบ็ฝใฎใพใพใซใใพใใ",
+ "sentenceDelimitersPlaceholder": "ไพ: .ใ!ใ?ใ...",
+ "shortDescription": "ใใญในใใซ้ขใใ็ตฑ่จๆ
ๅ ฑใๅๅพใใ",
+ "statisticsOptions": "็ตฑ่จใชใใทใงใณ",
+ "title": "ใใญในใ็ตฑ่จ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟ็จใใใจใใใญในใใๅๆใใๆๅญๆฐใๅ่ชๆฐใ่กๆฐใๆๅญใจๅ่ชใฎ้ ปๅบฆๅๆใชใฉใฎๅ
ๆฌ็ใช็ตฑ่จใ็ๆใงใใพใใ",
+ "title": "ไฝใงใใ {{title}}๏ผ"
+ },
+ "wordDelimitersDescription": "ๅ่ชๆฐใใซใฆใณใใใใใใฎใซในใฟใ ๆญฃ่ฆ่กจ็พใๅ
ฅๅใใใใใใใฉใซใใฎๅ ดๅใฏ็ฉบ็ฝใฎใพใพใซใใพใใ",
+ "wordDelimitersPlaceholder": "ไพ: \\s.,;:!?\"ยซยป()โฆ",
+ "wordFrequencyAnalysis": "ๅ่ช้ ปๅบฆๅๆ",
+ "wordFrequencyAnalysisDescription": "ๅๅ่ชใใใญในใใซไฝๅๅบ็พใใใใๆฐใใ"
+ },
+ "textReplacer": {
+ "description": "ใใญในใ ใใฟใผใณใๆฐใใใณใณใใณใใซ็ฝฎใๆใใพใใ",
+ "findPatternInText": "ใใญในใๅ
ใฎใใฎใใฟใผใณใ่ฆใคใใ",
+ "findPatternUsingRegexp": "ๆญฃ่ฆ่กจ็พใไฝฟใฃใฆใใฟใผใณใ่ฆใคใใ",
+ "inputTitle": "็ฝฎๆใใใใญในใ",
+ "newTextPlaceholder": "ๆฐใใใใญในใ",
+ "regexpDescription": "็ฝฎๆใใๆญฃ่ฆ่กจ็พใๅ
ฅๅใใพใใ",
+ "replacePatternDescription": "็ฝฎๆใซไฝฟ็จใใใใฟใผใณใๅ
ฅๅใใพใใ",
+ "replaceText": "ใใญในใใฎ็ฝฎๆ",
+ "resultTitle": "็ฝฎๆใใญในใ",
+ "searchPatternDescription": "็ฝฎๆใใใใญในใ ใใฟใผใณใๅ
ฅๅใใพใใ",
+ "searchText": "ๆค็ดขใใญในใ",
+ "shortDescription": "ใณใณใใณใๅ
ใฎใใญในใใ็ด ๆฉใ็ฝฎใๆใใ",
+ "title": "ใใญในใ็ฝฎๆ",
+ "toolInfo": {
+ "description": "ใใฎใทใณใใซใชใใฉใฆใถใใผในใฎใใผใซใไฝฟใใฐใใณใณใใณใๅ
ใฎ็นๅฎใฎใใญในใใ็ฐกๅใซ็ฝฎใๆใใใใจใใงใใพใใใใญในใใๅ
ฅๅใใ็ฝฎใๆใใใใใญในใใจ็ฝฎๆๅคใ่จญๅฎใใใ ใใงใใใใซๆดๆฐใใใใใผใธใงใณใๅๅพใงใใพใใ",
+ "title": "ใใญในใ็ฝฎๆ"
+ }
+ },
+ "toMorse": {
+ "dashSymbolDescription": "ใขใผใซในไฟกๅทใฎใใใทใฅใซๅฏพๅฟใใ่จๅทใ",
+ "description": "ใใญในใใใขใผใซในไฟกๅทใซๅคๆใใพใใ",
+ "dotSymbolDescription": "ใขใผใซในไฟกๅทใฎใใใใซๅฏพๅฟใใ่จๅทใ",
+ "longSignal": "ใญใณใฐใทใฐใใซ",
+ "resultTitle": "ใขใผใซในไฟกๅท",
+ "shortDescription": "ใใญในใใใขใผใซในไฟกๅทใซ็ด ๆฉใใจใณใณใผใ",
+ "shortSignal": "ใทใงใผใใทใฐใใซ",
+ "title": "ใขใผใซในไฟกๅทใธใฎๆๅญๅ"
+ },
+ "truncate": {
+ "addTruncationIndicator": "ๅใๆจใฆใคใณใธใฑใผใฟใผใ่ฟฝๅ ",
+ "charactersPlaceholder": "ใญใฃใฉใฏใฟใผ",
+ "description": "ใใญในใใๆๅฎใใใ้ทใใซ็ญ็ธฎใใพใใ",
+ "indicatorDescription": "ใใญในใใฎๆซๅฐพ๏ผใพใใฏๅ
้ ญ๏ผใซ่ฟฝๅ ใใๆๅญใๆณจ: ้ทใใซใซใฆใณใใใใพใใ",
+ "inputTitle": "ๅ
ฅๅใใญในใ",
+ "leftSideDescription": "ใใญในใใฎๅ
้ ญใใๆๅญใๅ้คใใพใใ",
+ "leftSideTruncation": "ๅทฆๅดๅใๆจใฆ",
+ "lengthAndLines": "้ทใใจ็ท",
+ "lineByLineDescription": "ๅ่กใๅๅฅใซๅใๆจใฆใพใใ",
+ "lineByLineTruncating": "่กใใจใฎๅใๆจใฆ",
+ "maxLengthDescription": "ใใญในใใซๆฎใๆๅญๆฐใ",
+ "numberPlaceholder": "็ชๅท",
+ "resultTitle": "ๅใๆจใฆใใใใใญในใ",
+ "rightSideDescription": "ใใญในใใฎๆซๅฐพใใๆๅญใๅ้คใใพใใ",
+ "rightSideTruncation": "ๅณๅดๅใๆจใฆ",
+ "shortDescription": "ๆๅฎใใใ้ทใใซใใญในใใๅใๆจใฆใ",
+ "suffixAndAffix": "ๆฅๅฐพ่พใจๆฅ่พ",
+ "title": "ใใญในใใๅใๆจใฆใ",
+ "toolInfo": {
+ "description": "ๅทฆๅดใฎๅ
ฅๅใใฉใผใ ใซใใญในใใ่ชญใฟ่พผใใจใๅณๅดใซๅใๆจใฆใใใใใญในใใ่ชๅ็ใซ่กจ็คบใใใพใใ",
+ "title": "ใใญในใใๅใๆจใฆใ"
+ },
+ "truncationSide": "ๅใๆจใฆๅด"
+ },
+ "uppercase": {
+ "description": "ใใญในใใๅคงๆๅญใซๅคๆใใพใใ",
+ "inputTitle": "ๅ
ฅๅใใญในใ",
+ "resultTitle": "ๅคงๆๅญใฎใใญในใ",
+ "shortDescription": "ใใญในใใๅคงๆๅญใซๅคๆใใ",
+ "title": "ๅคงๆๅญใซๅคๆ"
+ }
+}
diff --git a/public/locales/ja/time.json b/public/locales/ja/time.json
new file mode 100644
index 0000000..a9b6b2d
--- /dev/null
+++ b/public/locales/ja/time.json
@@ -0,0 +1,100 @@
+{
+ "checkLeapYears": {
+ "description": "ใใฎๅนดใใใใๅนดใใฉใใใ็ขบ่ชใใใใใๅนดๆ
ๅ ฑใๅๅพใใพใใ",
+ "inputTitle": "ๅ
ฅๅๅนด",
+ "resultTitle": "้ๅนดใฎ็ตๆ",
+ "shortDescription": "ใใฎๅนดใใใใๅนดใใฉใใใใใงใใฏใใ",
+ "title": "ใใใๅนดใ็ขบ่ชใใ",
+ "toolInfo": {
+ "description": "้ๅนดใจใฏใๆฆๅนดใๅคฉๆๅนดใจไธ่ดใใใใใใซใ1ๆฅ๏ผ2ๆ29ๆฅ๏ผใ่ฟฝๅ ใใใๅนดใงใใ้ๅนดใฏ4ๅนดใซ1ๅบฆ็บ็ใใพใใใ100ใงๅฒใๅใใใ400ใงๅฒใๅใใชใๅนดใฏไพๅคใงใใ",
+ "title": "ใใใๅนดใจใฏไฝใงใใ?"
+ }
+ },
+ "convertDaysToHours": {
+ "addHoursName": "ๅถๆฅญๆ้ๅใ่ฟฝๅ ",
+ "addHoursNameDescription": "ๅบๅๅคใซๆๅญๅใๆ้ใใ่ฟฝๅ ใใพใ",
+ "description": "ใซในใฟใใคใบๅฏ่ฝใชใชใใทใงใณใไฝฟ็จใใฆๆฅๆฐใๆ้ๆฐใซๅคๆใใพใใ",
+ "hoursName": "ๆ้ๅ",
+ "shortDescription": "ๆฅๆฐใๆ้ๆฐใซๅคๆใใ",
+ "title": "ๆฅๆฐใๆ้ๆฐใซๅคๆใใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใจใๆฅๆฐใๆ้ๆฐใซๅคๆใงใใพใใๆฅๆฐใๆฐๅคใพใใฏๅไฝไปใใงๅ
ฅๅใใใจใใใผใซใๆ้ๆฐใซๅคๆใใพใใใพใใๅบๅๅคใฎๆซๅฐพใซใๆ้ใใไปใใใใจใใงใใพใใ",
+ "title": "ๆฅๆฐใๆ้ๆฐใซๅคๆใใ"
+ }
+ },
+ "convertHoursToDays": {
+ "addDaysName": "ๆๆฅๅใ่ฟฝๅ ",
+ "addDaysNameDescription": "ๅบๅๅคใซๆๅญๅ days ใ่ฟฝๅ ใใพใ",
+ "daysName": "ๆฅไปๅ",
+ "description": "ใซในใฟใใคใบๅฏ่ฝใชใชใใทใงใณใไฝฟ็จใใฆๆ้ใๆฅๆฐใซๅคๆใใพใใ",
+ "shortDescription": "ๆ้ใๆฅๆฐใซๅคๆใใ",
+ "title": "ๆ้ใๆฅๆฐใซๅคๆใใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใจใๆ้ใๆฅๆฐใซๅคๆใงใใพใใๆ้ใๆฐๅคใพใใฏๅไฝไปใใงๅ
ฅๅใใใจใใใผใซใๆฅๆฐใซๅคๆใใพใใใพใใๅบๅๅคใฎๆซๅฐพใซใๆฅๆฐใใไปใใใใจใใงใใพใใ",
+ "title": "ๆ้ใๆฅๆฐใซๅคๆใใ"
+ }
+ },
+ "convertSecondsToTime": {
+ "addPadding": "ใใใฃใณใฐใ่ฟฝๅ ",
+ "addPaddingDescription": "ๆ้ใๅใ็งใซใผใญใใใฃใณใฐใ่ฟฝๅ ใใพใใ",
+ "description": "็งๆฐใๅค่ชญๅฏ่ฝใชๆๅปๅฝขๅผ๏ผๆ:ๅ:็ง๏ผใซๅคๆใใพใใ็งๆฐใๅ
ฅๅใใใจใใใฉใผใใใใใใๆๅปใ่กจ็คบใใใพใใ",
+ "shortDescription": "็งใๆ้ๅฝขๅผใซๅคๆใใ",
+ "timePadding": "ๆ้ใฎใใใฃใณใฐ",
+ "title": "็งใๆ้ใซๅคๆใใ",
+ "toolInfo": {
+ "title": "ไฝใงใใ {{title}}๏ผ"
+ }
+ },
+ "convertTimeToSeconds": {
+ "description": "ใใฉใผใใใใใใๆ้ (HH:MM:SS) ใ็งใซๅคๆใใพใใ",
+ "inputTitle": "ๅ
ฅๅๆ้",
+ "resultTitle": "็ง",
+ "shortDescription": "ๆ้ๅฝขๅผใ็งใซๅคๆใใ",
+ "title": "ๆ้ใ็งใซๅคๆใใ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใจใใใฉใผใใใใใใๆๅปๆๅญๅ๏ผHH:MM:SS๏ผใ็งๆฐใซๅคๆใงใใพใใๆ้ใๆ้้้ใ่จ็ฎใใใฎใซไพฟๅฉใงใใ",
+ "title": "ๆ้ใ็งใซๅคๆใใ"
+ }
+ },
+ "crontabGuru": {
+ "description": "cronๅผใ็ๆใใ็่งฃใใพใใ่ชๅๅใใใใฟในใฏใใทในใใ ใธใงใใฎcronในใฑใธใฅใผใซใไฝๆใใพใใ",
+ "shortDescription": "cronๅผใ็ๆใใฆ็่งฃใใ",
+ "title": "ใฏใญใณใฟใใฎ้ไบบ"
+ },
+ "timeBetweenDates": {
+ "description": "2ใคใฎๆฅไป้ใฎๆๅทฎใ่จ็ฎใใพใใๆญฃ็ขบใชๆฅๆฐใๆ้ใๅใ็งใๅๅพใใพใใ",
+ "endDate": "็ตไบๆฅ",
+ "endDateTime": "็ตไบๆฅๆ",
+ "endTime": "็ตไบๆ้",
+ "endTimezone": "็ตไบใฟใคใ ใพใผใณ",
+ "shortDescription": "2ใคใฎๆฅไป้ใฎๆ้ใ่จ็ฎใใ",
+ "startDate": "้ๅงๆฅ",
+ "startDateTime": "้ๅงๆฅๆ",
+ "startTime": "้ๅงๆ้",
+ "startTimezone": "้ๅงใฟใคใ ใพใผใณ",
+ "title": "ๆฅไป้ใฎๆ้",
+ "toolInfo": {
+ "description": "2ใคใฎๆฅไปใจๆๅปใฎๆญฃ็ขบใชๆๅทฎใ่จ็ฎใใพใใ่คๆฐใฎใฟใคใ ใพใผใณใซๅฏพๅฟใใฆใใพใใใใฎใใผใซใฏใๆๅทฎใๆงใ
ใชๅไฝ๏ผๅนดใๆใๆฅใๆใๅใ็ง๏ผใง่ฉณ็ดฐใซ่กจ็คบใใพใใ",
+ "title": "ๆฅไป้ใฎๆ้่จ็ฎๆฉ"
+ }
+ },
+ "truncateClockTime": {
+ "description": "็งๆฐใพใใฏๅๆฐใๅใๆจใฆใฆๆ่จใฎๆๅปใ่กจ็คบใใพใใๆ้ใๆใ่ฟใๆ้ใๅใใพใใฏใซในใฟใ ้้ใซไธธใใพใใ",
+ "printDroppedComponents": "ใใญใใใใใใณใณใใผใใณใใๅฐๅทใใ",
+ "shortDescription": "ๆๅฎใใใ็ฒพๅบฆใงใฏใญใใฏๆ้ใๅใๆจใฆใ",
+ "timePadding": "ๆ้ใฎใใใฃใณใฐ",
+ "title": "ๆ่จๆ้ใๅใๆจใฆใ",
+ "toolInfo": {
+ "title": "ไฝใงใใ {{title}}๏ผ"
+ },
+ "truncateMinutesAndSeconds": "ๅใจ็งใๅใๆจใฆใ",
+ "truncateMinutesAndSecondsDescription": "ๅใฏใญใใฏๆ้ใใๅใจ็งใฎไธกๆนใฎ่ฆ็ด ใๅ้คใใพใใ",
+ "truncateOnlySeconds": "็งใฎใฟๅใๆจใฆ",
+ "truncateOnlySecondsDescription": "ๅใฏใญใใฏๆ้ใใ็งใฎ่ฆ็ด ใๅ้คใใพใใ",
+ "truncationSide": "ๅใๆจใฆๅด",
+ "useZeroPadding": "ใผใญใใใฃใณใฐใไฝฟ็จใใ",
+ "zeroPaddingDescription": "ใในใฆใฎๆ้ใณใณใใผใใณใใๅธธใซ 2 ๆกใฎๅน
ใซใใพใใ",
+ "zeroPrintDescription": "ใใญใใใใใ้จๅใใผใญๅคใ00ใใจใใฆ่กจ็คบใใพใใ",
+ "zeroPrintTruncatedParts": "ใผใญๅฐๅทๅใๆจใฆ้จๅ"
+ }
+}
diff --git a/public/locales/ja/translation.json b/public/locales/ja/translation.json
new file mode 100644
index 0000000..97c87b0
--- /dev/null
+++ b/public/locales/ja/translation.json
@@ -0,0 +1,250 @@
+{
+ "audio": {
+ "changeSpeed": {
+ "description": "ใชใผใใฃใชใใกใคใซใฎๅ็้ๅบฆใๅคๆดใใพใใใใใใ็ถญๆใใชใใใใชใผใใฃใชใฎๅ็้ๅบฆใไธใใใไธใใใใงใใพใใ",
+ "name": "ใชใผใใฃใช้ๅบฆใๅคๆดใใ",
+ "shortDescription": "ใชใผใใฃใชใใกใคใซใฎ้ๅบฆใๅคๆดใใ"
+ },
+ "extractAudio": {
+ "description": "ใใใช ใใกใคใซใใใชใผใใฃใช ใใฉใใฏใๆฝๅบใใ้ธๆใใๅฝขๅผ (AACใMP3ใWAV) ใงๅๅฅใฎใชใผใใฃใช ใใกใคใซใจใใฆไฟๅญใใพใใ",
+ "name": "้ณๅฃฐใๆฝๅบใใ",
+ "shortDescription": "ใใใช ใใกใคใซ (MP4ใMOV ใชใฉ) ใใใชใผใใฃใชใ AACใMP3ใใพใใฏ WAV ใซๆฝๅบใใพใใ"
+ }
+ },
+ "baseFileInput": {
+ "copyFailed": "ใณใใผใซๅคฑๆใใพใใ: {{error}}",
+ "dropFileHere": "ใใญใใ {{type}} ใใ",
+ "fileCopied": "ใใกใคใซใใณใใผใใพใใ",
+ "selectFileDescription": "้ธๆใใใซใฏใใใใฏใชใใฏใใฆใใ ใใ {{type}} ใใใคในใใCtrl+Vใๆผใใฆ {{type}} ใฏใชใใใใผใใใใใพใใฏใในใฏใใใใใใใกใคใซใใใฉใใฐใขใณใใใญใใใใพใ"
+ },
+ "categories": {
+ "audio": {
+ "description": "ใชใผใใฃใชใๆไฝใใใใใฎใใผใซ โ ใใใชใใใชใผใใฃใชใๆฝๅบใใใใใชใผใใฃใช้ๅบฆใ่ชฟๆดใใใใ่คๆฐใฎใชใผใใฃใช ใใกใคใซใ็ตๅใใใใใใฎไปใใพใใพใชๆฉ่ฝใๅใใฆใใพใใ",
+ "title": "ใชใผใใฃใชใใผใซ"
+ },
+ "csv": {
+ "description": "CSV ใใกใคใซใฎๆไฝ็จใใผใซ - CSV ใใใพใใพใชๅฝขๅผใซๅคๆใใCSV ใใผใฟใๆไฝใใCSV ๆง้ ใๆค่จผใใCSV ใใกใคใซใๅน็็ใซๅฆ็ใใพใใ",
+ "title": "CSVใใผใซ"
+ },
+ "gif": {
+ "description": "GIF ใขใใกใผใทใงใณใๆไฝใใใใใฎใใผใซ โ ้ๆใช GIF ใฎไฝๆใGIF ใใฌใผใ ใฎๆฝๅบใGIF ใธใฎใใญในใใฎ่ฟฝๅ ใGIF ใฎๅใๅใใๅ่ปขใๅ่ปขใชใฉใ",
+ "title": "GIFใใผใซ"
+ },
+ "image-generic": {
+ "description": "็ปๅใๆไฝใใใใผใซ โ ๅง็ธฎใใตใคใบๅคๆดใๅใๅใใJPG ใธใฎๅคๆใๅ่ปขใ่ๆฏใฎๅ้คใชใฉใ",
+ "title": "็ปๅใใผใซ"
+ },
+ "json": {
+ "description": "JSON ใใผใฟๆง้ ใๆไฝใใใใใฎใใผใซ โ JSON ใชใใธใงใฏใใฎๆดๅฝขใจ็ธฎๅฐใJSON ้
ๅใฎใใฉใใๅใJSON ๅคใฎๆๅญๅๅใใใผใฟใฎๅๆใชใฉ",
+ "title": "JSONใใผใซ"
+ },
+ "list": {
+ "description": "ใชในใใๆไฝใใใใใฎใใผใซ โ ใชในใใฎไธฆในๆฟใใๅ่ปขใใฉใณใใ ๅใไธๆใฎใชในใ้
็ฎใจ้่คใใใชในใ้
็ฎใฎๆค็ดขใใชในใ้
็ฎใฎๅบๅใใฎๅคๆดใชใฉใ",
+ "title": "ใชในใใใผใซ"
+ },
+ "number": {
+ "description": "ๆฐๅญใๆไฝใใใใใฎใใผใซ โ ๆฐๅใ็ๆใใใใๆฐๅญใๅ่ชใซๅคๆใใใใๅ่ชใๆฐๅญใซๅคๆใใใใๆฐๅญใไธฆในๆฟใใใใๅๆจไบๅ
ฅใใใใๅ ๆฐๅ่งฃใใใใใใฎไปใใพใใพใชๆฉ่ฝใใใใพใใ",
+ "title": "ๆฐๅคใใผใซ"
+ },
+ "pdf": {
+ "description": "PDF ใใกใคใซใฎๆไฝใใผใซ - PDF ใใใใญในใใๆฝๅบใใใใPDF ใไปใฎๅฝขๅผใซๅคๆใใใใPDF ใๆไฝใใใใใใฎไปใใพใใพใชๆฉ่ฝใๅใใฆใใพใใ",
+ "title": "PDFใใผใซ"
+ },
+ "png": {
+ "description": "PNG ็ปๅใๆไฝใใใใผใซ โ PNG ใ JPG ใซๅคๆใใใใ้ๆใช PNG ใไฝๆใใใใPNG ใฎ่ฒใๅคๆดใใใใPNG ใๅใๅใฃใใใๅ่ปขใใใใใตใคใบๅคๆดใใใใใใฎไปๅคใใฎๆฉ่ฝใใใใพใใ",
+ "title": "PNGใใผใซ"
+ },
+ "seeAll": "ใในใฆใ่ฆใ {{title}}",
+ "string": {
+ "description": "ใใญในใใๆไฝใใใใใฎใใผใซ โ ใใญในใใ็ปๅใซๅคๆใใใใใใญในใใๆค็ดขใใฆ็ฝฎๆใใใใใใญในใใๆญ็ใซๅๅฒใใใใใใญในใ่กใ็ตๅใใใใใใญในใใ็นฐใ่ฟใใใใใใฎไปใใพใใพใชๆฉ่ฝใใใใพใใ",
+ "title": "ใใญในใใใผใซ"
+ },
+ "time": {
+ "description": "ๆ้ใจๆฅไปใๆไฝใใใใใฎใใผใซ โ ๆๅทฎใฎ่จ็ฎใใฟใคใ ใพใผใณใฎๅคๆใๆฅไปใฎๆธๅผ่จญๅฎใๆฅไปใทใผใฑใณในใฎ็ๆใชใฉใ",
+ "title": "ๆ้ใใผใซ"
+ },
+ "try": "่ฉฆใ {{title}}",
+ "video": {
+ "description": "ใใใชใๆไฝใใใใใฎใใผใซ โ ใใใชใใใใฌใผใ ใๆฝๅบใใใใใใใชใใ GIF ใไฝๆใใใใใใใชใใใพใใพใชๅฝขๅผใซๅคๆใใใใใใฎไปใใพใใพใชๆฉ่ฝใๅใใฆใใพใใ",
+ "title": "ใใใชใใผใซ"
+ },
+ "xml": {
+ "description": "XML ใใผใฟๆง้ ใๆไฝใใใใใฎใใผใซ - ใใฅใผใขใใใฅใผใใฃใใกใคใขใใใชใใผใฟใชใฉ",
+ "title": "XMLใใผใซ"
+ }
+ },
+ "csv": {
+ "findIncompleteCsvRecords": {
+ "description": "ไปฅไธใฎใใฉใผใ ใซCSVใใกใคใซใใขใใใญใผใใใใ ใใงใใใฎใใผใซใฏ่กใพใใฏๅใซๆฌ ๆๅคใใชใใใฉใใใ่ชๅ็ใซใใงใใฏใใพใใใใผใซใฎใชใใทใงใณใงใฏใๅ
ฅๅใใกใคใซใฎๅฝขๅผ๏ผๅบๅใๆๅญใๅผ็จ็ฌฆใใณใกใณใๆๅญใฎๆๅฎ๏ผใ่ชฟๆดใงใใพใใใใใซใ็ฉบๅคใฎใใงใใฏใๆๅนใซใใใใ็ฉบ่กใในใญใใใใใใๅบๅๆใฎใจใฉใผใกใใปใผใธใฎๆฐใซๅถ้ใ่จญๅฎใใใใใใใจใใงใใพใใ",
+ "name": "ไธๅฎๅ
จใชCSVใฌใณใผใใ่ฆใคใใ",
+ "shortDescription": "CSV ๅ
ใงๅคใๆฌ ่ฝใใฆใใ่กใจๅใใใฐใใ่ฆใคใใพใใ"
+ }
+ },
+ "hero": {
+ "brand": "ใชใ ใใใผใซ",
+ "description": "ไฝๆฅญใ็ด ๆฉใๅฎไบใใใใใฎ็ฉถๆฅตใฎใใผใซใญใใใOmniTools ใง็็ฃๆงใ้ฃ่บ็ใซๅไธใใใพใใใใ็ปๅใใใญในใใใชในใใใใผใฟใ็ทจ้ใใใใใฎๆฐๅใใฎไฝฟใใใใใฆใผใใฃใชใใฃใซใใใฉใฆใถใใ็ดๆฅใขใฏใปในใงใใพใใ",
+ "examples": {
+ "calculateNumberSum": "ๆฐๅคใฎๅ่จใ่จ็ฎใใ",
+ "changeGifSpeed": "GIFใฎ้ๅบฆใๅคๆดใใ",
+ "compressPng": "PNGใๅง็ธฎ",
+ "createTransparentImage": "้ๆใช็ปๅใไฝๆใใ",
+ "prettifyJson": "JSONใ็พใใใใ",
+ "sortList": "ใชในใใไธฆในๆฟใใ",
+ "splitPdf": "PDFใๅๅฒ",
+ "splitText": "ใใญในใใๅๅฒใใ",
+ "trimVideo": "ใใใชใใใชใใณใฐใใ"
+ },
+ "searchPlaceholder": "ใในใฆใฎใใผใซใๆค็ดข",
+ "title": "็ฉไบใ็ด ๆฉใ็ตใใใใ"
+ },
+ "inputFooter": {
+ "clear": "ใฏใชใข",
+ "copyToClipboard": "ใฏใชใใใใผใใซใณใใผ",
+ "importFromFile": "ใใกใคใซใใใคใณใใผใ"
+ },
+ "list": {
+ "group": {
+ "description": "ใชในใ้
็ฎใใฐใซใผใๅใใใใใฎใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใชในใใๅ
ฅๅใใใฐใซใผใๅใฎๆกไปถใๆๅฎใใใ ใใงใ้
็ฎใ่ซ็็ใชใฐใซใผใใซๆด็ใงใใพใใใใผใฟใฎๅ้กใๆ
ๅ ฑใฎๆด็ใๆง้ ๅใใใใชในใใฎไฝๆใซๆ้ฉใงใใใซในใฟใ ใปใใฌใผใฟใผใจๆงใ
ใชใฐใซใผใๅใชใใทใงใณใใตใใผใใใฆใใพใใ",
+ "name": "ใฐใซใผใ",
+ "shortDescription": "ๅ
ฑ้ใฎใใญใใใฃใงใชในใ้
็ฎใใฐใซใผใๅใใ"
+ },
+ "reverse": {
+ "description": "ใใใฏใใในใฆใฎใชในใ้
็ฎใ้้ ใซ่กจ็คบใใใ้ๅธธใซใทใณใใซใชใใฉใฆใถใใผในใฎใขใใชใฑใผใทใงใณใงใใๅ
ฅๅ้
็ฎใฏไปปๆใฎ่จๅทใงๅบๅใใใจใใงใใ้้ ใซ่กจ็คบใใใชในใ้
็ฎใฎๅบๅใๆๅญใๅคๆดใใใใจใใงใใพใใ",
+ "name": "้่กใใ",
+ "shortDescription": "ใชในใใ็ด ๆฉใ้้ ใซใใ"
+ },
+ "sort": {
+ "description": "ใใใฏใใชในใๅ
ใฎ้
็ฎใๆ้ ใพใใฏ้้ ใซไธฆในๆฟใใใ้ๅธธใซใทใณใใซใชใใฉใฆใถใใผในใฎใขใใชใฑใผใทใงใณใงใใ้
็ฎใฏใขใซใใกใใใ้ ใๆฐๅญ้ ใใพใใฏ้ทใใงไธฆในๆฟใใใใจใใงใใพใใใพใใ้่ค้
็ฎใ็ฉบ้
็ฎใๅ้คใใใใ็ฉบ็ฝใงๅฒใพใใ้
็ฎใๅๅฅใซๅใๅใฃใใใใใใจใๅฏ่ฝใงใใๅ
ฅๅใชในใ้
็ฎใฏใไปปๆใฎๅบๅใๆๅญใใพใใฏๆญฃ่ฆ่กจ็พใไฝฟ็จใใฆๅบๅใใใจใใงใใพใใใใใซใใฝใผใใใใๅบๅใชในใ็จใซๆฐใใๅบๅใๆๅญใไฝๆใใใใจใใงใใพใใ",
+ "name": "้ธๅฅ",
+ "shortDescription": "ใชในใใ็ด ๆฉใไธฆในๆฟใใ"
+ }
+ },
+ "navbar": {
+ "buyMeACoffee": "ใณใผใใผใ่ฒทใฃใฆใใ ใใ",
+ "home": "ๅฎถ",
+ "tools": "ใใผใซ"
+ },
+ "number": {
+ "generate": {
+ "description": "ใใฉใฆใถใงๆดๆฐใฎใชในใใ็ด ๆฉใ่จ็ฎใใพใใใชในใใๅๅพใใใซใฏใๆๅใฎๆดๆฐใๆๅฎใใไปฅไธใฎใชใใทใงใณใงๅคใจๅ่จๆฐใๅคๆดใใใ ใใงใใใฎใฆใผใใฃใชใใฃใใใฎๆฐใฎๆดๆฐใ็ๆใใพใใ",
+ "name": "ๆฐๅญใ็ๆใใ",
+ "shortDescription": "ใใฉใฆใถใงๆดๆฐใฎใชในใใ็ด ๆฉใ่จ็ฎใใ"
+ },
+ "sum": {
+ "description": "ใใใฏใๆฐๅคใๅ่จใใ้ๅธธใซใทใณใใซใชใใฉใฆใถใใผในใฎใขใใชใฑใผใทใงใณใงใใๅ
ฅๅใใๆฐๅคใฏไปปๆใฎ่จๅทใงๅบๅใใใจใใงใใๅ่จใใๆฐๅคใฎๅบๅใๆๅญใๅคๆดใใใใจใใงใใพใใ",
+ "name": "ๆฐๅญใๅ่จใใ",
+ "shortDescription": "ๆฐๅคใชในใใ็ด ๆฉใๅ่จใใ"
+ }
+ },
+ "numericInputWithUnit": {
+ "unit": "ใฆใใใ"
+ },
+ "pdf": {
+ "compressPdf": {
+ "description": "Ghostscriptใไฝฟ็จใใฆๅ่ณชใ็ถญๆใใชใใPDFใใกใคใซใฎใตใคใบใ็ธฎๅฐใใ",
+ "name": "PDFใๅง็ธฎ",
+ "shortDescription": "ใใฉใฆใถใงPDFใใกใคใซใๅฎๅ
จใซๅง็ธฎ"
+ },
+ "mergePdf": {
+ "description": "่คๆฐใฎ PDF ใใกใคใซใ 1 ใคใฎใใญใฅใกใณใใซ็ตๅใใพใใ",
+ "name": "PDFใ็ตๅ",
+ "shortDescription": "่คๆฐใฎPDFใใกใคใซใ1ใคใฎๆๆธใซ็ตๅใใ"
+ },
+ "pdfToEpub": {
+ "description": "้ปๅญๆธ็ฑใชใผใใผใจใฎไบๆๆงใ้ซใใใใใซใPDF ใใญใฅใกใณใใ EPUB ใใกใคใซใซๅคๆใใพใใ",
+ "name": "PDFใใEPUBใธ",
+ "shortDescription": "PDFใใกใคใซใEPUBๅฝขๅผใซๅคๆใใ"
+ },
+ "protectPdf": {
+ "description": "ใใฉใฆใถใงๅฎๅ
จใซPDFใใกใคใซใซใในใฏใผใไฟ่ญทใ่ฟฝๅ ใใพใ",
+ "name": "PDFใไฟ่ญทใใ",
+ "shortDescription": "PDFใใกใคใซใใในใฏใผใใงๅฎๅ
จใซไฟ่ญทใใ"
+ },
+ "splitPdf": {
+ "description": "ใใผใธ็ชๅทใพใใฏ็ฏๅฒ๏ผไพ๏ผ1,5-8๏ผใไฝฟ็จใใฆใPDF ใใกใคใซใใ็นๅฎใฎใใผใธใๆฝๅบใใพใใ",
+ "name": "PDFใๅๅฒ",
+ "shortDescription": "PDFใใกใคใซใใ็นๅฎใฎใใผใธใๆฝๅบใใ"
+ }
+ },
+ "resultFooter": {
+ "copy": "ใฏใชใใใใผใใซใณใใผ",
+ "download": "ใใฆใณใญใผใ"
+ },
+ "string": {
+ "createPalindrome": {
+ "description": "ใใใใใใญในใใใๅๆใไฝๆใงใใใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใใญในใใๅ
ฅๅใใใจใๅๅพใฉใกใใใ่ชญใใงใๅใๅๆใซ็ฌๆใซๅคๆใใใพใใ่จ่้ใณใๅฏพ็งฐ็ใชใใญในใใใฟใผใณใฎไฝๆใ่จ่ช็ๅฅฝๅฅๅฟใฎๆขๆฑใชใฉใซๆ้ฉใงใใ",
+ "name": "ๅๆใไฝๆใใ",
+ "shortDescription": "ๅๅพใฉใกใใใ่ชญใใงใๅใใใญในใใไฝๆใใ"
+ },
+ "palindrome": {
+ "description": "ใใญในใใๅๆใงใใใใฉใใใใใงใใฏใใใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใใใญในใใๅๅพใฉใกใใใ่ชญใใงใๅใใใฉใใใ็ฌๆใซๆค่จผใใพใใๅ่ชใใบใซใ่จ่ชๅๆใๅฏพ็งฐ็ใชใใญในใใใฟใผใณใฎๆค่จผใซๆ้ฉใงใใๆงใ
ใชๅบๅใๆๅญใจ่คๆฐๅ่ชใฎๅๆๆคๅบใซๅฏพๅฟใใฆใใพใใ",
+ "name": "ๅๆ",
+ "shortDescription": "ใใญในใใๅๅพใงๅใ่ชญใฟๆนใใใฆใใใ็ขบ่ชใใ"
+ },
+ "repeat": {
+ "description": "ใใฎใใผใซใไฝฟ็จใใใจใใชใใทใงใณใฎๅบๅใๆๅญใไฝฟ็จใใฆใ็นๅฎใฎใใญในใใ่คๆฐๅ็นฐใ่ฟใใใจใใงใใพใใ",
+ "name": "ใใญในใใฎ็นฐใ่ฟใ",
+ "shortDescription": "ใใญในใใ่คๆฐๅ็นฐใ่ฟใ"
+ },
+ "reverse": {
+ "description": "ไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใใญในใๅ่ปขใฆใผใใฃใชใใฃใไปปๆใฎใใญในใใๅ
ฅๅใใใจใๆๅญใใจใซ็ฌๆใซๅ่ปขใใพใใ้กๆๅญใฎไฝๆใๅๆใฎ่งฃๆใใใญในใใใฟใผใณใฎๆไฝใซๆ้ฉใงใใๅ่ปขๆใซในใใผในใจ็นๆฎๆๅญใฏไฟๆใใใพใใ",
+ "name": "้่กใใ",
+ "shortDescription": "ใใญในใใๆๅญใใจใซๅ่ปขใใพใ"
+ },
+ "toMorse": {
+ "description": "ใใญในใใใขใผใซในไฟกๅทใซๅคๆใใใไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใฆใผใใฃใชใใฃใงใใๅทฆๅดใฎๅ
ฅๅใใฉใผใ ใซใใญในใใๅ
ฅๅใใใจใๅบๅใจใชใขใซใขใผใซในไฟกๅทใ็ฌๆใซ่กจ็คบใใใพใใ้ซๆฉ่ฝใ็กๆใใใใฆ้ซ้ใใใญในใใ่ชญใฟ่พผใใงใขใผใซในไฟกๅทใๅๅพใ",
+ "name": "ใขใผใซในไฟกๅทใธใฎๆๅญๅ",
+ "shortDescription": "ใใญในใใใขใผใซในไฟกๅทใซ็ด ๆฉใใจใณใณใผใ"
+ },
+ "uppercase": {
+ "description": "ไธ็ใงๆใใทใณใใซใชใใฉใฆใถใใผในใฎใใญในใๅคงๆๅญๅคๆใฆใผใใฃใชใใฃใใใญในใใๅ
ฅๅใใใ ใใงใ่ชๅ็ใซใในใฆๅคงๆๅญใซๅคๆใใใพใใ่ฆๅบใใฎไฝๆใใใญในใใฎๅผท่ชฟใใใญในใๅฝขๅผใฎๆจๆบๅใซๆ้ฉใงใใๆงใ
ใชใใญในใๅฝขๅผใใตใใผใใใ็นๆฎๆๅญใไฟๆใใพใใ",
+ "name": "ๅคงๆๅญ",
+ "shortDescription": "ใใญในใใๅคงๆๅญใซๅคๆใใ"
+ }
+ },
+ "toolExamples": {
+ "subtitle": "ใฏใชใใฏใใฆใ่ฉฆใใใ ใใ!",
+ "title": "{{title}} ไพ"
+ },
+ "toolFileResult": {
+ "copied": "ใใกใคใซใใณใใผใใพใใ",
+ "copyFailed": "ใณใใผใซๅคฑๆใใพใใ: {{error}}",
+ "loading": "่ชญใฟ่พผใฟไธญ... ๅฐใ
ๆ้ใใใใๅ ดๅใใใใพใใ",
+ "result": "็ตๆ"
+ },
+ "toolHeader": {
+ "seeExamples": "ไพใ่ฆใ"
+ },
+ "toolLayout": {
+ "allToolsTitle": "ๅ
จใฆ {{type}}"
+ },
+ "toolMultiFileResult": {
+ "copied": "ใใกใคใซใใณใใผใใพใใ",
+ "copyFailed": "ใณใใผใซๅคฑๆใใพใใ: {{error}}",
+ "loading": "่ชญใฟ่พผใฟไธญ... ๅฐใ
ๆ้ใใใใๅ ดๅใใใใพใใ",
+ "result": "็ตๆ"
+ },
+ "toolMultipleAudioInput": {
+ "inputTitle": "ๅ
ฅๅ {{type}}",
+ "noFilesSelected": "ใใกใคใซใ้ธๆใใใฆใใพใใ"
+ },
+ "toolMultiplePdfInput": {
+ "inputTitle": "ๅ
ฅๅ {{type}}",
+ "noFilesSelected": "ใใกใคใซใ้ธๆใใใฆใใพใใ"
+ },
+ "toolOptions": {
+ "title": "ใใผใซใชใใทใงใณ"
+ },
+ "toolTextInput": {
+ "copied": "ใใญในใใใณใใผใใพใใ",
+ "copyFailed": "ใณใใผใซๅคฑๆใใพใใ: {{error}}",
+ "input": "ๅ
ฅๅใใญในใ",
+ "placeholder": "ใใใซใใญในใใๅ
ฅๅใใฆใใ ใใ..."
+ },
+ "toolTextResult": {
+ "copied": "ใใญในใใใณใใผใใพใใ",
+ "copyFailed": "ใณใใผใซๅคฑๆใใพใใ: {{error}}",
+ "loading": "่ชญใฟ่พผใฟไธญ... ๅฐใ
ๆ้ใใใใๅ ดๅใใใใพใใ",
+ "result": "็ตๆ"
+ }
+}
diff --git a/public/locales/ja/video.json b/public/locales/ja/video.json
new file mode 100644
index 0000000..4cb451b
--- /dev/null
+++ b/public/locales/ja/video.json
@@ -0,0 +1,113 @@
+{
+ "changeSpeed": {
+ "defaultMultiplier": "ใใใฉใซใใฎไนๆฐ: 2ใฏ2ๅ้ใๆๅณใใพใ",
+ "description": "ๅ็ปใใกใคใซใฎๅ็้ๅบฆใๅคๆดใงใใพใใ้ณๅฃฐใฎๅๆใ็ถญๆใใชใใใๅ็ปใฎๅ็้ๅบฆใไธใใใไธใใใใงใใพใใๆงใ
ใช้ๅบฆ่ชฟๆดๆฉ่ฝใจไธ่ฌ็ใชๅ็ปๅฝขๅผใซๅฏพๅฟใใฆใใพใใ",
+ "inputTitle": "ๅ
ฅๅใใใช",
+ "newVideoSpeed": "ๆฐใใใใใช้ๅบฆ",
+ "resultTitle": "็ทจ้ใใใใใใช",
+ "settingSpeed": "้ๅบฆ่จญๅฎ",
+ "shortDescription": "ใใใชใฎๅ็้ๅบฆใๅคๆดใใ",
+ "title": "ใใใช้ๅบฆใฎๅคๆด",
+ "toolInfo": {
+ "title": "ไฝใงใใ {{title}}๏ผ"
+ }
+ },
+ "compress": {
+ "default": "ใใใฉใซใ",
+ "description": "ๅ็ปใ240pใ480pใ720pใชใฉใฎๆงใ
ใช่งฃๅๅบฆใซในใฑใผใชใณใฐใใฆๅง็ธฎใใพใใใใฎใใผใซใฏใ่จฑๅฎนใงใใๅ่ณชใ็ถญๆใใชใใใใกใคใซใตใคใบใ็ธฎๅฐใใใฎใซๅฝน็ซใกใพใใMP4ใWebMใOGGใชใฉใฎไธ่ฌ็ใชๅ็ปๅฝขๅผใใตใใผใใใฆใใพใใ",
+ "inputTitle": "ๅ
ฅๅใใใช",
+ "loadingText": "ใใใชใๅง็ธฎใใฆใใพใ...",
+ "lossless": "ใญในใฌใน",
+ "quality": "ๅ่ณช๏ผCRF๏ผ",
+ "resolution": "่งฃๆฑบ",
+ "resultTitle": "ๅง็ธฎใใใช",
+ "shortDescription": "ใใพใใพใช่งฃๅๅบฆใซๅใใใฆใใใชใๅง็ธฎใใ",
+ "title": "ใใใชใๅง็ธฎใใ",
+ "worst": "ๆๆช"
+ },
+ "cropVideo": {
+ "cropCoordinates": "ไฝ็ฉใฎๅบงๆจ",
+ "croppingVideo": "ใใใชใฎๅใๅใ",
+ "description": "ใใใชใใใชใใณใฐใใฆไธ่ฆใช้จๅใๅ้คใใพใใ",
+ "errorBeyondHeight": "ๅใๅใ้ ๅใใใใชใฎ้ซใใ่ถ
ใใฆๆกๅผตใใใพใ๏ผ{{height}}ใใฏใปใซ)",
+ "errorBeyondWidth": "ๅใๅใ้ ๅใใใใชใฎๅน
ใ่ถ
ใใฆใใพใ๏ผ{{width}}ใใฏใปใซ)",
+ "errorCroppingVideo": "ใใใชใฎใใชใใณใฐไธญใซใจใฉใผใ็บ็ใใพใใใใใฉใกใผใฟใจใใใชใใกใคใซใ็ขบ่ชใใฆใใ ใใใ",
+ "errorLoadingDimensions": "ใใใชใฎใตใคใบใ่ชญใฟ่พผใใพใใใงใใ",
+ "errorNonNegativeCoordinates": "XๅบงๆจใจYๅบงๆจใฏ่ฒ ใงใชใๅฟ
่ฆใใใใพใ",
+ "errorPositiveDimensions": "ๅน
ใจ้ซใใฏๆญฃใฎๆฐใงใชใใใฐใชใใพใใ",
+ "height": "่บซ้ท",
+ "inputTitle": "ๅ
ฅๅใใใช",
+ "loadVideoForDimensions": "ใใใชใใญใผใใใฆๅฏธๆณใ็ขบ่ชใใฆใใ ใใ",
+ "resultTitle": "ๅใๆใใใใใใช",
+ "shortDescription": "ไธ่ฆใช้จๅใๅ้คใใใใใซใใใชใใใชใใณใฐใใ",
+ "title": "ใใใชใใใชใใณใฐ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใจใๅ็ปใใกใคใซใใใชใใณใฐใใฆไธ่ฆใช้จๅใๅ้คใงใใพใใXใYๅบงๆจใจๅน
ใ้ซใใฎๅฏธๆณใ่จญๅฎใใใใจใงใใใชใใณใฐ้ ๅใๆๅฎใงใใพใใ",
+ "title": "ใใใชใใใชใใณใฐ"
+ },
+ "videoDimensions": "ใใใชใฎใตใคใบ: {{width}} ร {{height}} ใใฏใปใซ",
+ "videoInformation": "ใใใชๆ
ๅ ฑ",
+ "width": "ๅน
",
+ "xCoordinate": "X๏ผๅทฆ๏ผ",
+ "yCoordinate": "Y๏ผไธ๏ผ"
+ },
+ "flip": {
+ "description": "ใใใชใใกใคใซใๆฐดๅนณใพใใฏๅ็ดใซๅ่ปขใใพใใ็นๆฎๅนๆใๅใใฎๅ้กใไฟฎๆญฃใใใใใซใใใชใใใฉใผใชใณใฐใใพใใ",
+ "flippingVideo": "ๅ่ปขใใใช",
+ "horizontalLabel": "ๆฐดๅนณ๏ผใใฉใผ๏ผ",
+ "inputTitle": "ๅ
ฅๅใใใช",
+ "orientation": "ใชใชใจใณใใผใทใงใณ",
+ "resultTitle": "ๅ่ปขใใใช",
+ "shortDescription": "ใใใชใๆฐดๅนณใพใใฏๅ็ดใซๅ่ปขใใ",
+ "title": "ใใชใใใใใช",
+ "verticalLabel": "ๅ็ด๏ผ้ใใพ๏ผ"
+ },
+ "gif": {
+ "changeSpeed": {
+ "description": "GIFใขใใกใผใทใงใณใฎๅ็้ๅบฆใๅคๆดใใพใใในใ ใผใบใชใขใใกใผใทใงใณใ็ถญๆใใชใใใGIFใฎๅ็้ๅบฆใไธใใใไธใใใใงใใพใใ",
+ "shortDescription": "GIFใขใใกใผใทใงใณใฎ้ๅบฆใๅคๆดใใ",
+ "title": "GIFใฎ้ๅบฆใๅคๆดใใ"
+ }
+ },
+ "loop": {
+ "description": "ๅ
ใฎใใใชใ่คๆฐๅ็นฐใ่ฟใใฆใซใผใใใใชใไฝๆใใพใใ",
+ "inputTitle": "ๅ
ฅๅใใใช",
+ "loopingVideo": "ใซใผใใใใช",
+ "loops": "ใซใผใ",
+ "numberOfLoops": "ใซใผใๆฐ",
+ "resultTitle": "ใซใผใๅ็ป",
+ "shortDescription": "ใซใผใๅ็ปใใกใคใซใไฝๆใใ",
+ "title": "ใซใผใใใใช",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใฐใๅ
ใฎๅ็ปใ่คๆฐๅ็นฐใ่ฟใๅ็ใใใใจใงใใซใผใๅ็ปใไฝๆใงใใพใใๅ็ปใใซใผใใใใๅๆฐใๆๅฎใงใใพใใ",
+ "title": "ไฝใงใใ {{title}}๏ผ"
+ }
+ },
+ "rotate": {
+ "180Degrees": "180ยฐ๏ผไธไธ้ใใพ๏ผ",
+ "270Degrees": "270ยฐ๏ผๅๆ่จๅใ90ยฐ๏ผ",
+ "90Degrees": "90ยฐๆ่จๅใ",
+ "description": "ใใใชใใกใคใซใ90ๅบฆใ180ๅบฆใใพใใฏ270ๅบฆๅ่ปขใงใใพใใๆญฃ็ขบใชๅ่ปขๅถๅพกใซใใใใใใชใฎๅใใไฟฎๆญฃใใใใ็นๆฎๅนๆใไฝๆใใใใงใใพใใ",
+ "inputTitle": "ๅ
ฅๅใใใช",
+ "resultTitle": "ๅ่ปขใใใใใช",
+ "rotatingVideo": "ๅ่ปขใใใใใช",
+ "rotation": "ๅ่ปข",
+ "shortDescription": "ๆๅฎใใ่งๅบฆใงใใใชใๅ่ปขใใ",
+ "title": "ใใใชใๅ่ปขใใ"
+ },
+ "trim": {
+ "description": "้ๅงๆ้ใจ็ตไบๆ้ใๆๅฎใใฆใใใชใใกใคใซใใใชใใณใฐใใพใใใใใชใฎๅ
้ ญใพใใฏๆซๅฐพใฎไธ่ฆใช้จๅใๅ้คใใพใใ",
+ "endTime": "็ตไบๆ้",
+ "inputTitle": "ๅ
ฅๅใใใช",
+ "resultTitle": "ใใชใใณใฐใใใใใใช",
+ "shortDescription": "ไธ่ฆใช้จๅใๅ้คใใฆใใใชใใใชใใณใฐใใ",
+ "startTime": "้ๅงๆ้",
+ "timestamps": "ใฟใคใ ในใฟใณใ",
+ "title": "ใใใชใใใชใ ใใ"
+ },
+ "videoToGif": {
+ "description": "ใใใชใใกใคใซใใขใใกใผใทใงใณGIFๅฝขๅผใซๅคๆใใพใใ็นๅฎใฎๆ้็ฏๅฒใๆฝๅบใใๅ
ฑๆๅฏ่ฝใชใขใใกใผใทใงใณ็ปๅใไฝๆใใพใใ",
+ "shortDescription": "ใใใชใใขใใกใผใทใงใณGIFใซๅคๆใใ",
+ "title": "ใใใชใGIFใซๅคๆ"
+ }
+}
diff --git a/public/locales/ja/xml.json b/public/locales/ja/xml.json
new file mode 100644
index 0000000..42dd3c2
--- /dev/null
+++ b/public/locales/ja/xml.json
@@ -0,0 +1,38 @@
+{
+ "xmlBeautifier": {
+ "description": "้ฉๅใชใคใณใใณใใจในใใผในใไฝฟ็จใใฆ XML ใใใฉใผใใใใใพใใ",
+ "indentation": "ใคใณใใณใ",
+ "inputTitle": "ๅ
ฅๅXML",
+ "resultTitle": "็พๅใใใXML",
+ "shortDescription": "XML ใณใผใใใใฉใผใใใใใฆ็พใใใใ",
+ "title": "XML ็พๅใใผใซ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟ็จใใใจใ้ฉๅใชใคใณใใณใใจ้้ใง XML ใใผใฟใใใฉใผใใใใงใใใใใ่ชญใฟใใใใๆไฝใใใใใชใใพใใ",
+ "title": "XML ็พๅใใผใซ"
+ },
+ "useSpaces": "ในใใผในใไฝฟ็จใใ",
+ "useSpacesDescription": "ในใใผในใงๅบๅใใคใณใใณใใใ",
+ "useTabs": "ใฟใใไฝฟ็จใใ",
+ "useTabsDescription": "ๅบๅใใฟใใงใคใณใใณใใใพใใ"
+ },
+ "xmlValidator": {
+ "description": "XML ๆงๆใจๆง้ ใๆค่จผใใพใใ",
+ "placeholder": "ใใใซ XML ใ่ฒผใไปใใใใคใณใใผใใใพใ...",
+ "shortDescription": "XMLใณใผใใฎใจใฉใผใๆค่จผใใ",
+ "title": "XMLใใชใใผใฟ",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟใใจใXMLใฎๆงๆใจๆง้ ใๆค่จผใงใใพใใXMLใๆดๅฝขๅผใงใใใใฉใใใ็ขบ่ชใใๅ้กใ่ฆใคใใฃใๅ ดๅใฏ่ฉณ็ดฐใชใจใฉใผใกใใปใผใธใ่กจ็คบใใพใใ",
+ "title": "XMLใใชใใผใฟ"
+ }
+ },
+ "xmlViewer": {
+ "description": "XML ๆง้ ใใใชใผๅฝขๅผใง่กจ็คบใใใณๆข็ดขใใพใใ",
+ "inputTitle": "ๅ
ฅๅXML",
+ "resultTitle": "XMLใใชใผใใฅใผ",
+ "title": "XMLใใฅใผใข",
+ "toolInfo": {
+ "description": "ใใฎใใผใซใไฝฟ็จใใใจใXML ใใผใฟใ้ๅฑคใใชใผๅฝขๅผใง่กจ็คบใงใใใใใXML ใใญใฅใกใณใใฎๆง้ ใ็ฐกๅใซ่ชฟๆปใใฆ็่งฃใงใใใใใซใชใใพใใ",
+ "title": "XMLใใฅใผใข"
+ }
+ }
+}
diff --git a/public/locales/nl/audio.json b/public/locales/nl/audio.json
new file mode 100644
index 0000000..3967aec
--- /dev/null
+++ b/public/locales/nl/audio.json
@@ -0,0 +1,42 @@
+{
+ "changeSpeed": {
+ "description": "Wijzig de afspeelsnelheid van audiobestanden. Versnel of vertraag audio met behoud van toonhoogte.",
+ "inputTitle": "Invoer audio",
+ "newAudioSpeed": "Nieuwe audiosnelheid",
+ "outputFormat": "Uitvoerformaat",
+ "resultTitle": "Bewerkte audio",
+ "settingSpeed": "Snelheid instellen",
+ "shortDescription": "De snelheid van audiobestanden wijzigen",
+ "speedDescription": "Standaardvermenigvuldiger: 2 betekent 2x sneller",
+ "title": "Wijzig audiosnelheid",
+ "toolInfo": {
+ "title": "Wat is {{title}}?"
+ }
+ },
+ "extractAudio": {
+ "description": "Haal een audiotrack uit videobestanden.",
+ "extractingAudio": "Audio extraheren",
+ "inputTitle": "Invoervideo",
+ "outputFormat": "Uitvoerformaat",
+ "outputFormatDescription": "Selecteer het formaat waarin u de audio wilt extraheren.",
+ "resultTitle": "Geรซxtraheerde audio",
+ "shortDescription": "Extraheer audio uit videobestanden (MP4, MOV, enz.) naar AAC, MP3 of WAV.",
+ "title": "Audio uit video extraheren",
+ "toolInfo": {
+ "description": "Met deze tool kun je de audiotrack uit videobestanden halen. Je kunt kiezen uit verschillende audioformaten, waaronder AAC, MP3 en WAV.",
+ "title": "Wat is {{title}}?"
+ }
+ },
+ "mergeAudio": {
+ "description": "Combineer meerdere audiobestanden tot รฉรฉn audiobestand door ze in volgorde te plaatsen.",
+ "longDescription": "Met deze tool kun je meerdere audiobestanden samenvoegen tot รฉรฉn bestand door ze te combineren in de volgorde waarin je ze uploadt. Perfect voor het combineren van podcastfragmenten, muzieknummers of andere audiobestanden die moeten worden samengevoegd. Ondersteunt diverse audioformaten, waaronder MP3, AAC en WAV.",
+ "shortDescription": "Voeg meerdere audiobestanden samen tot รฉรฉn bestand (MP3, AAC, WAV).",
+ "title": "Audio samenvoegen"
+ },
+ "trim": {
+ "description": "Knip en trim audiobestanden om specifieke segmenten te extraheren door start- en eindtijden op te geven.",
+ "longDescription": "Met deze tool kun je audiobestanden inkorten door de begin- en eindtijd op te geven. Je kunt specifieke segmenten uit langere audiobestanden halen, ongewenste delen verwijderen of kortere clips maken. Ondersteunt diverse audioformaten, waaronder MP3, AAC en WAV. Perfect voor podcastbewerking, muziekproductie of andere audiobewerkingsbehoeften.",
+ "shortDescription": "Trim audiobestanden om specifieke tijdssegmenten te extraheren (MP3, AAC, WAV).",
+ "title": "Audio bijsnijden"
+ }
+}
diff --git a/public/locales/nl/csv.json b/public/locales/nl/csv.json
new file mode 100644
index 0000000..9a43017
--- /dev/null
+++ b/public/locales/nl/csv.json
@@ -0,0 +1,114 @@
+{
+ "changeCsvSeparator": {
+ "description": "Wijzig het scheidingsteken in CSV-bestanden. Converteer tussen verschillende CSV-formaten, zoals komma's, puntkomma's, tabs of aangepaste scheidingstekens.",
+ "shortDescription": "Wijzig het scheidingsteken van CSV-bestanden",
+ "title": "CSV-scheidingsteken wijzigen"
+ },
+ "csvRowsToColumns": {
+ "description": "Deze tool converteert rijen van een CSV-bestand (Comma Separated Values) naar kolommen. De horizontale regels worden รฉรฉn voor รฉรฉn uit het invoerbestand (CSV) gehaald, 90 graden gedraaid en als verticale kolommen, gescheiden door komma's, na elkaar weergegeven.', longDescription: 'Deze tool converteert rijen van een CSV-bestand (Comma Separated Values) naar kolommen. Als de invoergegevens bijvoorbeeld 6 rijen bevatten, bevat de uitvoer 6 kolommen en worden de elementen van de rijen van boven naar beneden gerangschikt. In een correct opgemaakte CSV is het aantal waarden in elke rij hetzelfde. Wanneer er echter velden in rijen ontbreken, kan het programma deze herstellen en kunt u kiezen uit de beschikbare opties: ontbrekende gegevens vullen met lege elementen of ontbrekende gegevens vervangen door aangepaste elementen, zoals \"ontbrekend\", \"?\" of \"x\". Tijdens het conversieproces verwijdert de tool ook onnodige informatie uit het CSV-bestand, zoals lege regels (dit zijn regels zonder zichtbare informatie) en opmerkingen. Om de tool te helpen opmerkingen correct te identificeren, kunt u in de opties het symbool opgeven aan het begin van een regel waarmee een opmerking begint. Dit symbool is meestal een hekje \"#\" of een dubbele slash \"//\". Csv-abulous!",
+ "longDescription": "Deze tool converteert rijen van een CSV-bestand (Comma Separated Values) naar kolommen. Als de invoergegevens in CSV-formaat bijvoorbeeld 6 rijen bevatten, heeft de uitvoer 6 kolommen en worden de elementen van de rijen van boven naar beneden gerangschikt. In een correct opgemaakte CSV is het aantal waarden in elke rij hetzelfde. Wanneer er echter velden in rijen ontbreken, kan het programma deze herstellen en kunt u kiezen uit de beschikbare opties: ontbrekende gegevens vullen met lege elementen of ontbrekende gegevens vervangen door aangepaste elementen, zoals",
+ "shortDescription": "Converteer CSV-rijen naar kolommen.",
+ "title": "CSV-rijen naar kolommen converteren"
+ },
+ "csvToJson": {
+ "columnSeparator": "Kolomscheidingsteken (bijv. , ; \\t)",
+ "commentSymbol": "Commentaarsymbool (bijv. #)",
+ "conversionOptions": "Conversie-opties",
+ "description": "Converteer CSV-bestanden naar JSON-formaat met aanpasbare opties voor scheidingstekens, aanhalingstekens en uitvoeropmaak. Ondersteuning voor kopteksten, opmerkingen en dynamische typeconversie.",
+ "dynamicTypes": "Dynamische typen",
+ "dynamicTypesDescription": "Automatisch getallen en Booleaanse waarden converteren",
+ "errorParsing": "Fout bij het parseren van CSV: {{error}}",
+ "fieldQuote": "Veldcitaat (bijv. \")",
+ "inputCsvFormat": "CSV-invoerformaat",
+ "inputTitle": "CSV-invoer",
+ "resultTitle": "Uitvoer JSON",
+ "shortDescription": "Converteer CSV-gegevens naar JSON-formaat.",
+ "skipEmptyLines": "Lege regels overslaan",
+ "skipEmptyLinesDescription": "Negeer lege regels in de invoer-CSV",
+ "title": "CSV naar JSON converteren",
+ "useHeaders": "Gebruik headers",
+ "useHeadersDescription": "Behandel de eerste rij als kolomkoppen"
+ },
+ "csvToTsv": {
+ "description": "Upload uw CSV-bestand via onderstaand formulier en het wordt automatisch omgezet naar een TSV-bestand. In de toolopties kunt u het CSV-invoerformaat aanpassen: geef het veldscheidingsteken, het aanhalingsteken en het commentaarsymbool op, sla lege CSV-regels over en kies of u CSV-kolomkoppen wilt behouden.",
+ "longDescription": "Deze tool zet Comma Separated Values (CSV)-gegevens om in Tab Separated Values (TSV). Zowel CSV als TSV zijn populaire bestandsformaten voor het opslaan van tabelgegevens, maar ze gebruiken verschillende scheidingstekens om waarden te scheiden. CSV gebruikt komma's (",
+ "shortDescription": "Converteer CSV-gegevens naar TSV-formaat.",
+ "title": "CSV naar TSV converteren"
+ },
+ "csvToXml": {
+ "description": "Converteer CSV-bestanden naar XML-formaat met aanpasbare opties.",
+ "shortDescription": "Converteer CSV-gegevens naar XML-formaat.",
+ "title": "CSV naar XML converteren"
+ },
+ "csvToYaml": {
+ "description": "Upload uw CSV-bestand via onderstaand formulier en het wordt automatisch omgezet naar een YAML-bestand. In de toolopties kunt u het scheidingsteken voor velden, het aanhalingsteken voor velden en het commentaarteken opgeven om de tool aan te passen aan aangepaste CSV-indelingen. Daarnaast kunt u de uitvoer-YAML-indeling selecteren: een indeling die CSV-headers behoudt of een indeling die CSV-headers uitsluit.",
+ "longDescription": "Deze tool transformeert CSV-gegevens (Comma Separated Values) naar YAML-gegevens (Yet Another Markup Language). CSV is een eenvoudig tabelformaat dat wordt gebruikt om matrixachtige gegevenstypen weer te geven die bestaan uit rijen en kolommen. YAML daarentegen is een geavanceerder formaat (eigenlijk een superset van JSON), dat beter leesbare gegevens voor serialisatie genereert en lijsten, woordenboeken en geneste objecten ondersteunt. Dit programma ondersteunt verschillende CSV-invoerformaten: de invoergegevens kunnen door komma's (standaard), door puntkomma's, door slierten of een ander scheidingsteken worden gescheiden. U kunt het exacte scheidingsteken dat uw gegevens gebruiken in de opties opgeven. Op dezelfde manier kunt u in de opties het aanhalingsteken opgeven dat wordt gebruikt om CSV-velden in te sluiten (standaard een dubbel aanhalingsteken). U kunt ook regels overslaan die beginnen met opmerkingen door de opmerkingsymbolen in de opties op te geven. Zo houdt u uw gegevens overzichtelijk door onnodige regels over te slaan. Er zijn twee manieren om CSV naar YAML te converteren. De eerste methode converteert elke CSV-rij naar een YAML-lijst. De tweede methode extraheert headers uit de eerste CSV-rij en creรซert YAML-objecten met sleutels op basis van deze headers. U kunt de YAML-uitvoer ook aanpassen door het aantal spaties voor inspringing van YAML-structuren op te geven. Als u de omgekeerde conversie wilt uitvoeren, dat wil zeggen YAML naar CSV wilt converteren, kunt u onze tool YAML naar CSV converteren gebruiken. Csv-abulous!",
+ "shortDescription": "Converteer snel een CSV-bestand naar een YAML-bestand.",
+ "title": "CSV naar YAML converteren"
+ },
+ "findIncompleteCsvRecords": {
+ "checkingOptions": "Opties controleren",
+ "commentCharacterDescription": "Voer het teken in dat het begin van een commentaarregel aangeeft. Regels die met dit symbool beginnen, worden overgeslagen.",
+ "csvInputOptions": "CSV-invoeropties",
+ "csvSeparatorDescription": "Voer het teken in dat gebruikt wordt om kolommen in het CSV-invoerbestand te scheiden.",
+ "deleteLinesWithNoData": "Regels zonder gegevens verwijderen",
+ "deleteLinesWithNoDataDescription": "Verwijder lege regels uit het CSV-invoerbestand.",
+ "description": "Upload uw CSV-bestand via onderstaand formulier en deze tool controleert automatisch of er geen waarden in de rijen of kolommen ontbreken. In de toolopties kunt u de opmaak van het invoerbestand aanpassen (het scheidingsteken, de aanhalingstekens en het commentaarteken opgeven). Daarnaast kunt u de controle op lege waarden inschakelen, lege regels overslaan en een limiet instellen voor het aantal foutmeldingen in de uitvoer.",
+ "findEmptyValues": "Lege waarden zoeken",
+ "findEmptyValuesDescription": "Geef een bericht weer over lege CSV-velden (dit zijn geen ontbrekende velden, maar velden die niets bevatten).",
+ "inputTitle": "CSV-invoer",
+ "limitNumberOfMessages": "Beperk het aantal berichten",
+ "messageLimitDescription": "Stel de limiet in voor het aantal berichten in de uitvoer.",
+ "quoteCharacterDescription": "Voer het aanhalingsteken in dat u wilt gebruiken om de CSV-invoervelden te citeren.",
+ "resultTitle": "CSV-status",
+ "shortDescription": "Vind snel rijen en kolommen in CSV waar waarden ontbreken.",
+ "title": "Onvolledige CSV-records vinden",
+ "toolInfo": {
+ "title": "Wat is een {{title}}?"
+ }
+ },
+ "insertCsvColumns": {
+ "appendColumns": "Kolommen toevoegen",
+ "commentCharacterDescription": "Voer het teken in dat het begin van een commentaarregel aangeeft. Regels die met dit symbool beginnen, worden overgeslagen.",
+ "csvOptions": "CSV-opties",
+ "csvSeparator": "CSV-scheidingsteken",
+ "csvToInsert": "CSV om in te voegen",
+ "csvToInsertDescription": "Voer een of meer kolommen in die u in het CSV-bestand wilt invoegen. Het teken dat wordt gebruikt om kolommen te scheiden, moet hetzelfde zijn als het teken in het CSV-invoerbestand. Let op: lege regels worden genegeerd.",
+ "customFillDescription": "Als het invoer-CSV-bestand niet compleet is (ontbrekende waarden), kunt u dan lege velden of aangepaste symbolen aan de records toevoegen om een goed opgemaakte CSV te maken?",
+ "customFillValueDescription": "Gebruik deze aangepaste waarde om ontbrekende velden in te vullen. (Werkt alleen met de modus 'Aangepaste waarden' hierboven.)",
+ "customPosition": "Aangepaste positie",
+ "customPositionOptionsDescription": "Selecteer de methode om de kolommen in het CSV-bestand in te voegen.",
+ "description": "Voeg nieuwe kolommen toe aan CSV-gegevens op de opgegeven posities.",
+ "fillWithCustomValues": "Vul met douanewaarden",
+ "fillWithEmptyValues": "Vullen met lege waarden",
+ "headerName": "Koptekstnaam",
+ "headerNameDescription": "Koptekst van de kolom waarna u kolommen wilt invoegen.",
+ "inputTitle": "CSV-invoer",
+ "insertingPositionDescription": "Geef aan waar de kolommen in het CSV-bestand moeten worden ingevoegd.",
+ "position": "Positie",
+ "positionOptions": "Positieopties",
+ "prependColumns": "Kolommen vooraf toevoegen",
+ "quoteCharDescription": "Voer het aanhalingsteken in dat u wilt gebruiken om de CSV-invoervelden te citeren.",
+ "resultTitle": "CSV-uitvoer",
+ "rowNumberDescription": "Nummer van de kolom waarna u kolommen wilt invoegen.",
+ "separatorDescription": "Voer het teken in dat gebruikt wordt om kolommen in het CSV-invoerbestand te scheiden.",
+ "shortDescription": "Voeg snel een of meer nieuwe kolommen in, waar dan ook in een CSV-bestand.",
+ "title": "CSV-kolommen invoegen",
+ "toolInfo": {
+ "description": "Met deze tool kunt u nieuwe kolommen op specifieke posities in CSV-gegevens invoegen. U kunt kolommen op aangepaste posities voorvoegen, toevoegen of invoegen op basis van koptekstnamen of kolomnummers.",
+ "title": "CSV-kolommen invoegen"
+ }
+ },
+ "swapCsvColumns": {
+ "description": "Upload uw CSV-bestand via het onderstaande formulier, geef aan welke kolommen u wilt omwisselen en de tool wijzigt automatisch de posities van de opgegeven kolommen in het uitvoerbestand. In de toolopties kunt u de kolomposities of -namen opgeven die u wilt omwisselen, onvolledige gegevens corrigeren en optioneel lege records en uitgeschakelde records verwijderen.",
+ "longDescription": "Deze tool reorganiseert CSV-gegevens door de posities van de kolommen om te wisselen. Het omwisselen van kolommen kan de leesbaarheid van een CSV-bestand verbeteren door veelgebruikte gegevens samen of vooraan te plaatsen, voor eenvoudigere gegevensvergelijking en -bewerking. U kunt bijvoorbeeld de eerste kolom omwisselen met de laatste of de tweede kolom met de derde. Om kolommen op basis van hun positie om te wisselen, selecteert u",
+ "shortDescription": "CSV-kolommen opnieuw ordenen.",
+ "title": "CSV-kolommen verwisselen"
+ },
+ "transposeCsv": {
+ "description": "Upload uw CSV-bestand via onderstaand formulier en deze tool transponeert uw CSV-bestand automatisch. In de toolopties kunt u het teken opgeven waarmee de commentaarregels in het CSV-bestand beginnen om ze te verwijderen. Als het CSV-bestand onvolledig is (ontbrekende waarden), kunt u de ontbrekende waarden vervangen door het lege teken of een aangepast teken.",
+ "longDescription": "Deze tool transponeert Comma Separated Values (CSV). Het behandelt de CSV als een matrix met data en draait alle elementen om over de hoofddiagonaal. De uitvoer bevat dezelfde CSV-data als de invoer, maar nu zijn alle rijen kolommen en alle kolommen rijen geworden. Na transpositie heeft het CSV-bestand tegengestelde afmetingen. Als het invoerbestand bijvoorbeeld 4 kolommen en 3 rijen heeft, heeft het uitvoerbestand 3 kolommen en 4 rijen. Tijdens de conversie zuivert het programma de data ook van onnodige regels en corrigeert het onvolledige data. De tool verwijdert automatisch alle lege records en opmerkingen die beginnen met een specifiek teken, dat u in de optie kunt instellen. Bovendien, in gevallen waarin de CSV-data beschadigd of verloren zijn, vult het hulpprogramma het bestand aan met lege velden of aangepaste velden die u in de opties kunt opgeven. Csv-abulous!",
+ "shortDescription": "Snel een CSV-bestand transponeren.",
+ "title": "CSV transponeren"
+ }
+}
diff --git a/public/locales/nl/image.json b/public/locales/nl/image.json
new file mode 100644
index 0000000..145b0a8
--- /dev/null
+++ b/public/locales/nl/image.json
@@ -0,0 +1,98 @@
+{
+ "changeColors": {
+ "description": "Wereld",
+ "shortDescription": "Snel kleuren in een afbeelding verwisselen",
+ "title": "Kleuren in afbeelding wijzigen"
+ },
+ "changeOpacity": {
+ "description": "Pas de transparantie van je afbeeldingen eenvoudig aan. Upload je afbeelding, gebruik de schuifbalk om de gewenste dekking in te stellen tussen 0 (volledig transparant) en 1 (volledig ondoorzichtig) en download de aangepaste afbeelding.",
+ "shortDescription": "Pas de transparantie van afbeeldingen aan",
+ "title": "Afbeeldingsdekking wijzigen"
+ },
+ "compress": {
+ "description": "Verklein de bestandsgrootte van een afbeelding, maar behoud de kwaliteit.",
+ "inputTitle": "Invoerafbeelding",
+ "resultTitle": "Gecomprimeerde afbeelding",
+ "shortDescription": "Comprimeer afbeeldingen om de bestandsgrootte te verkleinen, maar zorg er wel voor dat de kwaliteit redelijk blijft.",
+ "title": "Afbeelding comprimeren"
+ },
+ "compressPng": {
+ "description": "Dit is een programma dat PNG-afbeeldingen comprimeert. Zodra u uw PNG-afbeelding in het invoerveld plakt, comprimeert het programma deze en toont het resultaat in het uitvoerveld. In de opties kunt u het compressieniveau aanpassen en de oude en nieuwe bestandsgroottes van de afbeeldingen vinden.",
+ "shortDescription": "Snel een PNG comprimeren",
+ "title": "PNG comprimeren"
+ },
+ "convertJgpToPng": {
+ "description": "Converteer je JPG-afbeeldingen snel naar PNG. Importeer je PNG-afbeelding in de editor aan de linkerkant.",
+ "shortDescription": "Converteer uw JPG-afbeeldingen snel naar PNG",
+ "title": "JPG naar PNG converteren"
+ },
+ "convertToJpg": {
+ "description": "Converteer verschillende afbeeldingsformaten (PNG, GIF, TIF, PSD, SVG, WEBP, HEIC, RAW) naar JPG met aanpasbare instellingen voor de kwaliteit en achtergrondkleur.",
+ "shortDescription": "Converteer afbeeldingen naar JPG met kwaliteitscontrole",
+ "title": "Afbeeldingen naar JPG converteren"
+ },
+ "createTransparent": {
+ "description": "Wereld",
+ "shortDescription": "Snel een afbeelding transparant maken",
+ "title": "Transparante PNG maken"
+ },
+ "crop": {
+ "description": "Snijd afbeeldingen bij om ongewenste delen te verwijderen.",
+ "inputTitle": "Invoerafbeelding",
+ "resultTitle": "Bijgesneden afbeelding",
+ "shortDescription": "Snel afbeeldingen bijsnijden.",
+ "title": "Afbeelding bijsnijden"
+ },
+ "editor": {
+ "description": "Geavanceerde beeldbewerker met tools voor bijsnijden, roteren, annoteren, kleuren aanpassen en watermerken toevoegen. Bewerk je afbeeldingen met professionele tools rechtstreeks in je browser.",
+ "shortDescription": "Bewerk afbeeldingen met geavanceerde tools en functies",
+ "title": "Afbeeldingseditor"
+ },
+ "imageToText": {
+ "description": "Extraheer tekst uit afbeeldingen (JPG, PNG) met behulp van optische tekenherkenning (OCR).",
+ "shortDescription": "Tekst uit afbeeldingen extraheren met OCR.",
+ "title": "Afbeelding naar tekst (OCR)"
+ },
+ "qrCode": {
+ "description": "Genereer QR-codes voor verschillende gegevenstypen: URL, tekst, e-mail, telefoon, sms, wifi, vCard en meer.",
+ "shortDescription": "Maak aangepaste QR-codes voor verschillende gegevensformaten.",
+ "title": "QR-codegenerator"
+ },
+ "removeBackground": {
+ "description": "Wereld",
+ "shortDescription": "Achtergronden automatisch uit afbeeldingen verwijderen",
+ "title": "Achtergrond uit afbeelding verwijderen"
+ },
+ "resize": {
+ "description": "Afbeeldingen aanpassen naar verschillende afmetingen.",
+ "dimensionType": "Dimensietype",
+ "heightDescription": "Hoogte (in pixels)",
+ "inputTitle": "Invoerafbeelding",
+ "maintainAspectRatio": "Beeldverhouding behouden",
+ "maintainAspectRatioDescription": "Behoud de originele beeldverhouding van de afbeelding.",
+ "percentage": "Percentage",
+ "percentageDescription": "Percentage van de oorspronkelijke grootte (bijv. 50 voor halve grootte, 200 voor dubbele grootte)",
+ "resizeByPercentage": "Formaat wijzigen met percentage",
+ "resizeByPercentageDescription": "U kunt de grootte wijzigen door een percentage van de oorspronkelijke grootte op te geven.",
+ "resizeByPixels": "Formaat wijzigen met pixels",
+ "resizeByPixelsDescription": "U kunt het formaat wijzigen door de afmetingen in pixels op te geven.",
+ "resizeMethod": "Methode voor het wijzigen van de grootte",
+ "resultTitle": "Afbeelding met gewijzigd formaat",
+ "setHeight": "Hoogte instellen",
+ "setHeightDescription": "Geef de hoogte op in pixels en bereken de breedte op basis van de beeldverhouding.",
+ "setWidth": "Breedte instellen",
+ "setWidthDescription": "Geef de breedte op in pixels en bereken de hoogte op basis van de beeldverhouding.",
+ "shortDescription": "U kunt de grootte van afbeeldingen eenvoudig aanpassen.",
+ "title": "Afbeelding formaat wijzigen",
+ "toolInfo": {
+ "description": "Met deze tool kun je de grootte van JPG-, PNG-, SVG- of GIF-afbeeldingen aanpassen. Je kunt de grootte aanpassen door de afmetingen in pixels of percentages op te geven, met opties om de oorspronkelijke beeldverhouding te behouden.",
+ "title": "Afbeelding formaat wijzigen"
+ },
+ "widthDescription": "Breedte (in pixels)"
+ },
+ "rotate": {
+ "description": "Draai een afbeelding met een bepaalde hoek.",
+ "shortDescription": "Draai een afbeelding eenvoudig.",
+ "title": "Afbeelding roteren"
+ }
+}
diff --git a/public/locales/nl/json.json b/public/locales/nl/json.json
new file mode 100644
index 0000000..1fa6fe4
--- /dev/null
+++ b/public/locales/nl/json.json
@@ -0,0 +1,62 @@
+{
+ "escapeJson": {
+ "description": "Escape speciale tekens in JSON-strings. Converteer JSON-gegevens naar een correct geรซscapete indeling voor veilige overdracht of opslag.",
+ "shortDescription": "Speciale tekens in JSON ontsnappen",
+ "title": "Ontsnappen aan JSON"
+ },
+ "jsonToXml": {
+ "description": "Converteer JSON-gegevens naar XML-formaat. Transformeer gestructureerde JSON-objecten naar correct vormgegeven XML-documenten.",
+ "shortDescription": "Converteer JSON naar XML-formaat",
+ "title": "JSON naar XML"
+ },
+ "minify": {
+ "description": "Verwijder alle onnodige witruimte uit JSON.",
+ "inputTitle": "Invoer JSON",
+ "resultTitle": "Geminimaliseerde JSON",
+ "shortDescription": "Verklein JSON door witruimte te verwijderen",
+ "title": "JSON verkleinen",
+ "toolInfo": {
+ "description": "JSON-minificatie is het proces waarbij alle onnodige witruimte uit JSON-gegevens wordt verwijderd, terwijl de geldigheid ervan behouden blijft. Dit omvat het verwijderen van spaties, nieuwe regels en inspringingen die niet nodig zijn voor een correcte parsering van de JSON. Minificatie verkleint de grootte van JSON-gegevens, waardoor deze efficiรซnter worden opgeslagen en verzonden, met behoud van exact dezelfde datastructuur en waarden.",
+ "title": "Wat is JSON-minificatie?"
+ }
+ },
+ "prettify": {
+ "description": "Formatteer JSON met de juiste inspringing en spatie.",
+ "indentation": "Inspringing",
+ "inputTitle": "Invoer JSON",
+ "resultTitle": "Verfraaide JSON",
+ "shortDescription": "JSON-code opmaken en verfraaien",
+ "title": "JSON verfraaien",
+ "toolInfo": {
+ "description": "Met deze tool kunt u JSON-gegevens opmaken met de juiste inspringing en spaties, waardoor ze beter leesbaar en eenvoudiger te gebruiken zijn.",
+ "title": "JSON verfraaien"
+ },
+ "useSpaces": "Gebruik spaties",
+ "useSpacesDescription": "Uitvoer inspringen met spaties",
+ "useTabs": "Tabbladen gebruiken",
+ "useTabsDescription": "Uitvoer inspringen met tabs."
+ },
+ "stringify": {
+ "description": "Converteer JavaScript-objecten naar JSON-stringformaat. Serialiseer datastructuren naar JSON-strings voor opslag of verzending.",
+ "shortDescription": "Objecten converteren naar JSON-string",
+ "title": "Stringify JSON"
+ },
+ "tsvToJson": {
+ "description": "Converteer TSV-gegevens (Tab-Separated Values) naar JSON-formaat. Transformeer tabelgegevens naar gestructureerde JSON-objecten.",
+ "shortDescription": "Converteer TSV naar JSON-formaat",
+ "title": "TSV naar JSON"
+ },
+ "validateJson": {
+ "description": "Controleer of JSON geldig en correct is geformuleerd.",
+ "inputTitle": "Invoer JSON",
+ "invalidJson": "โ {{error}}",
+ "resultTitle": "Validatieresultaat",
+ "shortDescription": "Valideer JSON-code op fouten",
+ "title": "Valideer JSON",
+ "toolInfo": {
+ "description": "JSON (JavaScript Object Notation) is een lichtgewicht formaat voor gegevensuitwisseling. JSON-validatie zorgt ervoor dat de structuur van de gegevens voldoet aan de JSON-standaard. Een geldig JSON-object moet het volgende bevatten: - Eigenschapsnamen tussen dubbele aanhalingstekens. - Correct gebalanceerde accolades {}. - Geen afsluitende komma's na het laatste sleutel-waardepaar. - Correcte nesting van objecten en arrays. Deze tool controleert de invoer-JSON en geeft feedback om veelvoorkomende fouten te identificeren en te verhelpen.",
+ "title": "Wat is JSON-validatie?"
+ },
+ "validJson": "โ
Geldige JSON"
+ }
+}
diff --git a/public/locales/nl/list.json b/public/locales/nl/list.json
new file mode 100644
index 0000000..ae2f1ee
--- /dev/null
+++ b/public/locales/nl/list.json
@@ -0,0 +1,208 @@
+{
+ "duplicate": {
+ "concatenate": "Concateneren",
+ "concatenateDescription": "Kopieรซn samenvoegen (indien niet aangevinkt, worden de items verweven)",
+ "copyDescription": "Aantal kopieรซn (kan fractioneel zijn)",
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het dupliceren van lijstitems. Voer uw lijst in en specificeer duplicatiecriteria om kopieรซn van items te maken. Perfect voor data-uitbreiding, testen of het creรซren van herhaalde patronen.",
+ "duplicationOptions": "Duplicatieopties",
+ "examples": {
+ "fractional": {
+ "description": "Dit voorbeeld laat zien hoe u een lijst kunt dupliceren met een fractioneel aantal kopieรซn.",
+ "title": "Fractionele duplicatie"
+ },
+ "interweave": {
+ "description": "Dit voorbeeld laat zien hoe u items kunt verweven in plaats van aaneenschakelen.",
+ "title": "Verweven items"
+ },
+ "reverse": {
+ "description": "Dit voorbeeld laat zien hoe u een lijst in omgekeerde volgorde kunt dupliceren.",
+ "title": "Omgekeerde duplicatie"
+ },
+ "simple": {
+ "description": "Dit voorbeeld laat zien hoe u een lijst met woorden kunt dupliceren.",
+ "title": "Eenvoudige duplicatie"
+ }
+ },
+ "inputTitle": "Invoerlijst",
+ "joinSeparatorDescription": "Scheidingsteken om de gedupliceerde lijst samen te voegen",
+ "resultTitle": "Gedupliceerde lijst",
+ "reverse": "Achteruit",
+ "reverseDescription": "Draai de gedupliceerde items om",
+ "shortDescription": "Dubbele lijstitems met opgegeven criteria",
+ "splitByRegex": "Gesplitst door reguliere expressie",
+ "splitBySymbol": "Gesplitst op symbool",
+ "splitOptions": "Gesplitste opties",
+ "splitSeparatorDescription": "Scheidingsteken om de lijst te splitsen",
+ "title": "Duplicaat",
+ "toolInfo": {
+ "description": "Met deze tool kunt u items in een lijst dupliceren. U kunt het aantal kopieรซn (inclusief fractionele waarden) opgeven, bepalen of items worden samengevoegd of verweven, en zelfs de gedupliceerde items omkeren. Dit is handig voor het creรซren van herhaalde patronen, het genereren van testgegevens of het uitbreiden van lijsten met voorspelbare inhoud.",
+ "title": "Lijstduplicatie"
+ }
+ },
+ "findMostPopular": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde tool om de populairste items in een lijst te vinden. Voer je lijst in en krijg direct de items die het vaakst voorkomen. Perfect voor data-analyse, trendidentificatie of het vinden van gemeenschappelijke elementen.",
+ "shortDescription": "Vind de meest voorkomende items",
+ "title": "Vind de meest populaire"
+ },
+ "findUnique": {
+ "caseSensitiveItems": "Hoofdlettergevoelige items",
+ "caseSensitiveItemsDescription": "Geef items met verschillende hoofdletters/kleine letters weer als unieke elementen in de lijst.",
+ "delimiterDescription": "Stel een scheidingsteken of reguliere expressie in.",
+ "description": "'s Werelds eenvoudigste browsergebaseerde tool voor het vinden van unieke items in een lijst. Voer uw lijst in en ontvang direct alle unieke waarden, inclusief verwijderde duplicaten. Perfect voor dataopschoning, deduplicatie of het vinden van afzonderlijke elementen.",
+ "findAbsolutelyUniqueItems": "Vind absoluut unieke items",
+ "findAbsolutelyUniqueItemsDescription": "Geef alleen die items van de lijst weer die in รฉรฉn exemplaar aanwezig zijn.",
+ "inputListDelimiter": "Invoerlijst scheidingsteken",
+ "inputTitle": "Invoerlijst",
+ "outputListDelimiter": "Uitvoerlijstscheidingsteken",
+ "resultTitle": "Unieke items",
+ "shortDescription": "Vind unieke items in een lijst",
+ "skipEmptyItems": "Lege items overslaan",
+ "skipEmptyItemsDescription": "Neem de lege lijst-items niet op in de uitvoer.",
+ "title": "Vind uniek",
+ "trimItems": "Items in de trimlijst",
+ "trimItemsDescription": "Verwijder spaties voor en na de items voordat u ze vergelijkt.",
+ "uniqueItemOptions": "Unieke itemopties"
+ },
+ "group": {
+ "deleteEmptyItems": "Lege items verwijderen",
+ "deleteEmptyItemsDescription": "Negeer lege items en neem ze niet op in de groepen.",
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het groeperen van lijstitems. Voer uw lijst in en specificeer groeperingscriteria om items in logische groepen te ordenen. Perfect voor het categoriseren van gegevens, het organiseren van informatie of het maken van gestructureerde lijsten. Ondersteunt aangepaste scheidingstekens en diverse groeperingsopties.",
+ "emptyItemsAndPadding": "Lege items en opvulling",
+ "groupNumberDescription": "Aantal items in een groep",
+ "groupSeparatorDescription": "Groepsscheidingsteken",
+ "groupSizeAndSeparators": "Groepsgrootte en scheidingstekens",
+ "inputItemSeparator": "Scheidingsteken voor invoeritems",
+ "inputTitle": "Invoerlijst",
+ "itemSeparatorDescription": "Itemscheidingsteken",
+ "leftWrapDescription": "Linksomloopsymbool van de groep.",
+ "padNonFullGroups": "Pad Niet-volledige groepen",
+ "padNonFullGroupsDescription": "Vul niet-volledige groepen met een aangepast item (voer hieronder in).",
+ "paddingCharDescription": "Gebruik dit karakter of item om groepen aan te vullen die niet vol zijn.",
+ "resultTitle": "Gegroepeerde items",
+ "rightWrapDescription": "Symbool voor de rechteromslag van de groep.",
+ "shortDescription": "Groepeer lijstitems op basis van gemeenschappelijke eigenschappen",
+ "splitOperators": {
+ "regex": {
+ "description": "Beperk de items in de invoerlijst met een reguliere expressie.",
+ "title": "Gebruik een Regex voor het splitsen"
+ },
+ "symbol": {
+ "description": "Beperk de items in de invoerlijst met een teken.",
+ "title": "Gebruik een symbool voor splitsen"
+ }
+ },
+ "splitSeparatorDescription": "Stel een scheidingsteken of reguliere expressie in.",
+ "title": "Groep"
+ },
+ "reverse": {
+ "description": "Dit is een supereenvoudige browserapplicatie die alle items in de lijst in spiegelbeeld afdrukt. De invoeritems kunnen worden gescheiden door een willekeurig symbool en u kunt ook de scheidingstekens van de omgekeerde items in de lijst wijzigen.",
+ "inputTitle": "Invoerlijst",
+ "itemSeparator": "Itemscheidingsteken",
+ "itemSeparatorDescription": "Stel een scheidingsteken of reguliere expressie in.",
+ "outputListOptions": "Opties voor uitvoerlijst",
+ "outputSeparatorDescription": "Scheidingsteken voor uitvoerlijst-items.",
+ "resultTitle": "Omgekeerde lijst",
+ "shortDescription": "Een lijst snel omkeren",
+ "splitOperators": {
+ "regex": {
+ "description": "Beperk de items in de invoerlijst met een reguliere expressie.",
+ "title": "Gebruik een Regex voor het splitsen"
+ },
+ "symbol": {
+ "description": "Beperk de items in de invoerlijst met een teken.",
+ "title": "Gebruik een symbool voor splitsen"
+ }
+ },
+ "splitterMode": "Splittermodus",
+ "title": "Achteruit",
+ "toolInfo": {
+ "description": "Met dit hulpprogramma kunt u de volgorde van items in een lijst omkeren. Het hulpprogramma splitst de invoerlijst eerst op in afzonderlijke items en doorloopt deze vervolgens van het laatste naar het eerste item, waarbij elk item tijdens de iteratie in de uitvoer wordt afgedrukt. De invoerlijst kan alles bevatten wat kan worden weergegeven als tekstuele gegevens, zoals cijfers, getallen, strings, woorden, zinnen, enz. Het scheidingsteken voor invoeritems kan ook een reguliere expressie zijn. Met de regex /[;,]/ kunt u bijvoorbeeld items gebruiken die door komma's of puntkomma's worden gescheiden. De scheidingstekens voor invoer- en uitvoerlijstitems kunnen in de opties worden aangepast. Standaard zijn zowel invoer- als uitvoerlijsten door komma's gescheiden. Listabulous!",
+ "title": "Wat is een lijstomkeerder?"
+ }
+ },
+ "rotate": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het roteren van lijstitems. Voer uw lijst in en specificeer de rotatiehoeveelheid om items met een bepaald aantal posities te verschuiven. Perfect voor gegevensmanipulatie, circulaire verschuivingen of het opnieuw ordenen van lijsten.",
+ "shortDescription": "Lijstitems roteren op opgegeven posities",
+ "title": "Draaien"
+ },
+ "shuffle": {
+ "delimiterDescription": "Stel een scheidingsteken of reguliere expressie in.",
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het herschikken van lijstitems. Voer je lijst in en ontvang direct een gerandomiseerde versie met items in willekeurige volgorde. Perfect voor het creรซren van variatie, het testen van willekeur of het door elkaar halen van geordende gegevens.",
+ "inputListSeparator": "Scheidingsteken voor invoerlijst",
+ "inputTitle": "Invoerlijst",
+ "joinSeparatorDescription": "Gebruik dit scheidingsteken in de willekeurige lijst.",
+ "outputLengthDescription": "Geef zoveel willekeurige items weer",
+ "resultTitle": "Geschudde lijst",
+ "shortDescription": "De volgorde van lijstitems willekeurig maken",
+ "shuffledListLength": "Lengte van de geschudde lijst",
+ "shuffledListSeparator": "Geschudde lijstscheidingsteken",
+ "title": "Schudden"
+ },
+ "sort": {
+ "caseSensitive": "Hoofdlettergevoelig sorteren",
+ "caseSensitiveDescription": "Sorteer hoofdletters en kleine letters apart. Hoofdletters gaan vooraf aan kleine letters in een oplopende lijst. (Werkt alleen in alfabetische sorteermodus.)",
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het sorteren van lijstitems. Voer uw lijst in en specificeer sorteercriteria om items in oplopende of aflopende volgorde te ordenen. Perfect voor gegevensorganisatie, tekstverwerking of het maken van geordende lijsten.",
+ "inputItemSeparator": "Scheidingsteken voor invoeritems",
+ "inputTitle": "Invoerlijst",
+ "joinSeparatorDescription": "Gebruik dit symbool als verbindingsstuk tussen items in een gesorteerde lijst.",
+ "orderDescription": "Selecteer een sorteervolgorde.",
+ "orderOptions": {
+ "decreasing": "Afnemende volgorde",
+ "increasing": "Toenemende orde"
+ },
+ "removeDuplicates": "Duplicaten verwijderen",
+ "removeDuplicatesDescription": "Verwijder dubbele lijstonderdelen.",
+ "resultTitle": "Gesorteerde lijst",
+ "shortDescription": "Lijstitems in de opgegeven volgorde sorteren",
+ "sortMethod": "Sorteermethode",
+ "sortMethodDescription": "Selecteer een sorteermethode.",
+ "sortOptions": {
+ "alphabetic": "Alfabetisch sorteren",
+ "length": "Sorteren op lengte",
+ "numeric": "Numeriek sorteren"
+ },
+ "sortedItemProperties": "Gesorteerde itemeigenschappen",
+ "splitOperators": {
+ "regex": {
+ "description": "Beperk de items in de invoerlijst met een reguliere expressie.",
+ "title": "Gebruik een Regex voor het splitsen"
+ },
+ "symbol": {
+ "description": "Beperk de items in de invoerlijst met een teken.",
+ "title": "Gebruik een symbool voor splitsen"
+ }
+ },
+ "splitSeparatorDescription": "Stel een scheidingsteken of reguliere expressie in.",
+ "title": "Soort"
+ },
+ "truncate": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het afkappen van lijsten. Voer uw lijst in en specificeer het maximale aantal items dat u wilt behouden. Perfect voor gegevensverwerking, lijstbeheer of het beperken van de lengte van content.",
+ "shortDescription": "Lijst afkappen tot een bepaald aantal items",
+ "title": "Afkappen"
+ },
+ "unwrap": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het uitpakken van lijstitems. Voer uw ingepakte lijst in en specificeer uitpakcriteria om georganiseerde items plat te maken. Perfect voor gegevensverwerking, tekstmanipulatie of het extraheren van inhoud uit gestructureerde lijsten.",
+ "shortDescription": "Lijstitems uit gestructureerde opmaak uitpakken",
+ "title": "Uitpakken"
+ },
+ "wrap": {
+ "description": "Voeg tekst toe voor en na elk item in de lijst.",
+ "inputTitle": "Invoerlijst",
+ "joinSeparatorDescription": "Scheidingsteken om de ingepakte lijst samen te voegen",
+ "leftTextDescription": "Tekst die vรณรณr elk item moet worden toegevoegd",
+ "removeEmptyItems": "Lege items verwijderen",
+ "resultTitle": "Ingepakte lijst",
+ "rightTextDescription": "Tekst die na elk item moet worden toegevoegd",
+ "shortDescription": "Lijstitems inpakken met opgegeven criteria",
+ "splitByRegex": "Gesplitst door reguliere expressie",
+ "splitBySymbol": "Gesplitst op symbool",
+ "splitOptions": "Gesplitste opties",
+ "splitSeparatorDescription": "Scheidingsteken om de lijst te splitsen",
+ "title": "Wrap",
+ "toolInfo": {
+ "description": "Met deze tool kunt u tekst voor en na elk item in een lijst toevoegen. U kunt verschillende tekst opgeven voor de linker- en rechterkant en bepalen hoe de lijst wordt verwerkt. Deze tool is handig voor het toevoegen van aanhalingstekens, haakjes of andere opmaak aan lijstitems, het voorbereiden van gegevens voor verschillende formaten of het maken van gestructureerde tekst.",
+ "title": "Lijstomloop"
+ },
+ "wrapOptions": "Wrap-opties"
+ }
+}
diff --git a/public/locales/nl/number.json b/public/locales/nl/number.json
new file mode 100644
index 0000000..4800780
--- /dev/null
+++ b/public/locales/nl/number.json
@@ -0,0 +1,89 @@
+{
+ "arithmeticSequence": {
+ "commonDifferenceDescription": "Veelvoorkomend verschil tussen termen (d)",
+ "description": "Genereer rekenkundige reeksen met aanpasbare parameters.",
+ "firstTermDescription": "Eerste term van de reeks (aโ)",
+ "numberOfTermsDescription": "Aantal te genereren termen (n)",
+ "outputFormat": "Uitvoerformaat",
+ "resultTitle": "Gegenereerde sequentie",
+ "separatorDescription": "Scheidingsteken tussen termen",
+ "sequenceParameters": "Sequentieparameters",
+ "shortDescription": "Genereer rekenkundige reeksen",
+ "title": "Rekenkundige reeks",
+ "toolInfo": {
+ "description": "Een rekenkundige rij is een reeks getallen waarbij het verschil tussen elke opeenvolgende term constant is. Dit constante verschil wordt de gemeenschappelijke afwijking genoemd. Gegeven de eerste term (aโ) en de gemeenschappelijke afwijking (d), kan elke term worden gevonden door de gemeenschappelijke afwijking op te tellen bij de vorige term.",
+ "title": "Wat is een rekenkundige rij?"
+ }
+ },
+ "generate": {
+ "arithmeticSequenceOption": "Optie voor rekenkundige reeks",
+ "description": "Genereer een getallenreeks met aanpasbare parameters.",
+ "numberOfElementsDescription": "Aantal elementen in volgorde.",
+ "resultTitle": "Gegenereerde nummers",
+ "separator": "Scheidingsteken",
+ "separatorDescription": "Scheid elementen in de rekenkundige reeks met dit teken.",
+ "shortDescription": "Genereer willekeurige getallen in opgegeven bereiken",
+ "startSequenceDescription": "Start de reeks vanaf dit nummer.",
+ "stepDescription": "Verhoog elk element met dit bedrag",
+ "title": "Genereren",
+ "toolInfo": {
+ "description": "Met deze tool kunt u een getallenreeks genereren met aanpasbare parameters. U kunt de startwaarde, stapgrootte en het aantal elementen specificeren.",
+ "title": "Genereer getallen"
+ }
+ },
+ "ohmsLaw": {
+ "description": "Bereken spanning, stroom en weerstand",
+ "longDescription": "Deze rekenmachine past de wet van Ohm (V = I ร R) toe om een van de drie elektrische parameters te bepalen wanneer de andere twee bekend zijn. De wet van Ohm is een fundamenteel principe in de elektrotechniek dat de relatie beschrijft tussen spanning (V), stroomsterkte (I) en weerstand (R). Deze tool is essentieel voor elektronicahobbyisten, elektrotechnici en studenten die met schakelingen werken om snel onbekende waarden in hun elektrische ontwerpen op te lossen.",
+ "shortDescription": "Bereken spanning, stroom of weerstand in elektrische circuits met behulp van de wet van Ohm",
+ "title": "Wet van Ohm"
+ },
+ "slackline": {
+ "description": "Bereken de spanning in een slackline",
+ "longDescription": "Deze rekenmachine gaat uit van een last in het midden van het touw",
+ "shortDescription": "Bereken de geschatte spanning van een slackline of waslijn. Vertrouw hier niet op voor je veiligheid.",
+ "title": "Slackline-spanning"
+ },
+ "sphereArea": {
+ "description": "Oppervlakte van een bol",
+ "longDescription": "Deze rekenmachine bepaalt de oppervlakte van een bol met behulp van de formule A = 4ฯrยฒ. U kunt de straal invoeren om de oppervlakte te berekenen, of de oppervlakte invoeren om de gewenste straal te berekenen. Deze tool is handig voor studenten meetkunde, ingenieurs die met bolvormige objecten werken en iedereen die berekeningen met bolvormige oppervlakken moet uitvoeren.",
+ "shortDescription": "Bereken het oppervlak van een bol op basis van de straal",
+ "title": "Oppervlakte van een bol"
+ },
+ "sphereVolume": {
+ "description": "Volume van een bol",
+ "longDescription": "Deze rekenmachine berekent het volume van een bol met de formule V = (4/3)ฯrยณ. U kunt de straal of diameter invoeren om het volume te berekenen, of het volume invoeren om de gewenste straal te bepalen. Deze tool is nuttig voor studenten, ingenieurs en professionals die met bolvormige objecten werken in vakgebieden zoals natuurkunde, techniek en productie.",
+ "shortDescription": "Bereken het volume van een bol met behulp van de straal of diameter",
+ "title": "Volume van een bol"
+ },
+ "sum": {
+ "description": "Bereken de som van een lijst met getallen. Voer getallen gescheiden door komma's of nieuwe regels in om de som te berekenen.",
+ "extractionTypes": {
+ "delimiter": {
+ "description": "Pas hier het scheidingsteken voor getallen aan. (Standaard een regelafbreking.)",
+ "title": "Nummerscheidingsteken"
+ },
+ "smart": {
+ "description": "Automatische detectie van getallen in de invoer.",
+ "title": "Slimme Som"
+ }
+ },
+ "inputTitle": "Invoer",
+ "numberExtraction": "Nummer extractie",
+ "printRunningSum": "Afdrukken Lopende Som",
+ "printRunningSumDescription": "Geef de som weer terwijl deze stap voor stap wordt berekend.",
+ "resultTitle": "Totaal",
+ "runningSum": "Lopende som",
+ "shortDescription": "Bereken de som van getallen",
+ "title": "Som",
+ "toolInfo": {
+ "description": "Dit is een online browserprogramma waarmee je de som van een aantal getallen kunt berekenen. Je kunt de getallen invoeren, gescheiden door een komma, spatie of een ander teken, inclusief de regelafbreking. Je kunt ook gewoon een fragment tekstuele gegevens plakken met numerieke waarden die je wilt optellen. Het programma zal deze waarden dan extraheren en de som bepalen.",
+ "title": "Wat is een getallensomcalculator?"
+ }
+ },
+ "voltageDropInWire": {
+ "description": "Bereken de retourspanning en het vermogensverlies in een 2-aderige kabel",
+ "longDescription": "Deze calculator helpt bij het bepalen van de spanningsval en het vermogensverlies in een tweeaderige elektrische kabel. Hierbij wordt rekening gehouden met de kabellengte, de draaddikte (dwarsdoorsnede), de materiaalweerstand en de stroomsterkte. De tool berekent de spanningsval heen en terug, de totale weerstand van de kabel en het vermogen dat als warmte wordt afgegeven. Dit is met name handig voor elektrotechnici, elektriciens en hobbyisten bij het ontwerpen van elektrische systemen om ervoor te zorgen dat de spanningsniveaus bij de belasting binnen acceptabele grenzen blijven.",
+ "shortDescription": "Bereken spanningsval en vermogensverlies in elektrische kabels op basis van lengte, materiaal en stroom",
+ "title": "Spanningsval in de kabel bij retour"
+ }
+}
diff --git a/public/locales/nl/pdf.json b/public/locales/nl/pdf.json
new file mode 100644
index 0000000..250f554
--- /dev/null
+++ b/public/locales/nl/pdf.json
@@ -0,0 +1,113 @@
+{
+ "compressPdf": {
+ "compressedFileSize": "Gecomprimeerde bestandsgrootte",
+ "compressingPdf": "PDF comprimeren...",
+ "compressionLevel": "Compressieniveau",
+ "compressionSettings": "Compressie-instellingen",
+ "description": "Verklein de PDF-bestandsgrootte met behoud van kwaliteit met Ghostscript",
+ "errorCompressingPdf": "PDF comprimeren is mislukt: {{error}}",
+ "errorReadingPdf": "PDF-bestand kan niet worden gelezen. Controleer of het een geldig PDF-bestand is.",
+ "fileSize": "Originele bestandsgrootte",
+ "highCompression": "Hoge compressie",
+ "highCompressionDescription": "Maximale bestandsgroottevermindering met enig kwaliteitsverlies",
+ "inputTitle": "PDF-invoer",
+ "lowCompression": "Lage compressie",
+ "lowCompressionDescription": "Verklein de bestandsgrootte lichtjes met minimaal kwaliteitsverlies",
+ "mediumCompression": "Gemiddelde compressie",
+ "mediumCompressionDescription": "Balans tussen bestandsgrootte en kwaliteit",
+ "pages": "Aantal pagina's",
+ "resultTitle": "Gecomprimeerde PDF",
+ "shortDescription": "Comprimeer PDF-bestanden veilig in uw browser",
+ "title": "PDF comprimeren"
+ },
+ "editor": {
+ "description": "Geavanceerde PDF-editor met mogelijkheden voor annotatie, formulieren invullen, markeren en exporteren. Bewerk uw PDF's rechtstreeks in de browser met professionele tools zoals tekst invoegen, tekenen, markeren, ondertekenen en formulieren invullen.",
+ "shortDescription": "Bewerk PDF's met geavanceerde hulpmiddelen voor annotatie, ondertekening en bewerking",
+ "title": "PDF-editor"
+ },
+ "merge": {
+ "inputTitle": "PDF-invoer",
+ "loadingText": "Pagina's extraheren",
+ "resultTitle": "Samengevoegde PDF-uitvoer",
+ "toolInfo": {
+ "description": "Met deze tool kun je meerdere PDF-bestanden samenvoegen tot รฉรฉn document. Om de tool te gebruiken, upload je eenvoudig de PDF-bestanden die je wilt samenvoegen. De tool combineert vervolgens alle pagina's uit de invoerbestanden tot รฉรฉn PDF-document.",
+ "title": "Hoe gebruik ik de PDF-samenvoegtool?"
+ }
+ },
+ "mergePdf": {
+ "description": "Combineer meerdere PDF-bestanden tot รฉรฉn document.",
+ "inputTitle": "PDF-invoer",
+ "mergingPdfs": "PDF's samenvoegen",
+ "pdfOptions": "PDF-opties",
+ "resultTitle": "Samengevoegde PDF",
+ "shortDescription": "Meerdere PDF-bestanden samenvoegen tot รฉรฉn document",
+ "sortByFileName": "Sorteren op bestandsnaam",
+ "sortByFileNameDescription": "PDF's alfabetisch sorteren op bestandsnaam",
+ "sortByUploadOrder": "Sorteren op uploadvolgorde",
+ "sortByUploadOrderDescription": "Bewaar PDF's in de volgorde waarin ze zijn geรผpload",
+ "title": "PDF samenvoegen",
+ "toolInfo": {
+ "description": "Met deze tool kun je meerdere PDF-bestanden combineren tot รฉรฉn document. Je kunt kiezen hoe je de PDF's wilt sorteren en de tool voegt ze samen in de opgegeven volgorde.",
+ "title": "PDF-bestanden samenvoegen"
+ }
+ },
+ "pdfToEpub": {
+ "description": "PDF-documenten transformeren naar EPUB-bestanden voor betere compatibiliteit met e-readers.', pictogram: 'material-symbols:import-contacts', component: lazy(() => import('./index')), trefwoorden: ['pdf', 'epub', 'convert', 'ebook'], pad: 'pdf-naar-epub', i18n: { naam: 'pdf:pdfToEpub.title', beschrijving: 'pdf:pdfToEpub.description",
+ "shortDescription": "PDF-bestanden converteren naar EPUB-formaat",
+ "title": "PDF naar EPUB"
+ },
+ "pdfToPng": {
+ "description": "Transformeer PDF-documenten naar PNG-panelen.",
+ "longDescription": "Upload een PDF en converteer elke pagina rechtstreeks in je browser naar een hoogwaardige PNG-afbeelding. Deze tool is ideaal voor het extraheren van visuele content of het delen van individuele pagina's. Er worden geen gegevens geรผpload - alles wordt lokaal uitgevoerd.",
+ "shortDescription": "PDF naar PNG-afbeeldingen converteren",
+ "title": "PDF naar PNG"
+ },
+ "protectPdf": {
+ "description": "Voeg wachtwoordbeveiliging toe aan uw PDF-bestanden veilig in uw browser",
+ "shortDescription": "PDF-bestanden veilig met een wachtwoord beveiligen",
+ "title": "PDF beschermen"
+ },
+ "rotatePdf": {
+ "allPagesWillBeRotated": "Alle {{count}} pagina's worden gedraaid",
+ "angleOptions": {
+ "clockwise90": "90ยฐ met de klok mee",
+ "counterClockwise270": "270ยฐ (90ยฐ tegen de klok in)",
+ "upsideDown180": "180ยฐ (op zijn kop)"
+ },
+ "applyToAllPages": "Toepassen op alle pagina's",
+ "description": "Pagina's in een PDF-document roteren.",
+ "inputTitle": "PDF-invoer",
+ "longDescription": "Wijzig de oriรซntatie van PDF-pagina's door ze 90, 180 of 270 graden te draaien. Handig voor het corrigeren van onjuist gescande documenten of het voorbereiden van PDF's voor afdrukken.",
+ "pageRangesDescription": "Voer paginanummers of bereiken in, gescheiden door komma's (bijv. 1, 3, 5-7)",
+ "pageRangesPlaceholder": "bijv. 1,5-8",
+ "pagesWillBeRotated": "{{count}} pagina{{count !== 1 ? 's' : ''}} zal worden gedraaid",
+ "pdfPageCount": "PDF heeft {{count}} pagina{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "Gedraaide PDF",
+ "rotatingPages": "Roterende pagina's",
+ "rotationAngle": "Rotatiehoek",
+ "rotationSettings": "Rotatie-instellingen",
+ "shortDescription": "Pagina's in een PDF-document roteren",
+ "title": "PDF roteren",
+ "toolInfo": {
+ "description": "Met deze tool kunt u pagina's in een PDF-document roteren. U kunt alle pagina's roteren of specifieke pagina's opgeven. Kies een rotatiehoek: 90ยฐ met de klok mee, 180ยฐ (ondersteboven) of 270ยฐ (90ยฐ tegen de klok in). Om specifieke pagina's te roteren, schakelt u 'Toepassen op alle pagina's' uit en voert u paginanummers of paginabereiken in, gescheiden door komma's (bijvoorbeeld 1, 3, 5-7).",
+ "title": "De PDF-rotatietool gebruiken"
+ }
+ },
+ "splitPdf": {
+ "description": "Specifieke pagina's uit een PDF-document extraheren.",
+ "extractingPages": "Pagina's extraheren",
+ "inputTitle": "PDF-invoer",
+ "pageExtractionPreview": "{{count}} pagina{{count !== 1 ? 's' : ''}} zal worden geรซxtraheerd",
+ "pageRangesDescription": "Voer paginanummers of bereiken in, gescheiden door komma's (bijv. 1, 3, 5-7)",
+ "pageRangesPlaceholder": "bijv. 1,5-8",
+ "pageSelection": "Paginaselectie",
+ "pdfPageCount": "PDF heeft {{count}} pagina{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "Geรซxtraheerde PDF",
+ "shortDescription": "Specifieke pagina's uit een PDF-bestand extraheren",
+ "title": "PDF splitsen",
+ "toolInfo": {
+ "description": "Met deze tool kunt u specifieke pagina's uit een PDF-document extraheren. U kunt specifieke pagina's of paginareeksen opgeven die u wilt extraheren.",
+ "title": "PDF splitsen"
+ }
+ }
+}
diff --git a/public/locales/nl/string.json b/public/locales/nl/string.json
new file mode 100644
index 0000000..5864ea2
--- /dev/null
+++ b/public/locales/nl/string.json
@@ -0,0 +1,261 @@
+{
+ "base64": {
+ "decode": "Base64-decodering",
+ "description": "Codeer of decodeer tekst met Base64-codering.",
+ "encode": "Base64-codering",
+ "inputTitle": "Invoergegevens",
+ "optionsTitle": "Base64-opties",
+ "resultTitle": "Resultaat",
+ "shortDescription": "Codeer of decodeer gegevens met Base64.",
+ "title": "Base64-encoder/-decoder",
+ "toolInfo": {
+ "description": "Base64 is een coderingsmethode die gegevens in een ASCII-stringformaat weergeeft door ze te vertalen naar een radix-64-representatie. Hoewel het gebruikt kan worden om strings te coderen, wordt het vaak gebruikt om binaire gegevens te coderen voor transmissie via media die ontworpen zijn voor tekstuele gegevens.",
+ "title": "Wat is Base64?"
+ }
+ },
+ "censor": {
+ "description": "Hulpprogramma voor het censureren van woorden in tekst. Laad uw tekst in het invoerformulier aan de linkerkant, specificeer alle ongewenste woorden in de opties en u krijgt direct gecensureerde tekst in het uitvoergebied.\", longDescription: 'Met deze online tool kunt u bepaalde woorden in elke tekst censureren. U kunt een lijst met ongewenste woorden (zoals scheldwoorden of geheime woorden) opgeven en het programma vervangt deze door alternatieve woorden en creรซert een veilig leesbare tekst. De woorden kunnen worden opgegeven in een tekstveld van meerdere regels in de opties door รฉรฉn woord per regel in te voeren.', keywords: ['tekst', 'censureren', 'woorden', 'tekens'], component: lazy(() => import('./index')), i18n: { name: 'string:censor.title', description: 'string:censor.description",
+ "shortDescription": "Maskeer snel slechte woorden of vervang ze door alternatieve woorden.",
+ "title": "Tekstcensor"
+ },
+ "createPalindrome": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde tool voor het maken van palindromen van elke tekst. Voer tekst in en transformeer deze direct in een palindroom die zowel van voor naar achter als van achter naar voren hetzelfde leest. Perfect voor woordspelletjes, het creรซren van symmetrische tekstpatronen of het verkennen van taalkundige curiosa.",
+ "shortDescription": "Maak een tekst die van voor naar achter en van achter naar voren hetzelfde leest",
+ "title": "Palindroom maken"
+ },
+ "extractSubstring": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het extraheren van substrings uit tekst. Voer uw tekst in en specificeer de begin- en eindposities om het gewenste deel te extraheren. Perfect voor gegevensverwerking, tekstanalyse of het extraheren van specifieke inhoud uit grotere tekstblokken.",
+ "shortDescription": "Een tekstgedeelte tussen opgegeven posities extraheren",
+ "title": "Substring extraheren"
+ },
+ "join": {
+ "blankLinesAndTrailingSpaces": "Lege regels en spaties aan het einde",
+ "deleteBlankDescription": "Verwijder regels die geen tekstsymbolen bevatten.",
+ "deleteBlankTitle": "Lege regels verwijderen",
+ "deleteTrailingDescription": "Verwijder spaties en tabs aan het einde van de regels.",
+ "deleteTrailingTitle": "Verwijder afsluitende spaties",
+ "description": "Voeg tekststukken samen met aanpasbare scheidingstekens.",
+ "inputTitle": "Tekststukken",
+ "joinCharacterDescription": "Symbool dat gebroken tekststukken met elkaar verbindt. (Standaard spatie.)",
+ "joinCharacterPlaceholder": "Sluit je aan bij het personage",
+ "resultTitle": "Gekoppelde tekst",
+ "shortDescription": "Tekstelementen samenvoegen met een opgegeven scheidingsteken",
+ "textMergedOptions": "Opties voor samengevoegde tekst",
+ "title": "Tekst toevoegen",
+ "toolInfo": {
+ "description": "Met deze tool kun je tekstdelen samenvoegen. Het neemt een lijst met tekstwaarden, gescheiden door nieuwe regels, en voegt deze samen. Je kunt het teken instellen dat tussen de delen van de samengevoegde tekst wordt geplaatst. Je kunt ook alle lege regels negeren en spaties en tabs aan het einde van alle regels verwijderen. Tekstabulous!",
+ "title": "Wat is een tekstsamenvoeger?"
+ }
+ },
+ "palindrome": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma om te controleren of tekst een palindroom is. Controleer direct of uw tekst van voor naar achter hetzelfde leest. Perfect voor woordpuzzels, taalkundige analyses of het valideren van symmetrische tekstpatronen. Ondersteunt diverse scheidingstekens en palindroomdetectie van meerdere woorden.",
+ "shortDescription": "Controleren of de tekst van voor naar achter hetzelfde leest",
+ "title": "Palindroom"
+ },
+ "passwordGenerator": {
+ "avoidAmbiguous": "Vermijd dubbelzinnige tekens (i, I, l, 0, O)",
+ "description": "Genereer veilige, willekeurige wachtwoorden met aanpasbare lengte en tekentypes. Kies uit kleine letters, hoofdletters, cijfers en speciale tekens. Optie om dubbelzinnige tekens te vermijden voor een betere leesbaarheid.",
+ "includeLowercase": "Gebruik kleine letters (a-z)",
+ "includeNumbers": "Inclusief cijfers (0-9)",
+ "includeSymbols": "Speciale tekens toevoegen",
+ "includeUppercase": "Inclusief hoofdletters (A-Z)",
+ "lengthDesc": "Lengte van het wachtwoord",
+ "lengthPlaceholder": "bijv. 12",
+ "optionsTitle": "Wachtwoordopties",
+ "resultTitle": "gegenereerd wachtwoord",
+ "shortDescription": "Genereer veilige willekeurige wachtwoorden met aangepaste opties",
+ "title": "Wachtwoordgenerator",
+ "toolInfo": {
+ "description": "Deze tool genereert veilige, willekeurige wachtwoorden op basis van de door u geselecteerde criteria. U kunt de lengte aanpassen, verschillende tekentypen toevoegen of uitsluiten en dubbelzinnige tekens vermijden voor een betere leesbaarheid. Perfect voor het maken van sterke wachtwoorden voor accounts, applicaties of andere beveiligingsbehoeften.",
+ "title": "Over wachtwoordgenerator"
+ }
+ },
+ "quote": {
+ "allowDoubleQuotation": "Dubbele aanhalingstekens toestaan",
+ "description": "Voeg aanhalingstekens toe rondom de tekst met aanpasbare opties.",
+ "inputTitle": "Invoertekst",
+ "leftQuoteDescription": "Linker aanhalingsteken(s)",
+ "processAsMultiLine": "Verwerken als meerregelige tekst",
+ "quoteEmptyLines": "Lege regels citeren",
+ "quoteOptions": "Offerte-opties",
+ "resultTitle": "Geciteerde tekst",
+ "rightQuoteDescription": "Rechter aanhalingsteken(s)",
+ "shortDescription": "Voeg aanhalingstekens toe rond tekst met verschillende stijlen",
+ "title": "Tekstcitaat",
+ "toolInfo": {
+ "description": "Met deze tool kun je aanhalingstekens rond tekst plaatsen. Je kunt verschillende aanhalingstekens kiezen, tekst van meerdere regels verwerken en bepalen hoe lege regels worden verwerkt. Het is handig om tekst voor te bereiden voor programmering, gegevens op te maken of gestileerde tekst te maken.",
+ "title": "Tekstcitaat"
+ }
+ },
+ "randomizeCase": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het willekeurig maken van teksthoofdletters en kleine letters. Voer je tekst in en transformeer deze direct met willekeurige hoofdletters en kleine letters. Perfect voor het creรซren van unieke teksteffecten, het testen van hoofdlettergevoeligheid of het genereren van gevarieerde tekstpatronen.",
+ "shortDescription": "Willekeurige hoofdlettergebruik in tekst",
+ "title": "Randomiseer het geval"
+ },
+ "removeDuplicateLines": {
+ "description": "Laad je tekst in het invoerformulier aan de linkerkant en je krijgt direct tekst zonder dubbele regels in het uitvoergebied. Krachtig, gratis en snel. Laad tekstregels โ krijg unieke tekstregels.",
+ "shortDescription": "Verwijder snel alle herhaalde regels uit de tekst",
+ "title": "Dubbele regels verwijderen"
+ },
+ "repeat": {
+ "delimiterDescription": "Scheidingsteken voor uitvoerkopieรซn.",
+ "delimiterPlaceholder": "scheidingsteken",
+ "description": "Herhaal tekst meerdere keren met aanpasbare scheidingstekens.",
+ "inputTitle": "Invoertekst",
+ "numberPlaceholder": "Nummer",
+ "repeatAmountDescription": "Aantal herhalingen.",
+ "repetitionsDelimiter": "Herhalingen scheidingsteken",
+ "resultTitle": "Herhaalde tekst",
+ "shortDescription": "Herhaal de tekst meerdere keren",
+ "textRepetitions": "Tekstherhalingen",
+ "title": "Herhaal tekst",
+ "toolInfo": {
+ "description": "Met deze tool kunt u een bepaalde tekst meerdere keren herhalen met een optionele scheidingsteken.",
+ "title": "Herhaal tekst"
+ }
+ },
+ "reverse": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het omkeren van tekst. Voer tekst in en laat deze direct omkeren, teken voor teken. Perfect voor het maken van spiegeltekst, het analyseren van palindromen of het experimenteren met tekstpatronen. Spaties en speciale tekens blijven behouden tijdens het omkeren.",
+ "inputTitle": "Omgekeerde tekst",
+ "processMultiLine": "Verwerk meerregelige tekst",
+ "processMultiLineDescription": "Elke regel wordt onafhankelijk omgedraaid",
+ "resultTitle": "Omgekeerde tekst",
+ "reversalOptions": "Omkeeropties",
+ "shortDescription": "Elke tekst teken voor teken omdraaien",
+ "skipEmptyLines": "Lege regels overslaan",
+ "skipEmptyLinesDescription": "Lege regels worden uit de uitvoer verwijderd",
+ "title": "Achteruit",
+ "trimWhitespace": "Witruimte bijsnijden",
+ "trimWhitespaceDescription": "Verwijder voorloop- en volgspaties van elke regel"
+ },
+ "rot13": {
+ "description": "Codeer of decodeer tekst met behulp van de ROT13-codering.",
+ "inputTitle": "Invoertekst",
+ "resultTitle": "ROT13-resultaat",
+ "shortDescription": "Codeer of decodeer tekst met behulp van de ROT13-codering.",
+ "title": "ROT13 Encoder/Decoder",
+ "toolInfo": {
+ "description": "ROT13 (rotate by 13 places) is een eenvoudige lettervervangingscode die een letter vervangt door de 13e letter erna in het alfabet. ROT13 is een speciaal geval van de Caesarcode, die in het oude Rome werd ontwikkeld. Omdat het Engelse alfabet 26 letters telt, is ROT13 zijn eigen inverse; dat wil zeggen, om ROT13 ongedaan te maken, wordt hetzelfde algoritme toegepast, zodat dezelfde actie kan worden gebruikt voor zowel coderen als decoderen.",
+ "title": "Wat is ROT13?"
+ }
+ },
+ "rotate": {
+ "description": "Draai tekens in tekst over opgegeven posities.",
+ "inputTitle": "Invoertekst",
+ "processAsMultiLine": "Verwerken als meerregelige tekst (elke regel afzonderlijk roteren)",
+ "resultTitle": "Gedraaide tekst",
+ "rotateLeft": "Linksom draaien",
+ "rotateRight": "Rechts draaien",
+ "rotationOptions": "Rotatieopties",
+ "shortDescription": "Verplaats tekens in tekst per positie.",
+ "stepDescription": "Aantal te roteren posities",
+ "title": "Tekst roteren",
+ "toolInfo": {
+ "description": "Met deze tool kunt u tekens in een tekenreeks met een bepaald aantal posities roteren. U kunt naar links of rechts roteren en tekst van meerdere regels verwerken door elke regel afzonderlijk te roteren. Tekenreeksrotatie is handig voor eenvoudige teksttransformaties, het maken van patronen of het implementeren van basisversleutelingstechnieken.",
+ "title": "Snaarrotatie"
+ }
+ },
+ "split": {
+ "charAfterChunkDescription": "Karakter na elk stukje",
+ "charBeforeChunkDescription": "Karakter voor elk stukje",
+ "chunksDescription": "Aantal gelijke\nlengtes in de uitvoer.",
+ "chunksTitle": "Gebruik een aantal stukken",
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het splitsen van tekst. Voer uw tekst in en geef een scheidingsteken op om deze in meerdere delen te splitsen. Perfect voor gegevensverwerking, tekstmanipulatie of het extraheren van specifieke inhoud uit grotere tekstblokken.",
+ "lengthDescription": "Aantal symbolen dat in elk uitvoerblok wordt geplaatst.",
+ "lengthTitle": "Gebruik lengte voor splitsen",
+ "outputSeparatorDescription": "Teken dat tussen de gesplitste delen wordt geplaatst.\n(Standaard is dit een nieuwe regel \"\\n\".)",
+ "outputSeparatorOptions": "Opties voor uitvoerscheidingstekens",
+ "regexDescription": "Reguliere expressie die wordt gebruikt om tekst in stukken te splitsen.\n(Standaard meerdere spaties.)",
+ "regexTitle": "Gebruik een Regex voor het splitsen",
+ "resultTitle": "Tekststukken",
+ "shortDescription": "Tekst in meerdere delen splitsen met behulp van een scheidingsteken",
+ "splitSeparatorOptions": "Opties voor scheidingslijnen",
+ "symbolDescription": "Teken dat wordt gebruikt om tekst in stukken te splitsen.\n(Standaard spatie.)",
+ "symbolTitle": "Gebruik een symbool voor splitsen",
+ "title": "Split"
+ },
+ "statistic": {
+ "characterFrequencyAnalysis": "Karakterfrequentieanalyse",
+ "characterFrequencyAnalysisDescription": "Tel hoe vaak elk teken in de tekst voorkomt",
+ "delimitersOptions": "Opties voor scheidingstekens",
+ "description": "Analyseer tekst en genereer uitgebreide statistieken.",
+ "includeEmptyLines": "Lege regels toevoegen",
+ "includeEmptyLinesDescription": "Voeg lege regels toe bij het tellen van regels",
+ "inputTitle": "Invoertekst",
+ "resultTitle": "Tekststatistieken",
+ "sentenceDelimitersDescription": "Voer aangepaste tekens in die u wilt gebruiken om zinnen in uw taal af te bakenen (gescheiden door komma's) of laat dit veld leeg voor de standaardinstelling.",
+ "sentenceDelimitersPlaceholder": "bijv. ., !, ?, ...",
+ "shortDescription": "Ontvang statistieken over uw tekst",
+ "statisticsOptions": "Statistiekenopties",
+ "title": "Tekststatistieken",
+ "toolInfo": {
+ "description": "Met deze tool kunt u tekst analyseren en uitgebreide statistieken genereren, waaronder het aantal tekens, woorden, regels en de frequentieanalyse van tekens en woorden.",
+ "title": "Wat is een {{title}}?"
+ },
+ "wordDelimitersDescription": "Voer een aangepaste Regex in om het aantal woorden te tellen of laat dit leeg voor de standaardwaarde.",
+ "wordDelimitersPlaceholder": "bijv. \\s.,;:!?\"ยซยป()โฆ",
+ "wordFrequencyAnalysis": "Woordfrequentieanalyse",
+ "wordFrequencyAnalysisDescription": "Tel hoe vaak elk woord in de tekst voorkomt"
+ },
+ "textReplacer": {
+ "description": "Vervang tekstpatronen door nieuwe inhoud.",
+ "findPatternInText": "Vind dit patroon in de tekst",
+ "findPatternUsingRegexp": "Vind een patroon met behulp van een RegExp",
+ "inputTitle": "Te vervangen tekst",
+ "newTextPlaceholder": "Nieuwe tekst",
+ "regexpDescription": "Voer de reguliere expressie in die u wilt vervangen.",
+ "replacePatternDescription": "Voer het patroon in dat u voor de vervanging wilt gebruiken.",
+ "replaceText": "Tekst vervangen",
+ "resultTitle": "Tekst met vervangingen",
+ "searchPatternDescription": "Voer het tekstpatroon in dat u wilt vervangen.",
+ "searchText": "Zoektekst",
+ "shortDescription": "Vervang snel tekst in uw inhoud",
+ "title": "Tekstvervanger",
+ "toolInfo": {
+ "description": "Vervang eenvoudig specifieke tekst in je content met deze eenvoudige, browsergebaseerde tool. Voer je tekst in, stel de tekst die je wilt vervangen en de vervangingswaarde in, en ontvang direct de bijgewerkte versie.",
+ "title": "Tekstvervanger"
+ }
+ },
+ "toMorse": {
+ "dashSymbolDescription": "Symbool dat overeenkomt met het streepje in Morsecode.",
+ "description": "Converteer tekst naar morsecode.",
+ "dotSymbolDescription": "Symbool dat overeenkomt met het punt in Morsecode.",
+ "longSignal": "Lang signaal",
+ "resultTitle": "Morsecode",
+ "shortDescription": "Snel tekst naar morse coderen",
+ "shortSignal": "Kort signaal",
+ "title": "String naar morse"
+ },
+ "truncate": {
+ "addTruncationIndicator": "Voeg afkappingsindicator toe",
+ "charactersPlaceholder": "Personages",
+ "description": "Kort de tekst in tot een bepaalde lengte.",
+ "indicatorDescription": "Tekens die aan het einde (of begin) van de tekst moeten worden toegevoegd. Let op: deze tellen mee voor de lengte.",
+ "inputTitle": "Invoertekst",
+ "leftSideDescription": "Verwijder tekens aan het begin van de tekst.",
+ "leftSideTruncation": "Linkerkant afkapping",
+ "lengthAndLines": "Lengte en lijnen",
+ "lineByLineDescription": "Knip elke regel afzonderlijk af.",
+ "lineByLineTruncating": "Regel-voor-regel afkappen",
+ "maxLengthDescription": "Aantal tekens dat in de tekst moet worden overgelaten.",
+ "numberPlaceholder": "Nummer",
+ "resultTitle": "Afgekorte tekst",
+ "rightSideDescription": "Verwijder tekens aan het einde van de tekst.",
+ "rightSideTruncation": "Afkapping aan de rechterkant",
+ "shortDescription": "Tekst afkappen tot een bepaalde lengte",
+ "suffixAndAffix": "Achtervoegsel en affix",
+ "title": "Tekst afbreken",
+ "toolInfo": {
+ "description": "Vul uw tekst in het invoerformulier aan de linkerkant in, dan krijgt u rechts automatisch afgekapte tekst te zien.",
+ "title": "Tekst afkappen"
+ },
+ "truncationSide": "Afkappingszijde"
+ },
+ "uppercase": {
+ "description": "Converteer tekst naar hoofdletters.",
+ "inputTitle": "Invoertekst",
+ "resultTitle": "Hoofdlettertekst",
+ "shortDescription": "Tekst naar hoofdletters converteren",
+ "title": "Omzetten naar hoofdletters"
+ }
+}
diff --git a/public/locales/nl/time.json b/public/locales/nl/time.json
new file mode 100644
index 0000000..e0f423b
--- /dev/null
+++ b/public/locales/nl/time.json
@@ -0,0 +1,100 @@
+{
+ "checkLeapYears": {
+ "description": "Controleer of een jaar een schrikkeljaar is en ontvang informatie over schrikkeljaren.",
+ "inputTitle": "Invoerjaar",
+ "resultTitle": "Resultaat van een schrikkeljaar",
+ "shortDescription": "Controleren of een jaar een schrikkeljaar is",
+ "title": "Controleer schrikkeljaren",
+ "toolInfo": {
+ "description": "Een schrikkeljaar is een jaar met een extra dag (29 februari) om het kalenderjaar gelijk te laten lopen met het astronomische jaar. Schrikkeljaren komen elke vier jaar voor, behalve jaren die deelbaar zijn door 100 maar niet door 400.",
+ "title": "Wat is een schrikkeljaar?"
+ }
+ },
+ "convertDaysToHours": {
+ "addHoursName": "Urennaam toevoegen",
+ "addHoursNameDescription": "Voeg de tekenreeks uren toe aan de uitvoerwaarden",
+ "description": "Converteer dagen naar uren met aanpasbare opties.",
+ "hoursName": "Uren Naam",
+ "shortDescription": "Dagen naar uren omrekenen",
+ "title": "Dagen naar uren converteren",
+ "toolInfo": {
+ "description": "Met deze tool kunt u dagen naar uren omrekenen. U kunt dagen invoeren als getallen of met eenheden, waarna de tool ze naar uren converteert. U kunt er ook voor kiezen om het achtervoegsel 'uren' aan de uitvoerwaarden toe te voegen.",
+ "title": "Dagen naar uren converteren"
+ }
+ },
+ "convertHoursToDays": {
+ "addDaysName": "Dagennaam toevoegen",
+ "addDaysNameDescription": "Voeg de tekenreeks dagen toe aan de uitvoerwaarden",
+ "daysName": "Dagen Naam",
+ "description": "Converteer uren naar dagen met aanpasbare opties.",
+ "shortDescription": "Uren naar dagen omrekenen",
+ "title": "Uren naar dagen omrekenen",
+ "toolInfo": {
+ "description": "Met deze tool kunt u uren naar dagen omrekenen. U kunt uren invoeren als getallen of met eenheden, waarna de tool ze naar dagen converteert. U kunt er ook voor kiezen om het achtervoegsel 'dagen' aan de uitvoerwaarden toe te voegen.",
+ "title": "Uren naar dagen omrekenen"
+ }
+ },
+ "convertSecondsToTime": {
+ "addPadding": "Opvulling toevoegen",
+ "addPaddingDescription": "Voeg nulvulling toe aan uren, minuten en seconden.",
+ "description": "Converteer seconden naar een leesbaar tijdsformaat (uren:minuten:seconden). Voer het aantal seconden in om de tijd in het juiste formaat te krijgen.",
+ "shortDescription": "Seconden naar tijdformaat converteren",
+ "timePadding": "Tijdvulling",
+ "title": "Seconden naar tijd converteren",
+ "toolInfo": {
+ "title": "Wat is een {{title}}?"
+ }
+ },
+ "convertTimeToSeconds": {
+ "description": "Converteer de geformatteerde tijd (UU:MM:SS) naar seconden.",
+ "inputTitle": "Invoertijd",
+ "resultTitle": "Seconden",
+ "shortDescription": "Tijdformaat naar seconden converteren",
+ "title": "Tijd naar seconden converteren",
+ "toolInfo": {
+ "description": "Met deze tool kun je geformatteerde tijdreeksen (UU:MM:SS) omzetten naar seconden. Dit is handig voor het berekenen van tijdsduren en tijdsintervallen.",
+ "title": "Tijd naar seconden converteren"
+ }
+ },
+ "crontabGuru": {
+ "description": "Genereer en begrijp cron-expressies. Maak cron-schema's voor geautomatiseerde taken en systeemtaken.",
+ "shortDescription": "Genereer en begrijp cron-expressies",
+ "title": "Crontab-goeroe"
+ },
+ "timeBetweenDates": {
+ "description": "Bereken het tijdsverschil tussen twee datums. Bereken de exacte duur in dagen, uren, minuten en seconden.",
+ "endDate": "Einddatum",
+ "endDateTime": "Einddatum en -tijd",
+ "endTime": "Eindtijd",
+ "endTimezone": "Eindtijdzone",
+ "shortDescription": "Bereken de tijd tussen twee data",
+ "startDate": "Startdatum",
+ "startDateTime": "Startdatum en -tijd",
+ "startTime": "Starttijd",
+ "startTimezone": "Starttijdzone",
+ "title": "Tijd tussen data",
+ "toolInfo": {
+ "description": "Bereken het exacte tijdsverschil tussen twee datums en tijden, met ondersteuning voor verschillende tijdzones. Deze tool biedt een gedetailleerde weergave van het tijdsverschil in verschillende eenheden (jaren, maanden, dagen, uren, minuten en seconden).",
+ "title": "Tijd tussen datums calculator"
+ }
+ },
+ "truncateClockTime": {
+ "description": "Kort de kloktijd in om seconden of minuten te verwijderen. Rond de tijd af naar het dichtstbijzijnde uur, minuut of aangepaste interval.",
+ "printDroppedComponents": "Afdrukken van verwijderde componenten",
+ "shortDescription": "De kloktijd afkappen tot de opgegeven precisie",
+ "timePadding": "Tijdvulling",
+ "title": "Kloktijd afkappen",
+ "toolInfo": {
+ "title": "Wat is een {{title}}?"
+ },
+ "truncateMinutesAndSeconds": "Minuten en seconden afkappen",
+ "truncateMinutesAndSecondsDescription": "Laat beide componenten โ de minuten en seconden โ van elke kloktijd weg.",
+ "truncateOnlySeconds": "Alleen seconden afkappen",
+ "truncateOnlySecondsDescription": "Verwijder het secondecomponent van elke kloktijd.",
+ "truncationSide": "Afkappingszijde",
+ "useZeroPadding": "Gebruik nulvulling",
+ "zeroPaddingDescription": "Zorg ervoor dat alle tijdcomponenten altijd twee cijfers breed zijn.",
+ "zeroPrintDescription": "Geef de verwijderde onderdelen weer als nulwaarden \"00\".",
+ "zeroPrintTruncatedParts": "Afgekapte onderdelen zonder afdrukken"
+ }
+}
diff --git a/public/locales/nl/translation.json b/public/locales/nl/translation.json
new file mode 100644
index 0000000..6e463d5
--- /dev/null
+++ b/public/locales/nl/translation.json
@@ -0,0 +1,250 @@
+{
+ "audio": {
+ "changeSpeed": {
+ "description": "Wijzig de afspeelsnelheid van audiobestanden. Versnel of vertraag audio met behoud van toonhoogte.",
+ "name": "Wijzig audiosnelheid",
+ "shortDescription": "De snelheid van audiobestanden wijzigen"
+ },
+ "extractAudio": {
+ "description": "Haal het audiospoor uit een videobestand en sla het op als een afzonderlijk audiobestand in het door u gekozen formaat (AAC, MP3, WAV).",
+ "name": "Audio extraheren",
+ "shortDescription": "Extraheer audio uit videobestanden (MP4, MOV, enz.) naar AAC, MP3 of WAV."
+ }
+ },
+ "baseFileInput": {
+ "copyFailed": "Kopiรซren mislukt: {{error}}",
+ "dropFileHere": "Laat je vallen {{type}} hier",
+ "fileCopied": "Bestand gekopieerd",
+ "selectFileDescription": "Klik hier om een te selecteren {{type}} Druk vanaf uw apparaat op Ctrl+V om een {{type}} vanaf uw klembord, of sleep en zet een bestand neer vanaf uw bureaublad"
+ },
+ "categories": {
+ "audio": {
+ "description": "Hulpmiddelen voor het werken met audio: audio uit video extraheren, de audiosnelheid aanpassen, meerdere audiobestanden samenvoegen en nog veel meer.",
+ "title": "Audio-hulpmiddelen"
+ },
+ "csv": {
+ "description": "Hulpmiddelen voor het werken met CSV-bestanden: converteer CSV naar verschillende formaten, manipuleer CSV-gegevens, valideer de CSV-structuur en verwerk CSV-bestanden efficiรซnt.",
+ "title": "CSV-hulpmiddelen"
+ },
+ "gif": {
+ "description": "Hulpmiddelen voor het werken met GIF-animaties: maak transparante GIF's, extraheer GIF-frames, voeg tekst toe aan GIF, snijd GIF's bij, draai ze, draai ze om en nog veel meer.",
+ "title": "GIF-hulpmiddelen"
+ },
+ "image-generic": {
+ "description": "Hulpmiddelen voor het werken met afbeeldingen: comprimeren, formaat wijzigen, bijsnijden, converteren naar JPG, roteren, achtergrond verwijderen en nog veel meer.",
+ "title": "Afbeeldingshulpmiddelen"
+ },
+ "json": {
+ "description": "Hulpmiddelen voor het werken met JSON-datastructuren: JSON-objecten mooier maken en verkleinen, JSON-arrays afvlakken, JSON-waarden stringen, gegevens analyseren en nog veel meer",
+ "title": "JSON-hulpmiddelen"
+ },
+ "list": {
+ "description": "Hulpmiddelen voor het werken met lijsten: lijsten sorteren, omkeren, willekeurig maken, unieke en dubbele listitems vinden, listitemscheidingstekens wijzigen en nog veel meer.",
+ "title": "Lijsthulpmiddelen"
+ },
+ "number": {
+ "description": "Hulpmiddelen voor het werken met getallen: genereer getallenreeksen, converteer getallen naar woorden en woorden naar getallen, sorteer, rond af, ontbind getallen en nog veel meer.",
+ "title": "Getallenhulpmiddelen"
+ },
+ "pdf": {
+ "description": "Hulpmiddelen voor het werken met PDF-bestanden: tekst uit PDF's extraheren, PDF's naar andere formaten converteren, PDF's bewerken en nog veel meer.",
+ "title": "PDF-hulpmiddelen"
+ },
+ "png": {
+ "description": "Hulpmiddelen voor het werken met PNG-afbeeldingen: converteer PNG's naar JPG's, maak transparante PNG's, wijzig PNG-kleuren, snijd PNG's bij, roteer ze, wijzig de grootte ervan en nog veel meer.",
+ "title": "PNG-hulpmiddelen"
+ },
+ "seeAll": "Bekijk alles {{title}}",
+ "string": {
+ "description": "Hulpmiddelen voor het werken met tekst: tekst naar afbeeldingen converteren, tekst zoeken en vervangen, tekst in fragmenten splitsen, tekstregels samenvoegen, tekst herhalen en nog veel meer.",
+ "title": "Teksthulpmiddelen"
+ },
+ "time": {
+ "description": "Hulpmiddelen voor het werken met tijd en datum: bereken tijdsverschillen, converteer tussen tijdzones, formatteer datums, genereer datumreeksen en nog veel meer.",
+ "title": "Tijdhulpmiddelen"
+ },
+ "try": "Poging {{title}}",
+ "video": {
+ "description": "Hulpmiddelen voor het werken met video's: frames uit video's halen, GIF's van video's maken, video's naar verschillende formaten converteren en nog veel meer.",
+ "title": "Videotools"
+ },
+ "xml": {
+ "description": "Hulpmiddelen voor het werken met XML-datastructuren - viewer, beautifier, validator en nog veel meer",
+ "title": "XML-hulpmiddelen"
+ }
+ },
+ "csv": {
+ "findIncompleteCsvRecords": {
+ "description": "Upload uw CSV-bestand via onderstaand formulier en deze tool controleert automatisch of er geen waarden in de rijen of kolommen ontbreken. In de toolopties kunt u de opmaak van het invoerbestand aanpassen (het scheidingsteken, de aanhalingstekens en het commentaarteken opgeven). Daarnaast kunt u de controle op lege waarden inschakelen, lege regels overslaan en een limiet instellen voor het aantal foutmeldingen in de uitvoer.",
+ "name": "Onvolledige CSV-records vinden",
+ "shortDescription": "Vind snel rijen en kolommen in CSV waar waarden ontbreken."
+ }
+ },
+ "hero": {
+ "brand": "OmniTools",
+ "description": "Verhoog je productiviteit met OmniTools, de ultieme toolkit om snel aan de slag te gaan! Krijg toegang tot duizenden gebruiksvriendelijke tools voor het bewerken van afbeeldingen, tekst, lijsten en gegevens, allemaal rechtstreeks vanuit je browser.",
+ "examples": {
+ "calculateNumberSum": "Bereken de getallensom",
+ "changeGifSpeed": "GIF-snelheid wijzigen",
+ "compressPng": "PNG comprimeren",
+ "createTransparentImage": "Een transparante afbeelding maken",
+ "prettifyJson": "JSON verfraaien",
+ "sortList": "Een lijst sorteren",
+ "splitPdf": "PDF splitsen",
+ "splitText": "Een tekst splitsen",
+ "trimVideo": "Video bijsnijden"
+ },
+ "searchPlaceholder": "Zoek in alle tools",
+ "title": "Krijg dingen snel gedaan met"
+ },
+ "inputFooter": {
+ "clear": "Duidelijk",
+ "copyToClipboard": "Kopiรซren naar klembord",
+ "importFromFile": "Importeren uit bestand"
+ },
+ "list": {
+ "group": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het groeperen van lijstitems. Voer uw lijst in en specificeer groeperingscriteria om items in logische groepen te ordenen. Perfect voor het categoriseren van gegevens, het organiseren van informatie of het maken van gestructureerde lijsten. Ondersteunt aangepaste scheidingstekens en diverse groeperingsopties.",
+ "name": "Groep",
+ "shortDescription": "Groepeer lijstitems op basis van gemeenschappelijke eigenschappen"
+ },
+ "reverse": {
+ "description": "Dit is een supereenvoudige browsergebaseerde applicatie die alle items in de lijst in spiegelbeeld afdrukt. De invoeritems kunnen worden gescheiden door een willekeurig symbool en u kunt ook de scheidingstekens van de omgekeerde items in de lijst wijzigen.",
+ "name": "Achteruit",
+ "shortDescription": "Snel een lijst omkeren"
+ },
+ "sort": {
+ "description": "Dit is een supereenvoudige browsergebaseerde applicatie die items in een lijst sorteert en in oplopende of aflopende volgorde rangschikt. U kunt de items alfabetisch, numeriek of op lengte sorteren. U kunt ook dubbele en lege items verwijderen, en afzonderlijke items met witruimte eromheen verwijderen. U kunt elk scheidingsteken gebruiken om de items in de invoerlijst te scheiden, of u kunt een reguliere expressie gebruiken om ze te scheiden. Daarnaast kunt u een nieuw scheidingsteken maken voor de gesorteerde uitvoerlijst.",
+ "name": "Soort",
+ "shortDescription": "Snel een lijst sorteren"
+ }
+ },
+ "navbar": {
+ "buyMeACoffee": "Koop me een koffie",
+ "home": "Thuis",
+ "tools": "Hulpmiddelen"
+ },
+ "number": {
+ "generate": {
+ "description": "Bereken snel een lijst met gehele getallen in uw browser. Om uw lijst te verkrijgen, specificeert u het eerste gehele getal, wijzigt u de waarde en het totale aantal in de onderstaande opties, en deze tool genereert dat aantal gehele getallen.",
+ "name": "Genereer getallen",
+ "shortDescription": "Bereken snel een lijst met gehele getallen in uw browser"
+ },
+ "sum": {
+ "description": "Dit is een supereenvoudige browserapplicatie die getallen optelt. De ingevoerde getallen kunnen worden gescheiden door een willekeurig symbool en je kunt ook het scheidingsteken van de opgetelde getallen wijzigen.",
+ "name": "Som getallen",
+ "shortDescription": "Snel een lijst met getallen optellen"
+ }
+ },
+ "numericInputWithUnit": {
+ "unit": "Eenheid"
+ },
+ "pdf": {
+ "compressPdf": {
+ "description": "Verklein de PDF-bestandsgrootte met behoud van kwaliteit met Ghostscript",
+ "name": "PDF comprimeren",
+ "shortDescription": "Comprimeer PDF-bestanden veilig in uw browser"
+ },
+ "mergePdf": {
+ "description": "Combineer meerdere PDF-bestanden tot รฉรฉn document.",
+ "name": "PDF samenvoegen",
+ "shortDescription": "Meerdere PDF-bestanden samenvoegen tot รฉรฉn document"
+ },
+ "pdfToEpub": {
+ "description": "Transformeer PDF-documenten naar EPUB-bestanden voor betere compatibiliteit met e-readers.",
+ "name": "PDF naar EPUB",
+ "shortDescription": "PDF-bestanden converteren naar EPUB-formaat"
+ },
+ "protectPdf": {
+ "description": "Voeg wachtwoordbeveiliging toe aan uw PDF-bestanden veilig in uw browser",
+ "name": "PDF beschermen",
+ "shortDescription": "PDF-bestanden veilig met een wachtwoord beveiligen"
+ },
+ "splitPdf": {
+ "description": "Specifieke pagina's uit een PDF-bestand extraheren met behulp van paginanummers of bereiken (bijv. 1, 5-8)",
+ "name": "PDF splitsen",
+ "shortDescription": "Specifieke pagina's uit een PDF-bestand extraheren"
+ }
+ },
+ "resultFooter": {
+ "copy": "Kopiรซren naar klembord",
+ "download": "Download"
+ },
+ "string": {
+ "createPalindrome": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde tool voor het maken van palindromen van elke tekst. Voer tekst in en transformeer deze direct in een palindroom die zowel van voor naar achter als van achter naar voren hetzelfde leest. Perfect voor woordspelletjes, het creรซren van symmetrische tekstpatronen of het verkennen van taalkundige curiosa.",
+ "name": "Palindroom maken",
+ "shortDescription": "Maak een tekst die van voor naar achter en van achter naar voren hetzelfde leest"
+ },
+ "palindrome": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma om te controleren of tekst een palindroom is. Controleer direct of uw tekst van voor naar achteren hetzelfde leest. Perfect voor woordpuzzels, taalkundige analyses of het valideren van symmetrische tekstpatronen. Ondersteunt diverse scheidingstekens en palindroomdetectie van meerdere woorden.",
+ "name": "Palindroom",
+ "shortDescription": "Controleren of de tekst van voor naar achter hetzelfde leest"
+ },
+ "repeat": {
+ "description": "Met deze tool kunt u een bepaalde tekst meerdere keren herhalen met een optionele scheidingsteken.",
+ "name": "Herhaal tekst",
+ "shortDescription": "Herhaal de tekst meerdere keren"
+ },
+ "reverse": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het omkeren van tekst. Voer tekst in en laat deze direct omkeren, teken voor teken. Perfect voor het maken van spiegeltekst, het analyseren van palindromen of het experimenteren met tekstpatronen. Spaties en speciale tekens blijven behouden tijdens het omkeren.",
+ "name": "Achteruit",
+ "shortDescription": "Elke tekst teken voor teken omdraaien"
+ },
+ "toMorse": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het converteren van tekst naar morsecode. Laad uw tekst in het invoerveld aan de linkerkant en u krijgt direct morsecode in het uitvoergebied. Krachtig, gratis en snel. Laad tekst โ ontvang morsecode.",
+ "name": "String naar morse",
+ "shortDescription": "Snel tekst naar morse coderen"
+ },
+ "uppercase": {
+ "description": "'s Werelds eenvoudigste browsergebaseerde hulpprogramma voor het omzetten van tekst naar hoofdletters. Voer uw tekst in en deze wordt automatisch omgezet naar alleen hoofdletters. Perfect voor het maken van koppen, het benadrukken van tekst of het standaardiseren van tekstopmaak. Ondersteunt diverse tekstformaten en behoudt speciale tekens.",
+ "name": "Hoofdletters",
+ "shortDescription": "Tekst naar hoofdletters converteren"
+ }
+ },
+ "toolExamples": {
+ "subtitle": "Klik om te proberen!",
+ "title": "{{title}} Voorbeelden"
+ },
+ "toolFileResult": {
+ "copied": "Bestand gekopieerd",
+ "copyFailed": "Kopiรซren mislukt: {{error}}",
+ "loading": "Bezig met laden... Dit kan even duren.",
+ "result": "Resultaat"
+ },
+ "toolHeader": {
+ "seeExamples": "Zie voorbeelden"
+ },
+ "toolLayout": {
+ "allToolsTitle": "Alle {{type}}"
+ },
+ "toolMultiFileResult": {
+ "copied": "Bestand gekopieerd",
+ "copyFailed": "Kopiรซren mislukt: {{error}}",
+ "loading": "Bezig met laden... Dit kan even duren.",
+ "result": "Resultaat"
+ },
+ "toolMultipleAudioInput": {
+ "inputTitle": "Invoer {{type}}",
+ "noFilesSelected": "Geen bestanden geselecteerd"
+ },
+ "toolMultiplePdfInput": {
+ "inputTitle": "Invoer {{type}}",
+ "noFilesSelected": "Geen bestanden geselecteerd"
+ },
+ "toolOptions": {
+ "title": "Gereedschapsopties"
+ },
+ "toolTextInput": {
+ "copied": "Tekst gekopieerd",
+ "copyFailed": "Kopiรซren mislukt: {{error}}",
+ "input": "Invoertekst",
+ "placeholder": "Voer hier uw tekst in..."
+ },
+ "toolTextResult": {
+ "copied": "Tekst gekopieerd",
+ "copyFailed": "Kopiรซren mislukt: {{error}}",
+ "loading": "Bezig met laden... Dit kan even duren.",
+ "result": "Resultaat"
+ }
+}
diff --git a/public/locales/nl/video.json b/public/locales/nl/video.json
new file mode 100644
index 0000000..9a7571b
--- /dev/null
+++ b/public/locales/nl/video.json
@@ -0,0 +1,113 @@
+{
+ "changeSpeed": {
+ "defaultMultiplier": "Standaardvermenigvuldiger: 2 betekent 2x sneller",
+ "description": "Wijzig de afspeelsnelheid van videobestanden. Versnel of vertraag video's met behoud van audiosynchronisatie. Ondersteunt diverse snelheidsvermenigvuldigers en gangbare videoformaten.",
+ "inputTitle": "Invoervideo",
+ "newVideoSpeed": "Nieuwe videosnelheid",
+ "resultTitle": "Bewerkte video",
+ "settingSpeed": "Snelheid instellen",
+ "shortDescription": "Wijzig de afspeelsnelheid van video",
+ "title": "Videosnelheid wijzigen",
+ "toolInfo": {
+ "title": "Wat is een {{title}}?"
+ }
+ },
+ "compress": {
+ "default": "Standaard",
+ "description": "Comprimeer video's door ze te schalen naar verschillende resoluties, zoals 240p, 480p, 720p, enz. Deze tool helpt de bestandsgrootte te verkleinen met behoud van een acceptabele kwaliteit. Ondersteunt gangbare videoformaten zoals MP4, WebM en OGG.",
+ "inputTitle": "Invoervideo",
+ "loadingText": "Video comprimeren...",
+ "lossless": "Verliesloos",
+ "quality": "Kwaliteit (CRF)",
+ "resolution": "Oplossing",
+ "resultTitle": "Gecomprimeerde video",
+ "shortDescription": "Comprimeer video's door te schalen naar verschillende resoluties",
+ "title": "Video comprimeren",
+ "worst": "Slechtst"
+ },
+ "cropVideo": {
+ "cropCoordinates": "Gewascoรถrdinaten",
+ "croppingVideo": "Video bijsnijden",
+ "description": "Snijd de video bij om ongewenste delen te verwijderen.",
+ "errorBeyondHeight": "Het gewasgebied strekt zich uit voorbij de videohoogte ({{height}}px)",
+ "errorBeyondWidth": "Het bijsnijdgebied is groter dan de videobreedte ({{width}}px)",
+ "errorCroppingVideo": "Fout bij het bijsnijden van de video. Controleer de parameters en het videobestand.",
+ "errorLoadingDimensions": "Het laden van de video-afmetingen is mislukt",
+ "errorNonNegativeCoordinates": "X- en Y-coรถrdinaten moeten niet-negatief zijn",
+ "errorPositiveDimensions": "Breedte en hoogte moeten positief zijn",
+ "height": "Hoogte",
+ "inputTitle": "Invoervideo",
+ "loadVideoForDimensions": "Laad een video om de afmetingen te zien",
+ "resultTitle": "Bijgesneden video",
+ "shortDescription": "Video bijsnijden om ongewenste gebieden te verwijderen",
+ "title": "Bijsnijden Video",
+ "toolInfo": {
+ "description": "Met deze tool kunt u videobestanden bijsnijden om ongewenste delen te verwijderen. U kunt het bijsnijdgebied specificeren door de X- en Y-coรถrdinaten en de breedte- en hoogte-afmetingen in te stellen.",
+ "title": "Bijsnijden Video"
+ },
+ "videoDimensions": "Video-afmetingen: {{width}} ร {{height}} pixels",
+ "videoInformation": "Video-informatie",
+ "width": "Breedte",
+ "xCoordinate": "X (links)",
+ "yCoordinate": "Y (boven)"
+ },
+ "flip": {
+ "description": "Draai videobestanden horizontaal of verticaal. Spiegel video's voor speciale effecten of om problemen met de oriรซntatie te corrigeren.",
+ "flippingVideo": "Flipping Video",
+ "horizontalLabel": "Horizontaal (Spiegel)",
+ "inputTitle": "Invoervideo",
+ "orientation": "Oriรซntatie",
+ "resultTitle": "Omgedraaide video",
+ "shortDescription": "Video horizontaal of verticaal spiegelen",
+ "title": "Flip Video",
+ "verticalLabel": "Verticaal (op zijn kop)"
+ },
+ "gif": {
+ "changeSpeed": {
+ "description": "Wijzig de afspeelsnelheid van GIF-animaties. Versnel of vertraag GIF's met behoud van vloeiende animaties.",
+ "shortDescription": "Verander de GIF-animatiesnelheid",
+ "title": "GIF-snelheid wijzigen"
+ }
+ },
+ "loop": {
+ "description": "Maak een herhalende video door de originele video meerdere keren te herhalen.",
+ "inputTitle": "Invoervideo",
+ "loopingVideo": "Video herhalen",
+ "loops": "Lussen",
+ "numberOfLoops": "Aantal lussen",
+ "resultTitle": "Geloopte video",
+ "shortDescription": "Maak herhalende videobestanden",
+ "title": "Loop-video",
+ "toolInfo": {
+ "description": "Met deze tool kun je een herhalende video maken door de originele video meerdere keren te herhalen. Je kunt zelf aangeven hoe vaak de video moet worden herhaald.",
+ "title": "Wat is een {{title}}?"
+ }
+ },
+ "rotate": {
+ "180Degrees": "180ยฐ (op zijn kop)",
+ "270Degrees": "270ยฐ (90ยฐ tegen de klok in)",
+ "90Degrees": "90ยฐ met de klok mee",
+ "description": "Roteer videobestanden 90, 180 of 270 graden. Corrigeer de video-oriรซntatie of creรซer speciale effecten met nauwkeurige rotatiecontrole.",
+ "inputTitle": "Invoervideo",
+ "resultTitle": "Gedraaide video",
+ "rotatingVideo": "Roterende video",
+ "rotation": "Rotatie",
+ "shortDescription": "Video met opgegeven graden roteren",
+ "title": "Video roteren"
+ },
+ "trim": {
+ "description": "Trim videobestanden door begin- en eindtijden op te geven. Verwijder ongewenste delen aan het begin of einde van video's.",
+ "endTime": "Eindtijd",
+ "inputTitle": "Invoervideo",
+ "resultTitle": "Bijgesneden video",
+ "shortDescription": "Video bijsnijden door ongewenste delen te verwijderen",
+ "startTime": "Starttijd",
+ "timestamps": "Tijdstempels",
+ "title": "Video bijsnijden"
+ },
+ "videoToGif": {
+ "description": "Converteer videobestanden naar geanimeerde GIF-indeling. Extraheer specifieke tijdsperioden en maak deelbare geanimeerde afbeeldingen.",
+ "shortDescription": "Converteer video naar geanimeerde GIF",
+ "title": "Video naar GIF"
+ }
+}
diff --git a/public/locales/nl/xml.json b/public/locales/nl/xml.json
new file mode 100644
index 0000000..17d0841
--- /dev/null
+++ b/public/locales/nl/xml.json
@@ -0,0 +1,38 @@
+{
+ "xmlBeautifier": {
+ "description": "Formatteer XML met de juiste inspringing en spatie.",
+ "indentation": "Inspringing",
+ "inputTitle": "Invoer XML",
+ "resultTitle": "Verfraaide XML",
+ "shortDescription": "XML-code opmaken en verfraaien",
+ "title": "XML-verfraaier",
+ "toolInfo": {
+ "description": "Met deze tool kunt u XML-gegevens opmaken met de juiste inspringing en spaties, waardoor ze beter leesbaar worden en u er gemakkelijker mee kunt werken.",
+ "title": "XML-verfraaier"
+ },
+ "useSpaces": "Gebruik spaties",
+ "useSpacesDescription": "Uitvoer inspringen met spaties",
+ "useTabs": "Tabbladen gebruiken",
+ "useTabsDescription": "Uitvoer inspringen met tabs."
+ },
+ "xmlValidator": {
+ "description": "Valideer XML-syntaxis en -structuur.",
+ "placeholder": "Plak of importeer hier XML...",
+ "shortDescription": "XML-code valideren op fouten",
+ "title": "XML-validator",
+ "toolInfo": {
+ "description": "Met deze tool kunt u de XML-syntaxis en -structuur valideren. De tool controleert of de XML correct is opgemaakt en geeft gedetailleerde foutmeldingen bij gevonden problemen.",
+ "title": "XML-validator"
+ }
+ },
+ "xmlViewer": {
+ "description": "Bekijk en verken de XML-structuur in een boomstructuur.",
+ "inputTitle": "Invoer XML",
+ "resultTitle": "XML-boomweergave",
+ "title": "XML-viewer",
+ "toolInfo": {
+ "description": "Met deze tool kunt u XML-gegevens in een hiรซrarchische boomstructuur bekijken, waardoor u de structuur van XML-documenten eenvoudiger kunt verkennen en begrijpen.",
+ "title": "XML-viewer"
+ }
+ }
+}
diff --git a/public/locales/pt/audio.json b/public/locales/pt/audio.json
new file mode 100644
index 0000000..568d31e
--- /dev/null
+++ b/public/locales/pt/audio.json
@@ -0,0 +1,42 @@
+{
+ "changeSpeed": {
+ "description": "Altere a velocidade de reproduรงรฃo dos arquivos de รกudio. Acelere ou desacelere o รกudio, mantendo o tom.",
+ "inputTitle": "รudio de entrada",
+ "newAudioSpeed": "Nova velocidade de รกudio",
+ "outputFormat": "Formato de saรญda",
+ "resultTitle": "รudio editado",
+ "settingSpeed": "Definindo a velocidade",
+ "shortDescription": "Alterar a velocidade dos arquivos de รกudio",
+ "speedDescription": "Multiplicador padrรฃo: 2 significa 2x mais rรกpido",
+ "title": "Alterar velocidade do รกudio",
+ "toolInfo": {
+ "title": "O que รฉ {{title}}?"
+ }
+ },
+ "extractAudio": {
+ "description": "Extraia faixas de รกudio de arquivos de vรญdeo.",
+ "extractingAudio": "Extraindo รกudio",
+ "inputTitle": "Entrada de vรญdeo",
+ "outputFormat": "Formato de saรญda",
+ "outputFormatDescription": "Selecione o formato para o รกudio ser extraรญdo.",
+ "resultTitle": "รudio extraรญdo",
+ "shortDescription": "Extraia รกudio de arquivos de vรญdeo (MP4, MOV, etc.) para AAC, MP3 ou WAV.",
+ "title": "Extrair รกudio de vรญdeo",
+ "toolInfo": {
+ "description": "Esta ferramenta permite extrair a faixa de รกudio de arquivos de vรญdeo. Vocรช pode escolher entre diferentes formatos de รกudio, incluindo AAC, MP3 e WAV.",
+ "title": "O que รฉ {{title}}?"
+ }
+ },
+ "mergeAudio": {
+ "description": "Combine vรกrios arquivos de รกudio em um รบnico arquivo de รกudio concatenando-os em sequรชncia.",
+ "longDescription": "Esta ferramenta permite mesclar vรกrios arquivos de รกudio em um รบnico arquivo, concatenando-os na ordem em que foram enviados. Perfeito para combinar segmentos de podcast, faixas de mรบsica ou qualquer arquivo de รกudio que precise ser unido. Suporta vรกrios formatos de รกudio, incluindo MP3, AAC e WAV.",
+ "shortDescription": "Mescle vรกrios arquivos de รกudio em um (MP3, AAC, WAV).",
+ "title": "Mesclar รกudio"
+ },
+ "trim": {
+ "description": "Corte e apare arquivos de รกudio para extrair segmentos especรญficos, especificando horรกrios de inรญcio e tรฉrmino.",
+ "longDescription": "Esta ferramenta permite cortar arquivos de รกudio especificando os tempos de inรญcio e tรฉrmino. Vocรช pode extrair segmentos especรญficos de arquivos de รกudio mais longos, remover partes indesejadas ou criar clipes mais curtos. Suporta vรกrios formatos de รกudio, incluindo MP3, AAC e WAV. Perfeito para ediรงรฃo de podcasts, produรงรฃo musical ou qualquer necessidade de ediรงรฃo de รกudio.",
+ "shortDescription": "Corte arquivos de รกudio para extrair segmentos de tempo especรญficos (MP3, AAC, WAV).",
+ "title": "Aparar รกudio"
+ }
+}
diff --git a/public/locales/pt/csv.json b/public/locales/pt/csv.json
new file mode 100644
index 0000000..6b8a2be
--- /dev/null
+++ b/public/locales/pt/csv.json
@@ -0,0 +1,114 @@
+{
+ "changeCsvSeparator": {
+ "description": "Altere o delimitador/separador em arquivos CSV. Converta entre diferentes formatos CSV, como vรญrgula, ponto e vรญrgula, tabulaรงรฃo ou separadores personalizados.",
+ "shortDescription": "Alterar delimitador de arquivo CSV",
+ "title": "Alterar separador CSV"
+ },
+ "csvRowsToColumns": {
+ "description": "Esta ferramenta converte linhas de um arquivo CSV (Valores Separados por Vรญrgula) em colunas. Ela extrai as linhas horizontais do arquivo CSV de entrada, uma a uma, gira-as 90 graus e as gera como colunas verticais, uma apรณs a outra, separadas por vรญrgulas.', longDescription: 'Esta ferramenta converte linhas de um arquivo CSV (Valores Separados por Vรญrgula) em colunas. Por exemplo, se os dados CSV de entrada tiverem 6 linhas, a saรญda terรก 6 colunas e os elementos das linhas serรฃo organizados de cima para baixo. Em um CSV bem formado, o nรบmero de valores em cada linha รฉ o mesmo. No entanto, nos casos em que as linhas nรฃo possuem campos, o programa pode corrigi-los e vocรช pode escolher entre as opรงรตes disponรญveis: preencher os dados ausentes com elementos vazios ou substituir os dados ausentes por elementos personalizados, como \"ausente\", \"?\" ou \"x\". Durante o processo de conversรฃo, a ferramenta tambรฉm limpa o arquivo CSV de informaรงรตes desnecessรกrias, como linhas vazias (linhas sem informaรงรตes visรญveis) e comentรกrios. Para ajudar a ferramenta a identificar corretamente os comentรกrios, nas opรงรตes, vocรช pode especificar o sรญmbolo no inรญcio de uma linha que inicia um comentรกrio. Este sรญmbolo normalmente รฉ um hash \"#\" ou uma barra dupla \"//\". Csv-abulous!.",
+ "longDescription": "Esta ferramenta converte linhas de um arquivo CSV (Valores Separados por Vรญrgula) em colunas. Por exemplo, se os dados CSV de entrada tiverem 6 linhas, a saรญda terรก 6 colunas e os elementos das linhas serรฃo organizados de cima para baixo. Em um CSV bem formado, o nรบmero de valores em cada linha รฉ o mesmo. No entanto, nos casos em que as linhas nรฃo possuem campos, o programa pode corrigi-los e vocรช pode escolher entre as opรงรตes disponรญveis: preencher os dados ausentes com elementos vazios ou substituir os dados ausentes por elementos personalizados, como",
+ "shortDescription": "Converter linhas CSV em colunas.",
+ "title": "Converter linhas CSV em colunas"
+ },
+ "csvToJson": {
+ "columnSeparator": "Separador de coluna (por exemplo, , ; \\t)",
+ "commentSymbol": "Sรญmbolo de comentรกrio (por exemplo, #)",
+ "conversionOptions": "Opรงรตes de conversรฃo",
+ "description": "Converta arquivos CSV para o formato JSON com opรงรตes personalizรกveis para delimitadores, aspas e formataรงรฃo de saรญda. Suporte para cabeรงalhos, comentรกrios e conversรฃo dinรขmica de tipos.",
+ "dynamicTypes": "Tipos dinรขmicos",
+ "dynamicTypesDescription": "Converta nรบmeros e booleanos automaticamente",
+ "errorParsing": "Erro ao analisar CSV: {{error}}",
+ "fieldQuote": "Citaรงรฃo de campo (por exemplo, \")",
+ "inputCsvFormat": "Formato CSV de entrada",
+ "inputTitle": "Entrada CSV",
+ "resultTitle": "Saรญda JSON",
+ "shortDescription": "Converta dados CSV para o formato JSON.",
+ "skipEmptyLines": "Pular linhas vazias",
+ "skipEmptyLinesDescription": "Ignorar linhas vazias no CSV de entrada",
+ "title": "Converter CSV para JSON",
+ "useHeaders": "Usar Cabeรงalhos",
+ "useHeadersDescription": "Tratar a primeira linha como cabeรงalhos de coluna"
+ },
+ "csvToTsv": {
+ "description": "Carregue seu arquivo CSV no formulรกrio abaixo e ele serรก convertido automaticamente para um arquivo TSV. Nas opรงรตes da ferramenta, vocรช pode personalizar o formato CSV de entrada โ especificar o delimitador de campo, o caractere de aspas e o sรญmbolo de comentรกrio, alรฉm de pular linhas CSV vazias e escolher se deseja preservar os cabeรงalhos das colunas CSV.",
+ "longDescription": "Esta ferramenta transforma dados de Valores Separados por Vรญrgula (CSV) em dados de Valores Separados por Tabulaรงรฃo (TSV). CSV e TSV sรฃo formatos de arquivo populares para armazenar dados tabulares, mas usam delimitadores diferentes para separar valores โ CSV usa vรญrgulas (",
+ "shortDescription": "Converter dados CSV para o formato TSV.",
+ "title": "Converter CSV para TSV"
+ },
+ "csvToXml": {
+ "description": "Converta arquivos CSV para o formato XML com opรงรตes personalizรกveis.",
+ "shortDescription": "Converta dados CSV para o formato XML.",
+ "title": "Converter CSV para XML"
+ },
+ "csvToYaml": {
+ "description": "Basta enviar seu arquivo CSV no formulรกrio abaixo e ele serรก convertido automaticamente para um arquivo YAML. Nas opรงรตes da ferramenta, vocรช pode especificar o caractere delimitador de campo, o caractere de aspas de campo e o caractere de comentรกrio para adaptar a ferramenta a formatos CSV personalizados. Alรฉm disso, vocรช pode selecionar o formato YAML de saรญda: um que preserva os cabeรงalhos CSV ou um que exclui os cabeรงalhos CSV.",
+ "longDescription": "Esta ferramenta transforma dados CSV (Valores Separados por Vรญrgula) em dados YAML (Yet Another Markup Language). CSV รฉ um formato tabular simples usado para representar tipos de dados matriciais, compostos por linhas e colunas. YAML, por outro lado, รฉ um formato mais avanรงado (na verdade, um superconjunto de JSON), que cria dados mais legรญveis para serializaรงรฃo e oferece suporte a listas, dicionรกrios e objetos aninhados. Este programa oferece suporte a vรกrios formatos CSV de entrada โ os dados de entrada podem ser separados por vรญrgula (padrรฃo), ponto e vรญrgula, barra vertical ou usar outro delimitador completamente diferente. Vocรช pode especificar o delimitador exato que seus dados usam nas opรงรตes. Da mesma forma, nas opรงรตes, vocรช pode especificar o caractere de aspas usado para quebrar campos CSV (por padrรฃo, um sรญmbolo de aspas duplas). Vocรช tambรฉm pode pular linhas que comeรงam com comentรกrios, especificando os sรญmbolos de comentรกrio nas opรงรตes. Isso permite que vocรช mantenha seus dados limpos, pulando linhas desnecessรกrias. Hรก duas maneiras de converter CSV para YAML. O primeiro mรฉtodo converte cada linha CSV em uma lista YAML. O segundo mรฉtodo extrai cabeรงalhos da primeira linha CSV e cria objetos YAML com chaves baseadas nesses cabeรงalhos. Vocรช tambรฉm pode personalizar o formato YAML de saรญda especificando o nรบmero de espaรงos para recuar as estruturas YAML. Se precisar realizar a conversรฃo reversa, ou seja, transformar YAML em CSV, vocรช pode usar nossa ferramenta Converter YAML para CSV. CSV-abulous!",
+ "shortDescription": "Converta rapidamente um arquivo CSV em um arquivo YAML.",
+ "title": "Converter CSV para YAML"
+ },
+ "findIncompleteCsvRecords": {
+ "checkingOptions": "Opรงรตes de verificaรงรฃo",
+ "commentCharacterDescription": "Insira o caractere que indica o inรญcio de uma linha de comentรกrio. Linhas que comeรงam com este sรญmbolo serรฃo ignoradas.",
+ "csvInputOptions": "Opรงรตes de entrada CSV",
+ "csvSeparatorDescription": "Digite o caractere usado para delimitar colunas no arquivo de entrada CSV.",
+ "deleteLinesWithNoData": "Excluir linhas sem dados",
+ "deleteLinesWithNoDataDescription": "Remova linhas vazias do arquivo de entrada CSV.",
+ "description": "Basta enviar seu arquivo CSV no formulรกrio abaixo e esta ferramenta verificarรก automaticamente se nenhuma das linhas ou colunas contรฉm valores ausentes. Nas opรงรตes da ferramenta, vocรช pode ajustar o formato do arquivo de entrada (especifique o delimitador, o caractere de aspas e o caractere de comentรกrio). Alรฉm disso, vocรช pode ativar a verificaรงรฃo de valores vazios, ignorar linhas vazias e definir um limite para o nรบmero de mensagens de erro na saรญda.",
+ "findEmptyValues": "Encontrar valores vazios",
+ "findEmptyValuesDescription": "Exibir uma mensagem sobre campos CSV que estรฃo vazios (nรฃo sรฃo campos ausentes, mas campos que nรฃo contรชm nada).",
+ "inputTitle": "Entrada CSV",
+ "limitNumberOfMessages": "Limite de nรบmero de mensagens",
+ "messageLimitDescription": "Defina o limite do nรบmero de mensagens na saรญda.",
+ "quoteCharacterDescription": "Digite o caractere de aspas usado para citar os campos de entrada CSV.",
+ "resultTitle": "Status do CSV",
+ "shortDescription": "Encontre rapidamente linhas e colunas em CSV que nรฃo tenham valores.",
+ "title": "Encontre registros CSV incompletos",
+ "toolInfo": {
+ "title": "O que รฉ um {{title}}?"
+ }
+ },
+ "insertCsvColumns": {
+ "appendColumns": "Adicionar colunas",
+ "commentCharacterDescription": "Insira o caractere que indica o inรญcio de uma linha de comentรกrio. Linhas que comeรงam com este sรญmbolo serรฃo ignoradas.",
+ "csvOptions": "Opรงรตes CSV",
+ "csvSeparator": "Separador CSV",
+ "csvToInsert": "CSV para inserir",
+ "csvToInsertDescription": "Insira uma ou mais colunas que deseja inserir no CSV. O caractere usado para delimitar as colunas deve ser o mesmo que o do arquivo CSV de entrada. Obs.: Linhas em branco serรฃo ignoradas.",
+ "customFillDescription": "Se o arquivo CSV de entrada estiver incompleto (valores ausentes), adicione campos vazios ou sรญmbolos personalizados aos registros para criar um CSV bem formado?",
+ "customFillValueDescription": "Use este valor personalizado para preencher campos ausentes. (Funciona apenas com o modo \"Valores Personalizados\" acima.)",
+ "customPosition": "Posiรงรฃo personalizada",
+ "customPositionOptionsDescription": "Selecione o mรฉtodo para inserir as colunas no arquivo CSV.",
+ "description": "Adicione novas colunas aos dados CSV em posiรงรตes especificadas.",
+ "fillWithCustomValues": "Preencher com valores alfandegรกrios",
+ "fillWithEmptyValues": "Preencher com valores vazios",
+ "headerName": "Nome do cabeรงalho",
+ "headerNameDescription": "Cabeรงalho da coluna depois da qual vocรช deseja inserir colunas.",
+ "inputTitle": "Entrada CSV",
+ "insertingPositionDescription": "Especifique onde inserir as colunas no arquivo CSV.",
+ "position": "Posiรงรฃo",
+ "positionOptions": "Opรงรตes de posiรงรฃo",
+ "prependColumns": "Prefixar colunas",
+ "quoteCharDescription": "Digite o caractere de aspas usado para citar os campos de entrada CSV.",
+ "resultTitle": "Saรญda CSV",
+ "rowNumberDescription": "Nรบmero da coluna depois da qual vocรช deseja inserir colunas.",
+ "separatorDescription": "Digite o caractere usado para delimitar colunas no arquivo de entrada CSV.",
+ "shortDescription": "Insira rapidamente uma ou mais colunas novas em qualquer lugar de um arquivo CSV.",
+ "title": "Inserir colunas CSV",
+ "toolInfo": {
+ "description": "Esta ferramenta permite inserir novas colunas em dados CSV em posiรงรตes especรญficas. Vocรช pode acrescentar, anexar ou inserir colunas em posiรงรตes personalizadas com base em nomes de cabeรงalho ou nรบmeros de coluna.",
+ "title": "Inserir colunas CSV"
+ }
+ },
+ "swapCsvColumns": {
+ "description": "Basta carregar seu arquivo CSV no formulรกrio abaixo, especificar as colunas a serem trocadas e a ferramenta alterarรก automaticamente as posiรงรตes das colunas especificadas no arquivo de saรญda. Nas opรงรตes da ferramenta, vocรช pode especificar as posiรงรตes ou nomes das colunas que deseja trocar, bem como corrigir dados incompletos e, opcionalmente, remover registros vazios e registros comentados.",
+ "longDescription": "Esta ferramenta reorganiza dados CSV trocando as posiรงรตes de suas colunas. Trocar colunas pode melhorar a legibilidade de um arquivo CSV, colocando dados usados com frequรชncia juntos ou na frente para facilitar a comparaรงรฃo e a ediรงรฃo de dados. Por exemplo, vocรช pode trocar a primeira coluna com a รบltima ou trocar a segunda coluna com a terceira. Para trocar colunas com base em suas posiรงรตes, selecione a opรงรฃo",
+ "shortDescription": "Reordene as colunas CSV.",
+ "title": "Trocar colunas CSV"
+ },
+ "transposeCsv": {
+ "description": "Basta enviar seu arquivo CSV no formulรกrio abaixo e esta ferramenta o transporรก automaticamente. Nas opรงรตes da ferramenta, vocรช pode especificar o caractere que inicia as linhas de comentรกrio no CSV para removรช-las. Alรฉm disso, se o CSV estiver incompleto (com valores ausentes), vocรช pode substituรญ-los pelo caractere vazio ou por um caractere personalizado.",
+ "longDescription": "Esta ferramenta transpรตe valores separados por vรญrgula (CSV). Ela trata o CSV como uma matriz de dados e inverte todos os elementos na diagonal principal. A saรญda contรฉm os mesmos dados CSV que a entrada, mas agora todas as linhas se tornaram colunas e todas as colunas se tornaram linhas. Apรณs a transposiรงรฃo, o arquivo CSV terรก dimensรตes opostas. Por exemplo, se o arquivo de entrada tiver 4 colunas e 3 linhas, o arquivo de saรญda terรก 3 colunas e 4 linhas. Durante a conversรฃo, o programa tambรฉm limpa os dados de linhas desnecessรกrias e corrige dados incompletos. Especificamente, a ferramenta exclui automaticamente todos os registros e comentรกrios vazios que comeรงam com um caractere especรญfico, que vocรช pode definir na opรงรฃo. Alรฉm disso, nos casos em que os dados CSV sรฃo corrompidos ou perdidos, o utilitรกrio completa o arquivo com campos vazios ou campos personalizados que podem ser especificados nas opรงรตes. CSV-abulous!",
+ "shortDescription": "Transponha rapidamente um arquivo CSV.",
+ "title": "Transpor CSV"
+ }
+}
diff --git a/public/locales/pt/image.json b/public/locales/pt/image.json
new file mode 100644
index 0000000..10ac100
--- /dev/null
+++ b/public/locales/pt/image.json
@@ -0,0 +1,98 @@
+{
+ "changeColors": {
+ "description": "Mundo",
+ "shortDescription": "Troque cores rapidamente em uma imagem",
+ "title": "Alterar cores na imagem"
+ },
+ "changeOpacity": {
+ "description": "Ajuste facilmente a transparรชncia das suas imagens. Basta carregar a sua imagem, usar o controle deslizante para definir o nรญvel de opacidade desejado entre 0 (totalmente transparente) e 1 (totalmente opaco) e baixar a imagem modificada.",
+ "shortDescription": "Ajustar a transparรชncia das imagens",
+ "title": "Alterar opacidade da imagem"
+ },
+ "compress": {
+ "description": "Reduza o tamanho do arquivo de imagem, mantendo a qualidade.",
+ "inputTitle": "Imagem de entrada",
+ "resultTitle": "Imagem compactada",
+ "shortDescription": "Compacte imagens para reduzir o tamanho do arquivo, mantendo uma qualidade razoรกvel.",
+ "title": "Comprimir imagem"
+ },
+ "compressPng": {
+ "description": "Este รฉ um programa que compacta imagens PNG. Assim que vocรช colar a imagem PNG na รกrea de entrada, o programa a compactarรก e exibirรก o resultado na รกrea de saรญda. Nas opรงรตes, vocรช pode ajustar o nรญvel de compactaรงรฃo, bem como encontrar os tamanhos de arquivo de imagem antigos e novos.",
+ "shortDescription": "Comprimir rapidamente um PNG",
+ "title": "Comprimir png"
+ },
+ "convertJgpToPng": {
+ "description": "Converta rapidamente suas imagens JPG para PNG. Basta importar sua imagem PNG no editor ร esquerda.",
+ "shortDescription": "Converta rapidamente suas imagens JPG para PNG",
+ "title": "Converter JPG para PNG"
+ },
+ "convertToJpg": {
+ "description": "Converta vรกrios formatos de imagem (PNG, GIF, TIF, PSD, SVG, WEBP, HEIC, RAW) para JPG com configuraรงรตes personalizรกveis de qualidade e cor de fundo.",
+ "shortDescription": "Converta imagens para JPG com controle de qualidade",
+ "title": "Converter imagens para JPG"
+ },
+ "createTransparent": {
+ "description": "Mundo",
+ "shortDescription": "Tornar uma imagem transparente rapidamente",
+ "title": "Criar PNG transparente"
+ },
+ "crop": {
+ "description": "Corte imagens para remover รกreas indesejadas.",
+ "inputTitle": "Imagem de entrada",
+ "resultTitle": "Imagem recortada",
+ "shortDescription": "Corte imagens rapidamente.",
+ "title": "Cortar imagem"
+ },
+ "editor": {
+ "description": "Editor de imagens avanรงado com ferramentas para cortar, girar, anotar, ajustar cores e adicionar marcas d'รกgua. Edite suas imagens com ferramentas profissionais diretamente no seu navegador.",
+ "shortDescription": "Edite imagens com ferramentas e recursos avanรงados",
+ "title": "Editor de imagens"
+ },
+ "imageToText": {
+ "description": "Extraia texto de imagens (JPG, PNG) usando reconhecimento รณptico de caracteres (OCR).",
+ "shortDescription": "Extraia texto de imagens usando OCR.",
+ "title": "Imagem para texto (OCR)"
+ },
+ "qrCode": {
+ "description": "Gere cรณdigos QR para diferentes tipos de dados: URL, texto, e-mail, telefone, SMS, WiFi, vCard e muito mais.",
+ "shortDescription": "Crie cรณdigos QR personalizados para vรกrios formatos de dados.",
+ "title": "Gerador de cรณdigo QR"
+ },
+ "removeBackground": {
+ "description": "Mundo",
+ "shortDescription": "Remover fundos de imagens automaticamente",
+ "title": "Remover fundo da imagem"
+ },
+ "resize": {
+ "description": "Redimensione imagens para dimensรตes diferentes.",
+ "dimensionType": "Tipo de dimensรฃo",
+ "heightDescription": "Altura (em pixels)",
+ "inputTitle": "Imagem de entrada",
+ "maintainAspectRatio": "Manter proporรงรฃo de aspecto",
+ "maintainAspectRatioDescription": "Manter a proporรงรฃo original da imagem.",
+ "percentage": "Percentagem",
+ "percentageDescription": "Porcentagem do tamanho original (por exemplo, 50 para metade do tamanho, 200 para o dobro do tamanho)",
+ "resizeByPercentage": "Redimensionar por porcentagem",
+ "resizeByPercentageDescription": "Redimensione especificando uma porcentagem do tamanho original.",
+ "resizeByPixels": "Redimensionar por pixels",
+ "resizeByPixelsDescription": "Redimensione especificando dimensรตes em pixels.",
+ "resizeMethod": "Mรฉtodo de redimensionamento",
+ "resultTitle": "Imagem redimensionada",
+ "setHeight": "Altura definida",
+ "setHeightDescription": "Especifique a altura em pixels e calcule a largura com base na proporรงรฃo.",
+ "setWidth": "Definir largura",
+ "setWidthDescription": "Especifique a largura em pixels e calcule a altura com base na proporรงรฃo.",
+ "shortDescription": "Redimensione imagens facilmente.",
+ "title": "Redimensionar imagem",
+ "toolInfo": {
+ "description": "Esta ferramenta permite redimensionar imagens JPG, PNG, SVG ou GIF. Vocรช pode redimensionar especificando as dimensรตes em pixels ou em porcentagem, com opรงรตes para manter a proporรงรฃo original.",
+ "title": "Redimensionar imagem"
+ },
+ "widthDescription": "Largura (em pixels)"
+ },
+ "rotate": {
+ "description": "Girar uma imagem em um รขngulo especificado.",
+ "shortDescription": "Gire uma imagem facilmente.",
+ "title": "Girar imagem"
+ }
+}
diff --git a/public/locales/pt/json.json b/public/locales/pt/json.json
new file mode 100644
index 0000000..32f981b
--- /dev/null
+++ b/public/locales/pt/json.json
@@ -0,0 +1,62 @@
+{
+ "escapeJson": {
+ "description": "Escape caracteres especiais em strings JSON. Converta dados JSON para um formato de escape adequado para transmissรฃo ou armazenamento seguro.",
+ "shortDescription": "Escape de caracteres especiais em JSON",
+ "title": "Escape JSON"
+ },
+ "jsonToXml": {
+ "description": "Converta dados JSON para o formato XML. Transforme objetos JSON estruturados em documentos XML bem-formados.",
+ "shortDescription": "Converter JSON para o formato XML",
+ "title": "JSON para XML"
+ },
+ "minify": {
+ "description": "Remova todos os espaรงos em branco desnecessรกrios do JSON.",
+ "inputTitle": "Entrada JSON",
+ "resultTitle": "JSON minificado",
+ "shortDescription": "Minifique JSON removendo espaรงos em branco",
+ "title": "Minificar JSON",
+ "toolInfo": {
+ "description": "A minificaรงรฃo de JSON รฉ o processo de remover todos os caracteres de espaรงo em branco desnecessรกrios dos dados JSON, mantendo sua validade. Isso inclui a remoรงรฃo de espaรงos, quebras de linha e recuos desnecessรกrios para que o JSON seja analisado corretamente. A minificaรงรฃo reduz o tamanho dos dados JSON, tornando-os mais eficientes para armazenamento e transmissรฃo, mantendo exatamente a mesma estrutura de dados e valores.",
+ "title": "O que รฉ minificaรงรฃo JSON?"
+ }
+ },
+ "prettify": {
+ "description": "Formate JSON com recuo e espaรงamento adequados.",
+ "indentation": "Recuo",
+ "inputTitle": "Entrada JSON",
+ "resultTitle": "JSON embelezado",
+ "shortDescription": "Formate e embeleze o cรณdigo JSON",
+ "title": "Embeleze JSON",
+ "toolInfo": {
+ "description": "Esta ferramenta permite formatar dados JSON com recuo e espaรงamento adequados, tornando-os mais legรญveis e fรกceis de trabalhar.",
+ "title": "Embeleze JSON"
+ },
+ "useSpaces": "Use Espaรงos",
+ "useSpacesDescription": "Recuar a saรญda com espaรงos",
+ "useTabs": "Usar guias",
+ "useTabsDescription": "Recuar a saรญda com tabulaรงรตes."
+ },
+ "stringify": {
+ "description": "Converta objetos JavaScript para o formato de string JSON. Serialize estruturas de dados em strings JSON para armazenamento ou transmissรฃo.",
+ "shortDescription": "Converter objetos em string JSON",
+ "title": "Stringify JSON"
+ },
+ "tsvToJson": {
+ "description": "Converta dados TSV (Valores Separados por Tabulaรงรฃo) para o formato JSON. Transforme dados tabulares em objetos JSON estruturados.",
+ "shortDescription": "Converter TSV para o formato JSON",
+ "title": "TSV para JSON"
+ },
+ "validateJson": {
+ "description": "Verifique se JSON รฉ vรกlido e bem formado.",
+ "inputTitle": "Entrada JSON",
+ "invalidJson": "โ {{error}}",
+ "resultTitle": "Resultado da Validaรงรฃo",
+ "shortDescription": "Validar cรณdigo JSON para erros",
+ "title": "Validar JSON",
+ "toolInfo": {
+ "description": "JSON (JavaScript Object Notation) รฉ um formato leve para troca de dados. A validaรงรฃo JSON garante que a estrutura dos dados esteja em conformidade com o padrรฃo JSON. Um objeto JSON vรกlido deve ter: - Nomes de propriedades entre aspas duplas. - Chaves {} devidamente balanceadas. - Sem vรญrgulas finais apรณs o รบltimo par chave-valor. - Aninhamento correto de objetos e matrizes. Esta ferramenta verifica o JSON de entrada e fornece feedback para ajudar a identificar e corrigir erros comuns.",
+ "title": "O que รฉ validaรงรฃo JSON?"
+ },
+ "validJson": "โ
JSON vรกlido"
+ }
+}
diff --git a/public/locales/pt/list.json b/public/locales/pt/list.json
new file mode 100644
index 0000000..8bc58ed
--- /dev/null
+++ b/public/locales/pt/list.json
@@ -0,0 +1,208 @@
+{
+ "duplicate": {
+ "concatenate": "Concatenar",
+ "concatenateDescription": "Concatenar cรณpias (se desmarcado, os itens serรฃo entrelaรงados)",
+ "copyDescription": "Nรบmero de cรณpias (pode ser fracionรกrio)",
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para duplicar itens de lista. Insira sua lista e especifique critรฉrios de duplicaรงรฃo para criar cรณpias dos itens. Perfeito para expansรฃo de dados, testes ou criaรงรฃo de padrรตes repetidos.",
+ "duplicationOptions": "Opรงรตes de duplicaรงรฃo",
+ "examples": {
+ "fractional": {
+ "description": "Este exemplo mostra como duplicar uma lista com um nรบmero fracionรกrio de cรณpias.",
+ "title": "Duplicaรงรฃo fracionรกria"
+ },
+ "interweave": {
+ "description": "Este exemplo mostra como entrelaรงar itens em vez de concatenรก-los.",
+ "title": "Itens entrelaรงados"
+ },
+ "reverse": {
+ "description": "Este exemplo mostra como duplicar uma lista na ordem inversa.",
+ "title": "Duplicaรงรฃo reversa"
+ },
+ "simple": {
+ "description": "Este exemplo mostra como duplicar uma lista de palavras.",
+ "title": "Duplicaรงรฃo simples"
+ }
+ },
+ "inputTitle": "Lista de Entrada",
+ "joinSeparatorDescription": "Separador para unir a lista duplicada",
+ "resultTitle": "Lista Duplicada",
+ "reverse": "Reverter",
+ "reverseDescription": "Reverter os itens duplicados",
+ "shortDescription": "Itens de lista duplicados com critรฉrios especificados",
+ "splitByRegex": "Dividir por expressรฃo regular",
+ "splitBySymbol": "Dividido por sรญmbolo",
+ "splitOptions": "Opรงรตes de divisรฃo",
+ "splitSeparatorDescription": "Separador para dividir a lista",
+ "title": "Duplicado",
+ "toolInfo": {
+ "description": "Esta ferramenta permite duplicar itens em uma lista. Vocรช pode especificar o nรบmero de cรณpias (incluindo valores fracionรกrios), controlar se os itens serรฃo concatenados ou entrelaรงados e atรฉ mesmo reverter os itens duplicados. ร รบtil para criar padrรตes repetidos, gerar dados de teste ou expandir listas com conteรบdo previsรญvel.",
+ "title": "Duplicaรงรฃo de lista"
+ }
+ },
+ "findMostPopular": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para encontrar os itens mais populares em uma lista. Insira sua lista e obtenha instantaneamente os itens que aparecem com mais frequรชncia. Perfeito para anรกlise de dados, identificaรงรฃo de tendรชncias ou busca por elementos comuns.",
+ "shortDescription": "Encontre os itens mais frequentes",
+ "title": "Encontre os mais populares"
+ },
+ "findUnique": {
+ "caseSensitiveItems": "Itens que diferenciam maiรบsculas de minรบsculas",
+ "caseSensitiveItemsDescription": "Produza itens com maiรบsculas e minรบsculas diferentes como elementos exclusivos na lista.",
+ "delimiterDescription": "Defina um sรญmbolo delimitador ou uma expressรฃo regular.",
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para encontrar itens รบnicos em uma lista. Insira sua lista e obtenha instantaneamente todos os valores รบnicos, com as duplicatas removidas. Perfeito para limpeza de dados, desduplicaรงรฃo ou busca de elementos distintos.",
+ "findAbsolutelyUniqueItems": "Encontre itens absolutamente รบnicos",
+ "findAbsolutelyUniqueItemsDescription": "Exibe somente os itens da lista que existem em uma รบnica cรณpia.",
+ "inputListDelimiter": "Delimitador de lista de entrada",
+ "inputTitle": "Lista de Entrada",
+ "outputListDelimiter": "Delimitador da lista de saรญda",
+ "resultTitle": "Itens รnicos",
+ "shortDescription": "Encontre itens exclusivos em uma lista",
+ "skipEmptyItems": "Pular itens vazios",
+ "skipEmptyItemsDescription": "Nรฃo inclua os itens da lista vazia na saรญda.",
+ "title": "Encontre algo รบnico",
+ "trimItems": "Itens da lista de corte",
+ "trimItemsDescription": "Remova os espaรงos iniciais e finais antes de comparar itens.",
+ "uniqueItemOptions": "Opรงรตes de itens exclusivos"
+ },
+ "group": {
+ "deleteEmptyItems": "Excluir itens vazios",
+ "deleteEmptyItemsDescription": "Ignore itens vazios e nรฃo os inclua nos grupos.",
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para agrupar itens de lista. Insira sua lista e especifique critรฉrios de agrupamento para organizar os itens em grupos lรณgicos. Perfeito para categorizar dados, organizar informaรงรตes ou criar listas estruturadas. Suporta separadores personalizados e diversas opรงรตes de agrupamento.",
+ "emptyItemsAndPadding": "Itens vazios e preenchimento",
+ "groupNumberDescription": "Nรบmero de itens em um grupo",
+ "groupSeparatorDescription": "Caractere separador de grupo",
+ "groupSizeAndSeparators": "Tamanho do grupo e separadores",
+ "inputItemSeparator": "Separador de itens de entrada",
+ "inputTitle": "Lista de entrada",
+ "itemSeparatorDescription": "Caractere separador de itens",
+ "leftWrapDescription": "Sรญmbolo de envoltรณrio esquerdo do grupo.",
+ "padNonFullGroups": "Grupos nรฃo completos",
+ "padNonFullGroupsDescription": "Preencha grupos nรฃo completos com um item personalizado (insira abaixo).",
+ "paddingCharDescription": "Use este caractere ou item para preencher grupos nรฃo completos.",
+ "resultTitle": "Itens agrupados",
+ "rightWrapDescription": "Sรญmbolo de envoltรณrio direito do grupo.",
+ "shortDescription": "Agrupar itens da lista por propriedades comuns",
+ "splitOperators": {
+ "regex": {
+ "description": "Delimite itens da lista de entrada com uma expressรฃo regular.",
+ "title": "Use um Regex para Divisรฃo"
+ },
+ "symbol": {
+ "description": "Delimitar itens da lista de entrada com um caractere.",
+ "title": "Use um sรญmbolo para dividir"
+ }
+ },
+ "splitSeparatorDescription": "Defina um sรญmbolo delimitador ou uma expressรฃo regular.",
+ "title": "Grupo"
+ },
+ "reverse": {
+ "description": "Este รฉ um aplicativo super simples baseado em navegador que imprime todos os itens da lista em ordem inversa. Os itens de entrada podem ser separados por qualquer sรญmbolo e vocรช tambรฉm pode alterar o separador dos itens da lista em ordem inversa.",
+ "inputTitle": "Lista de entrada",
+ "itemSeparator": "Separador de Itens",
+ "itemSeparatorDescription": "Defina um sรญmbolo delimitador ou uma expressรฃo regular.",
+ "outputListOptions": "Opรงรตes da lista de saรญda",
+ "outputSeparatorDescription": "Separador de itens da lista de saรญda.",
+ "resultTitle": "Lista invertida",
+ "shortDescription": "Inverter uma lista rapidamente",
+ "splitOperators": {
+ "regex": {
+ "description": "Delimite itens da lista de entrada com uma expressรฃo regular.",
+ "title": "Use um Regex para Divisรฃo"
+ },
+ "symbol": {
+ "description": "Delimitar itens da lista de entrada com um caractere.",
+ "title": "Use um sรญmbolo para dividir"
+ }
+ },
+ "splitterMode": "Modo divisor",
+ "title": "Reverter",
+ "toolInfo": {
+ "description": "Com este utilitรกrio, vocรช pode inverter a ordem dos itens em uma lista. O utilitรกrio primeiro divide a lista de entrada em itens individuais e, em seguida, itera entre eles, do รบltimo item para o primeiro, imprimindo cada item na saรญda durante a iteraรงรฃo. A lista de entrada pode conter qualquer coisa que possa ser representada como dados textuais, o que inclui dรญgitos, nรบmeros, strings, palavras, frases, etc. O separador de itens de entrada tambรฉm pode ser uma expressรฃo regular. Por exemplo, a expressรฃo regular /[;,]/ permitirรก que vocรช use itens separados por vรญrgula ou ponto e vรญrgula. Os delimitadores dos itens da lista de entrada e saรญda podem ser personalizados nas opรงรตes. Por padrรฃo, as listas de entrada e saรญda sรฃo separadas por vรญrgula. Listabulous!",
+ "title": "O que รฉ um inversor de lista?"
+ }
+ },
+ "rotate": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para rotacionar itens de lista. Insira sua lista e especifique o valor de rotaรงรฃo para deslocar os itens em um nรบmero especรญfico de posiรงรตes. Perfeito para manipulaรงรฃo de dados, deslocamentos circulares ou reordenaรงรฃo de listas.",
+ "shortDescription": "Girar itens da lista por posiรงรตes especificadas",
+ "title": "Girar"
+ },
+ "shuffle": {
+ "delimiterDescription": "Defina um sรญmbolo delimitador ou uma expressรฃo regular.",
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para embaralhar itens de lista. Insira sua lista e obtenha instantaneamente uma versรฃo aleatรณria com itens em ordem aleatรณria. Perfeito para criar variedade, testar aleatoriedade ou misturar dados ordenados.",
+ "inputListSeparator": "Separador de lista de entrada",
+ "inputTitle": "Lista de entrada",
+ "joinSeparatorDescription": "Use este separador na lista aleatรณria.",
+ "outputLengthDescription": "Produzir esta quantidade de itens aleatรณrios",
+ "resultTitle": "Lista embaralhada",
+ "shortDescription": "Randomize a ordem dos itens da lista",
+ "shuffledListLength": "Comprimento da lista embaralhada",
+ "shuffledListSeparator": "Separador de lista embaralhada",
+ "title": "Embaralhar"
+ },
+ "sort": {
+ "caseSensitive": "Classificaรงรฃo com diferenciaรงรฃo entre maiรบsculas e minรบsculas",
+ "caseSensitiveDescription": "Classifique itens em letras maiรบsculas e minรบsculas separadamente. Letras maiรบsculas precedem letras minรบsculas em uma lista crescente. (Funciona apenas no modo de classificaรงรฃo alfabรฉtica.)",
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para classificar itens de lista. Insira sua lista e especifique critรฉrios de classificaรงรฃo para organizar os itens em ordem crescente ou decrescente. Perfeito para organizaรงรฃo de dados, processamento de texto ou criaรงรฃo de listas ordenadas.",
+ "inputItemSeparator": "Separador de itens de entrada",
+ "inputTitle": "Lista de entrada",
+ "joinSeparatorDescription": "Use este sรญmbolo para unir itens em uma lista classificada.",
+ "orderDescription": "Selecione uma ordem de classificaรงรฃo.",
+ "orderOptions": {
+ "decreasing": "Ordem decrescente",
+ "increasing": "Ordem crescente"
+ },
+ "removeDuplicates": "Remover duplicatas",
+ "removeDuplicatesDescription": "Excluir itens duplicados da lista.",
+ "resultTitle": "Lista ordenada",
+ "shortDescription": "Classificar itens da lista na ordem especificada",
+ "sortMethod": "Mรฉtodo de classificaรงรฃo",
+ "sortMethodDescription": "Selecione um mรฉtodo de classificaรงรฃo.",
+ "sortOptions": {
+ "alphabetic": "Classificar em ordem alfabรฉtica",
+ "length": "Classificar por comprimento",
+ "numeric": "Classificar numericamente"
+ },
+ "sortedItemProperties": "Propriedades de itens classificados",
+ "splitOperators": {
+ "regex": {
+ "description": "Delimite itens da lista de entrada com uma expressรฃo regular.",
+ "title": "Use um Regex para Divisรฃo"
+ },
+ "symbol": {
+ "description": "Delimitar itens da lista de entrada com um caractere.",
+ "title": "Use um sรญmbolo para dividir"
+ }
+ },
+ "splitSeparatorDescription": "Defina um sรญmbolo delimitador ou uma expressรฃo regular.",
+ "title": "Organizar"
+ },
+ "truncate": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para truncar listas. Insira sua lista e especifique o nรบmero mรกximo de itens a serem mantidos. Perfeito para processamento de dados, gerenciamento de listas ou limitaรงรฃo de tamanho de conteรบdo.",
+ "shortDescription": "Truncar lista para um nรบmero especรญfico de itens",
+ "title": "Truncar"
+ },
+ "unwrap": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para descompactar itens de lista. Insira sua lista encapsulada e especifique critรฉrios de descompactaรงรฃo para simplificar os itens organizados. Perfeito para processamento de dados, manipulaรงรฃo de texto ou extraรงรฃo de conteรบdo de listas estruturadas.",
+ "shortDescription": "Desembrulhe itens de lista do formato estruturado",
+ "title": "Desembrulhar"
+ },
+ "wrap": {
+ "description": "Adicione texto antes e depois de cada item da lista.",
+ "inputTitle": "Lista de Entrada",
+ "joinSeparatorDescription": "Separador para unir a lista encapsulada",
+ "leftTextDescription": "Texto para adicionar antes de cada item",
+ "removeEmptyItems": "Remover itens vazios",
+ "resultTitle": "Lista encapsulada",
+ "rightTextDescription": "Texto para adicionar apรณs cada item",
+ "shortDescription": "Encapsule os itens da lista com critรฉrios especificados",
+ "splitByRegex": "Dividir por expressรฃo regular",
+ "splitBySymbol": "Dividido por sรญmbolo",
+ "splitOptions": "Opรงรตes de divisรฃo",
+ "splitSeparatorDescription": "Separador para dividir a lista",
+ "title": "Enrolar",
+ "toolInfo": {
+ "description": "Esta ferramenta permite adicionar texto antes e depois de cada item de uma lista. Vocรช pode especificar textos diferentes para os lados esquerdo e direito e controlar como a lista รฉ processada. ร รบtil para adicionar aspas, colchetes ou outras formataรงรตes aos itens da lista, preparar dados para diferentes formatos ou criar texto estruturado.",
+ "title": "Encapsulamento de lista"
+ },
+ "wrapOptions": "Opรงรตes de envoltรณrio"
+ }
+}
diff --git a/public/locales/pt/number.json b/public/locales/pt/number.json
new file mode 100644
index 0000000..419b83c
--- /dev/null
+++ b/public/locales/pt/number.json
@@ -0,0 +1,89 @@
+{
+ "arithmeticSequence": {
+ "commonDifferenceDescription": "Diferenรงa comum entre os termos (d)",
+ "description": "Gere sequรชncias aritmรฉticas com parรขmetros personalizรกveis.",
+ "firstTermDescription": "Primeiro termo da sequรชncia (aโ)",
+ "numberOfTermsDescription": "Nรบmero de termos a gerar (n)",
+ "outputFormat": "Formato de saรญda",
+ "resultTitle": "Sequรชncia Gerada",
+ "separatorDescription": "Separador entre termos",
+ "sequenceParameters": "Parรขmetros de sequรชncia",
+ "shortDescription": "Gerar sequรชncias aritmรฉticas",
+ "title": "Sequรชncia Aritmรฉtica",
+ "toolInfo": {
+ "description": "Uma progressรฃo aritmรฉtica รฉ uma sequรชncia de nรบmeros em que a diferenรงa entre cada termo consecutivo รฉ constante. Essa diferenรงa constante รฉ chamada de diferenรงa comum. Dado o primeiro termo (aโ) e a diferenรงa comum (d), cada termo pode ser encontrado somando a diferenรงa comum ao termo anterior.",
+ "title": "O que รฉ uma sequรชncia aritmรฉtica?"
+ }
+ },
+ "generate": {
+ "arithmeticSequenceOption": "Opรงรฃo de sequรชncia aritmรฉtica",
+ "description": "Gere uma sequรชncia de nรบmeros com parรขmetros personalizรกveis.",
+ "numberOfElementsDescription": "Nรบmero de elementos em sequรชncia.",
+ "resultTitle": "Nรบmeros gerados",
+ "separator": "Separador",
+ "separatorDescription": "Separe os elementos na sequรชncia aritmรฉtica por este caractere.",
+ "shortDescription": "Gerar nรบmeros aleatรณrios em intervalos especificados",
+ "startSequenceDescription": "Inicie a sequรชncia a partir deste nรบmero.",
+ "stepDescription": "Aumente cada elemento por esta quantidade",
+ "title": "Gerar",
+ "toolInfo": {
+ "description": "Esta ferramenta permite gerar uma sequรชncia de nรบmeros com parรขmetros personalizรกveis. Vocรช pode especificar o valor inicial, o tamanho do passo e o nรบmero de elementos.",
+ "title": "Gerar nรบmeros"
+ }
+ },
+ "ohmsLaw": {
+ "description": "Calcula tensรฃo, corrente e resistรชncia",
+ "longDescription": "Esta calculadora aplica a Lei de Ohm (V = I ร R) para determinar qualquer um dos trรชs parรขmetros elรฉtricos quando os outros dois sรฃo conhecidos. A Lei de Ohm รฉ um princรญpio fundamental em engenharia elรฉtrica que descreve a relaรงรฃo entre tensรฃo (V), corrente (I) e resistรชncia (R). Esta ferramenta รฉ essencial para entusiastas de eletrรดnica, engenheiros elรฉtricos e estudantes que trabalham com circuitos, para que possam resolver rapidamente valores desconhecidos em seus projetos elรฉtricos.",
+ "shortDescription": "Calcular tensรฃo, corrente ou resistรชncia em circuitos elรฉtricos usando a Lei de Ohm",
+ "title": "Lei de Ohm"
+ },
+ "slackline": {
+ "description": "Calcula a tensรฃo em uma slackline",
+ "longDescription": "Esta calculadora assume uma carga no centro da corda",
+ "shortDescription": "Calcule a tensรฃo aproximada de um slackline ou varal. Nรฃo confie apenas nisso para sua seguranรงa.",
+ "title": "Tensรฃo da Slackline"
+ },
+ "sphereArea": {
+ "description": "รrea de uma esfera",
+ "longDescription": "Esta calculadora determina a รกrea da superfรญcie de uma esfera usando a fรณrmula A = 4ฯrยฒ. Vocรช pode inserir o raio para encontrar a รกrea da superfรญcie ou inseri-la para calcular o raio necessรกrio. Esta ferramenta รฉ รบtil para estudantes de geometria, engenheiros que trabalham com objetos esfรฉricos e qualquer pessoa que precise realizar cรกlculos envolvendo superfรญcies esfรฉricas.",
+ "shortDescription": "Calcular a รกrea da superfรญcie de uma esfera com base em seu raio",
+ "title": "รrea de uma esfera"
+ },
+ "sphereVolume": {
+ "description": "Volume de uma esfera",
+ "longDescription": "Esta calculadora calcula o volume de uma esfera usando a fรณrmula V = (4/3)ฯrยณ. Vocรช pode inserir o raio ou o diรขmetro para encontrar o volume ou inserir o volume para determinar o raio necessรกrio. A ferramenta รฉ valiosa para estudantes, engenheiros e profissionais que trabalham com objetos esfรฉricos em รกreas como fรญsica, engenharia e manufatura.",
+ "shortDescription": "Calcular o volume de uma esfera usando raio ou diรขmetro",
+ "title": "Volume de uma esfera"
+ },
+ "sum": {
+ "description": "Calcule a soma de uma lista de nรบmeros. Insira os nรบmeros separados por vรญrgulas ou quebras de linha para obter a soma total.",
+ "extractionTypes": {
+ "delimiter": {
+ "description": "Personalize o separador de nรบmeros aqui. (Por padrรฃo, uma quebra de linha.)",
+ "title": "Delimitador de Nรบmero"
+ },
+ "smart": {
+ "description": "Detectar automaticamente nรบmeros na entrada.",
+ "title": "Soma Inteligente"
+ }
+ },
+ "inputTitle": "Entrada",
+ "numberExtraction": "Extraรงรฃo de Nรบmeros",
+ "printRunningSum": "Imprimir soma corrente",
+ "printRunningSumDescription": "Exiba a soma conforme ela รฉ calculada passo a passo.",
+ "resultTitle": "Total",
+ "runningSum": "Soma Corrente",
+ "shortDescription": "Calcular soma de nรบmeros",
+ "title": "Soma",
+ "toolInfo": {
+ "description": "Este รฉ um utilitรกrio online baseado em navegador para calcular a soma de vรกrios nรบmeros. Vocรช pode inserir os nรบmeros separados por vรญrgula, espaรงo ou qualquer outro caractere, incluindo a quebra de linha. Vocรช tambรฉm pode simplesmente colar um fragmento de dados textuais que contenha valores numรฉricos que vocรช deseja somar, e o utilitรกrio os extrairรก e calcularรก a soma.",
+ "title": "O que รฉ uma calculadora de soma numรฉrica?"
+ }
+ },
+ "voltageDropInWire": {
+ "description": "Calcula a tensรฃo de ida e volta e a perda de potรชncia em um cabo de 2 condutores",
+ "longDescription": "Esta calculadora ajuda a determinar a queda de tensรฃo e a perda de potรชncia em um cabo elรฉtrico de dois condutores. Ela leva em consideraรงรฃo o comprimento do cabo, a bitola do fio (รกrea da seรงรฃo transversal), a resistividade do material e o fluxo de corrente. A ferramenta calcula a queda de tensรฃo de ida e volta, a resistรชncia total do cabo e a potรชncia dissipada na forma de calor. Isso รฉ particularmente รบtil para engenheiros elรฉtricos, eletricistas e amadores ao projetar sistemas elรฉtricos para garantir que os nรญveis de tensรฃo permaneรงam dentro dos limites aceitรกveis na carga.",
+ "shortDescription": "Calcular queda de tensรฃo e perda de potรชncia em cabos elรฉtricos com base no comprimento, material e corrente",
+ "title": "Queda de tensรฃo de ida e volta no cabo"
+ }
+}
diff --git a/public/locales/pt/pdf.json b/public/locales/pt/pdf.json
new file mode 100644
index 0000000..049f798
--- /dev/null
+++ b/public/locales/pt/pdf.json
@@ -0,0 +1,113 @@
+{
+ "compressPdf": {
+ "compressedFileSize": "Tamanho do arquivo compactado",
+ "compressingPdf": "Compactando PDF...",
+ "compressionLevel": "Nรญvel de compressรฃo",
+ "compressionSettings": "Configuraรงรตes de compressรฃo",
+ "description": "Reduza o tamanho do arquivo PDF mantendo a qualidade usando Ghostscript",
+ "errorCompressingPdf": "Falha ao compactar PDF: {{error}}",
+ "errorReadingPdf": "Falha ao ler o arquivo PDF. Certifique-se de que รฉ um PDF vรกlido.",
+ "fileSize": "Tamanho original do arquivo",
+ "highCompression": "Alta compressรฃo",
+ "highCompressionDescription": "Reduรงรฃo mรกxima do tamanho do arquivo com alguma perda de qualidade",
+ "inputTitle": "PDF de entrada",
+ "lowCompression": "Baixa compressรฃo",
+ "lowCompressionDescription": "Reduza ligeiramente o tamanho do arquivo com perda mรญnima de qualidade",
+ "mediumCompression": "Compressรฃo mรฉdia",
+ "mediumCompressionDescription": "Equilรญbrio entre tamanho e qualidade do arquivo",
+ "pages": "Nรบmero de pรกginas",
+ "resultTitle": "PDF compactado",
+ "shortDescription": "Compacte arquivos PDF com seguranรงa no seu navegador",
+ "title": "Comprimir PDF"
+ },
+ "editor": {
+ "description": "Editor de PDF avanรงado com recursos de anotaรงรฃo, preenchimento de formulรกrios, destaque e exportaรงรฃo. Edite seus PDFs diretamente no navegador com ferramentas de nรญvel profissional, incluindo inserรงรฃo de texto, desenho, destaque, assinatura e preenchimento de formulรกrios.",
+ "shortDescription": "Edite PDFs com ferramentas avanรงadas de anotaรงรฃo, assinatura e ediรงรฃo",
+ "title": "Editor de PDF"
+ },
+ "merge": {
+ "inputTitle": "PDF de entrada",
+ "loadingText": "Extraindo pรกginas",
+ "resultTitle": "Saรญda PDF mesclada",
+ "toolInfo": {
+ "description": "Esta ferramenta permite mesclar vรกrios arquivos PDF em um รบnico documento. Para usรก-la, basta carregar os arquivos PDF que deseja mesclar. A ferramenta entรฃo combinarรก todas as pรกginas dos arquivos de entrada em um รบnico documento PDF.",
+ "title": "Como usar a ferramenta Mesclar PDF?"
+ }
+ },
+ "mergePdf": {
+ "description": "Combine vรกrios arquivos PDF em um รบnico documento.",
+ "inputTitle": "PDFs de entrada",
+ "mergingPdfs": "Mesclando PDFs",
+ "pdfOptions": "Opรงรตes de PDF",
+ "resultTitle": "PDF mesclado",
+ "shortDescription": "Mesclar vรกrios arquivos PDF em um รบnico documento",
+ "sortByFileName": "Classificar por nome de arquivo",
+ "sortByFileNameDescription": "Classificar PDFs em ordem alfabรฉtica por nome de arquivo",
+ "sortByUploadOrder": "Classificar por ordem de upload",
+ "sortByUploadOrderDescription": "Mantenha os PDFs na ordem em que foram enviados",
+ "title": "Mesclar PDF",
+ "toolInfo": {
+ "description": "Esta ferramenta permite combinar vรกrios arquivos PDF em um รบnico documento. Vocรช pode escolher como classificar os PDFs e a ferramenta os mesclarรก na ordem especificada.",
+ "title": "Mesclar arquivos PDF"
+ }
+ },
+ "pdfToEpub": {
+ "description": "Transforme documentos PDF em arquivos EPUB para melhor compatibilidade com leitores eletrรดnicos.', รญcone: 'material-symbols:import-contacts', componente: lazy(() => import('./index')), palavras-chave: ['pdf', 'epub', 'convert', 'ebook'], caminho: 'pdf-to-epub', i18n: { nome: 'pdf:pdfToEpub.title', descriรงรฃo: 'pdf:pdfToEpub.description",
+ "shortDescription": "Converter arquivos PDF para o formato EPUB",
+ "title": "PDF para EPUB"
+ },
+ "pdfToPng": {
+ "description": "Transforme documentos PDF em painรฉis PNG.",
+ "longDescription": "Carregue um PDF e converta cada pรกgina em uma imagem PNG de alta qualidade diretamente no seu navegador. Esta ferramenta รฉ ideal para extrair conteรบdo visual ou compartilhar pรกginas individuais. Nenhum dado รฉ carregado โ tudo รฉ executado localmente.",
+ "shortDescription": "Converter PDF em imagens PNG",
+ "title": "PDF para PNG"
+ },
+ "protectPdf": {
+ "description": "Adicione proteรงรฃo por senha aos seus arquivos PDF com seguranรงa no seu navegador",
+ "shortDescription": "Proteja arquivos PDF com senha com seguranรงa",
+ "title": "Proteger PDF"
+ },
+ "rotatePdf": {
+ "allPagesWillBeRotated": "Todos {{count}} as pรกginas serรฃo giradas",
+ "angleOptions": {
+ "clockwise90": "90ยฐ no sentido horรกrio",
+ "counterClockwise270": "270ยฐ (90ยฐ sentido anti-horรกrio)",
+ "upsideDown180": "180ยฐ (de cabeรงa para baixo)"
+ },
+ "applyToAllPages": "Aplicar a todas as pรกginas",
+ "description": "Girar pรกginas em um documento PDF.",
+ "inputTitle": "PDF de entrada",
+ "longDescription": "Altere a orientaรงรฃo das pรกginas do PDF girando-as 90, 180 ou 270 graus. รtil para corrigir documentos digitalizados incorretamente ou preparar PDFs para impressรฃo.",
+ "pageRangesDescription": "Insira nรบmeros de pรกgina ou intervalos separados por vรญrgulas (por exemplo, 1,3,5-7)",
+ "pageRangesPlaceholder": "por exemplo, 1,5-8",
+ "pagesWillBeRotated": "{{count}} pรกgina{{count !== 1 ? 's' : ''}} serรก girado",
+ "pdfPageCount": "PDF tem {{count}} pรกgina{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "PDF girado",
+ "rotatingPages": "Pรกginas rotativas",
+ "rotationAngle": "รngulo de rotaรงรฃo",
+ "rotationSettings": "Configuraรงรตes de rotaรงรฃo",
+ "shortDescription": "Girar pรกginas em um documento PDF",
+ "title": "Girar PDF",
+ "toolInfo": {
+ "description": "Esta ferramenta permite girar pรกginas em um documento PDF. Vocรช pode girar todas as pรกginas ou especificar pรกginas individuais para girar. Escolha um รขngulo de rotaรงรฃo: 90ยฐ no sentido horรกrio, 180ยฐ (de cabeรงa para baixo) ou 270ยฐ (90ยฐ no sentido anti-horรกrio). Para girar pรกginas especรญficas, desmarque \"Aplicar a todas as pรกginas\" e insira os nรบmeros das pรกginas ou intervalos separados por vรญrgulas (por exemplo, 1, 3, 5-7).",
+ "title": "Como usar a ferramenta Girar PDF"
+ }
+ },
+ "splitPdf": {
+ "description": "Extraia pรกginas especรญficas de um documento PDF.",
+ "extractingPages": "Extraindo pรกginas",
+ "inputTitle": "PDF de entrada",
+ "pageExtractionPreview": "{{count}} pรกgina{{count !== 1 ? 's' : ''}} serรก extraรญdo",
+ "pageRangesDescription": "Insira nรบmeros de pรกgina ou intervalos separados por vรญrgulas (por exemplo, 1,3,5-7)",
+ "pageRangesPlaceholder": "por exemplo, 1,5-8",
+ "pageSelection": "Seleรงรฃo de pรกgina",
+ "pdfPageCount": "PDF tem {{count}} pรกgina{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "PDF extraรญdo",
+ "shortDescription": "Extrair pรกginas especรญficas de um arquivo PDF",
+ "title": "Dividir PDF",
+ "toolInfo": {
+ "description": "Esta ferramenta permite extrair pรกginas especรญficas de um documento PDF. Vocรช pode especificar pรกginas individuais ou intervalos de pรกginas para extrair.",
+ "title": "Dividir PDF"
+ }
+ }
+}
diff --git a/public/locales/pt/string.json b/public/locales/pt/string.json
new file mode 100644
index 0000000..48c3ac4
--- /dev/null
+++ b/public/locales/pt/string.json
@@ -0,0 +1,261 @@
+{
+ "base64": {
+ "decode": "Decodificaรงรฃo Base64",
+ "description": "Codifique ou decodifique texto usando codificaรงรฃo Base64.",
+ "encode": "Codificaรงรฃo Base64",
+ "inputTitle": "Dados de entrada",
+ "optionsTitle": "Opรงรตes Base64",
+ "resultTitle": "Resultado",
+ "shortDescription": "Codifique ou decodifique dados usando Base64.",
+ "title": "Codificador/Decodificador Base64",
+ "toolInfo": {
+ "description": "Base64 รฉ um esquema de codificaรงรฃo que representa dados em um formato de string ASCII, traduzindo-os para uma representaรงรฃo radix-64. Embora possa ser usado para codificar strings, รฉ comumente usado para codificar dados binรกrios para transmissรฃo em mรญdias projetadas para lidar com dados textuais.",
+ "title": "O que รฉ Base64?"
+ }
+ },
+ "censor": {
+ "description": "Utilitรกrio para censurar palavras em texto. Carregue seu texto no formulรกrio de entrada ร esquerda, especifique todos os palavrรตes nas opรงรตes e vocรช obterรก instantaneamente o texto censurado na รกrea de saรญda.\", longDescription: \"Com esta ferramenta online, vocรช pode censurar certas palavras em qualquer texto. Vocรช pode especificar uma lista de palavras indesejadas (como palavrรตes ou palavras secretas) e o programa as substituirรก por palavras alternativas e criarรก um texto seguro para leitura. As palavras podem ser especificadas em um campo de texto de vรกrias linhas nas opรงรตes, inserindo uma palavra por linha.\", keywords: ['text', 'censor', 'words', 'characters'], component: lazy(() => import('./index')), i18n: { name: 'string:censor.title', description: 'string:censor.description",
+ "shortDescription": "Mascare rapidamente palavras ruins ou substitua-as por palavras alternativas.",
+ "title": "Censor de texto"
+ },
+ "createPalindrome": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para criar palรญndromos a partir de qualquer texto. Insira texto e transforme-o instantaneamente em um palรญndromo com a mesma leitura de trรกs para frente. Perfeito para jogos de palavras, criaรงรฃo de padrรตes de texto simรฉtricos ou exploraรงรฃo de curiosidades linguรญsticas.",
+ "shortDescription": "Crie um texto que seja lido da mesma forma para frente e para trรกs",
+ "title": "Criar palรญndromo"
+ },
+ "extractSubstring": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para extrair substrings de texto. Insira seu texto e especifique as posiรงรตes inicial e final para extrair a parte desejada. Perfeito para processamento de dados, anรกlise de texto ou extraรงรฃo de conteรบdo especรญfico de blocos de texto maiores.",
+ "shortDescription": "Extrair uma parte do texto entre posiรงรตes especificadas",
+ "title": "Extrair substring"
+ },
+ "join": {
+ "blankLinesAndTrailingSpaces": "Linhas em branco e espaรงos finais",
+ "deleteBlankDescription": "Exclua linhas que nรฃo tenham sรญmbolos de texto.",
+ "deleteBlankTitle": "Excluir linhas em branco",
+ "deleteTrailingDescription": "Remova espaรงos e tabulaรงรตes no final das linhas.",
+ "deleteTrailingTitle": "Excluir espaรงos finais",
+ "description": "Una partes de texto com separadores personalizรกveis.",
+ "inputTitle": "Pedaรงos de texto",
+ "joinCharacterDescription": "Sรญmbolo que conecta partes quebradas de texto. (Espaรงo por padrรฃo.)",
+ "joinCharacterPlaceholder": "Junte-se ao personagem",
+ "resultTitle": "Texto unido",
+ "shortDescription": "Unir elementos de texto com um separador especificado",
+ "textMergedOptions": "Opรงรตes de mesclagem de texto",
+ "title": "Junte-se ao texto",
+ "toolInfo": {
+ "description": "Com esta ferramenta, vocรช pode unir partes do texto. Ela pega uma lista de valores de texto, separados por quebras de linha, e os mescla. Vocรช pode definir o caractere que serรก colocado entre as partes do texto combinado. Alรฉm disso, vocรช pode ignorar todas as linhas vazias e remover espaรงos e tabulaรงรตes no final de todas as linhas. Textabulous!",
+ "title": "O que รฉ um unidor de texto?"
+ }
+ },
+ "palindrome": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para verificar se um texto รฉ um palรญndromo. Verifique instantaneamente se o seu texto รฉ lido da mesma forma, de trรกs para frente. Perfeito para quebra-cabeรงas de palavras, anรกlise linguรญstica ou validaรงรฃo de padrรตes de texto simรฉtricos. Suporta vรกrios delimitadores e detecรงรฃo de palรญndromos de vรกrias palavras.",
+ "shortDescription": "Verifique se o texto รฉ lido da mesma forma para frente e para trรกs",
+ "title": "Palรญndromo"
+ },
+ "passwordGenerator": {
+ "avoidAmbiguous": "Evite caracteres ambรญguos (i, I, l, 0, O)",
+ "description": "Gere senhas aleatรณrias e seguras com comprimento e tipos de caracteres personalizรกveis. Escolha entre letras minรบsculas, maiรบsculas, nรบmeros e caracteres especiais. Opรงรฃo para evitar caracteres ambรญguos para melhor legibilidade.",
+ "includeLowercase": "Incluir letras minรบsculas (a-z)",
+ "includeNumbers": "Incluir nรบmeros (0-9)",
+ "includeSymbols": "Incluir caracteres especiais",
+ "includeUppercase": "Incluir letras maiรบsculas (A-Z)",
+ "lengthDesc": "Comprimento da senha",
+ "lengthPlaceholder": "por exemplo 12",
+ "optionsTitle": "Opรงรตes de senha",
+ "resultTitle": "Senha gerada",
+ "shortDescription": "Gere senhas aleatรณrias seguras com opรงรตes personalizadas",
+ "title": "Gerador de senhas",
+ "toolInfo": {
+ "description": "Esta ferramenta gera senhas aleatรณrias e seguras com base nos critรฉrios selecionados. Vocรช pode personalizar o comprimento, incluir ou excluir diferentes tipos de caracteres e evitar caracteres ambรญguos para melhor legibilidade. Perfeito para criar senhas fortes para contas, aplicativos ou qualquer necessidade de seguranรงa.",
+ "title": "Sobre o gerador de senhas"
+ }
+ },
+ "quote": {
+ "allowDoubleQuotation": "Permitir aspas duplas",
+ "description": "Adicione aspas ao redor do texto com opรงรตes personalizรกveis.",
+ "inputTitle": "Texto de entrada",
+ "leftQuoteDescription": "Caractere(s) de aspas ร esquerda",
+ "processAsMultiLine": "Processar como texto multilinha",
+ "quoteEmptyLines": "Citar linhas vazias",
+ "quoteOptions": "Opรงรตes de cotaรงรฃo",
+ "resultTitle": "Texto citado",
+ "rightQuoteDescription": "Caractere(s) de aspas corretas",
+ "shortDescription": "Adicione aspas ao redor do texto com vรกrios estilos",
+ "title": "Citador de texto",
+ "toolInfo": {
+ "description": "Esta ferramenta permite adicionar aspas ao redor do texto. Vocรช pode escolher diferentes caracteres de aspas, manipular texto com vรกrias linhas e controlar como as linhas vazias sรฃo processadas. ร รบtil para preparar texto para programaรงรฃo, formatar dados ou criar texto estilizado.",
+ "title": "Citador de texto"
+ }
+ },
+ "randomizeCase": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para randomizar letras maiรบsculas e minรบsculas em textos. Insira seu texto e transforme-o instantaneamente com letras maiรบsculas e minรบsculas aleatรณrias. Perfeito para criar efeitos de texto exclusivos, testar a diferenciaรงรฃo entre maiรบsculas e minรบsculas ou gerar padrรตes de texto variados.",
+ "shortDescription": "Randomize a caixa das letras no texto",
+ "title": "Randomizar caso"
+ },
+ "removeDuplicateLines": {
+ "description": "Carregue seu texto no formulรกrio de entrada ร esquerda e vocรช obterรก instantaneamente texto sem linhas duplicadas na รกrea de saรญda. Poderoso, gratuito e rรกpido. Carregue linhas de texto โ obtenha linhas de texto exclusivas.",
+ "shortDescription": "Exclua rapidamente todas as linhas repetidas do texto",
+ "title": "Remover linhas duplicadas"
+ },
+ "repeat": {
+ "delimiterDescription": "Delimitador para cรณpias de saรญda.",
+ "delimiterPlaceholder": "Delimitador",
+ "description": "Repita o texto vรกrias vezes com separadores personalizรกveis.",
+ "inputTitle": "Texto de entrada",
+ "numberPlaceholder": "Nรบmero",
+ "repeatAmountDescription": "Nรบmero de repetiรงรตes.",
+ "repetitionsDelimiter": "Delimitador de Repetiรงรตes",
+ "resultTitle": "Texto repetido",
+ "shortDescription": "Repita o texto vรกrias vezes",
+ "textRepetitions": "Repetiรงรตes de texto",
+ "title": "Repetir texto",
+ "toolInfo": {
+ "description": "Esta ferramenta permite que vocรช repita um determinado texto vรกrias vezes com um separador opcional.",
+ "title": "Repetir texto"
+ }
+ },
+ "reverse": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para inverter texto. Insira qualquer texto e inverta-o instantaneamente, caractere por caractere. Perfeito para criar texto espelhado, analisar palรญndromos ou brincar com padrรตes de texto. Preserva espaรงos e caracteres especiais durante a inversรฃo.",
+ "inputTitle": "Texto para reverter",
+ "processMultiLine": "Processar texto multilinha",
+ "processMultiLineDescription": "Cada linha serรก revertida independentemente",
+ "resultTitle": "Texto invertido",
+ "reversalOptions": "Opรงรตes de reversรฃo",
+ "shortDescription": "Inverter qualquer texto caractere por caractere",
+ "skipEmptyLines": "Pular linhas vazias",
+ "skipEmptyLinesDescription": "As linhas vazias serรฃo removidas da saรญda",
+ "title": "Reverter",
+ "trimWhitespace": "Aparar espaรงos em branco",
+ "trimWhitespaceDescription": "Remova os espaรงos em branco ร esquerda e ร direita de cada linha"
+ },
+ "rot13": {
+ "description": "Codifique ou decodifique texto usando a cifra ROT13.",
+ "inputTitle": "Texto de entrada",
+ "resultTitle": "Resultado ROT13",
+ "shortDescription": "Codifique ou decodifique texto usando a cifra ROT13.",
+ "title": "Codificador/Decodificador ROT13",
+ "toolInfo": {
+ "description": "ROT13 (rotaรงรฃo de 13 posiรงรตes) รฉ uma cifra simples de substituiรงรฃo de letras que substitui uma letra pela 13ยช letra seguinte no alfabeto. ROT13 รฉ um caso especial da cifra de Cรฉsar, desenvolvida na Roma Antiga. Como o alfabeto inglรชs possui 26 letras, ROT13 รฉ seu prรณprio inverso; ou seja, para desfazer a ROT13, o mesmo algoritmo รฉ aplicado, permitindo que a mesma aรงรฃo seja usada para codificaรงรฃo e decodificaรงรฃo.",
+ "title": "O que รฉ ROT13?"
+ }
+ },
+ "rotate": {
+ "description": "Girar caracteres no texto por posiรงรตes especificadas.",
+ "inputTitle": "Texto de entrada",
+ "processAsMultiLine": "Processar como texto multilinha (girar cada linha separadamente)",
+ "resultTitle": "Texto girado",
+ "rotateLeft": "Girar para a esquerda",
+ "rotateRight": "Girar para a direita",
+ "rotationOptions": "Opรงรตes de rotaรงรฃo",
+ "shortDescription": "Deslocar caracteres no texto por posiรงรฃo.",
+ "stepDescription": "Nรบmero de posiรงรตes para girar",
+ "title": "Girar texto",
+ "toolInfo": {
+ "description": "Esta ferramenta permite girar caracteres em uma string por um nรบmero especรญfico de posiรงรตes. Vocรช pode girar para a esquerda ou para a direita e processar texto com vรกrias linhas girando cada linha separadamente. A rotaรงรฃo de strings รฉ รบtil para transformaรงรตes simples de texto, criaรงรฃo de padrรตes ou implementaรงรฃo de tรฉcnicas bรกsicas de criptografia.",
+ "title": "Rotaรงรฃo de cordas"
+ }
+ },
+ "split": {
+ "charAfterChunkDescription": "Caractere apรณs cada pedaรงo",
+ "charBeforeChunkDescription": "Caractere antes de cada pedaรงo",
+ "chunksDescription": "Nรบmero de pedaรงos de igual\ncomprimento na saรญda.",
+ "chunksTitle": "Use vรกrios pedaรงos",
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para dividir texto. Insira seu texto e especifique um separador para dividi-lo em vรกrias partes. Perfeito para processamento de dados, manipulaรงรฃo de texto ou extraรงรฃo de conteรบdo especรญfico de blocos de texto maiores.",
+ "lengthDescription": "Nรบmero de sรญmbolos que serรฃo colocados em cada bloco de saรญda.",
+ "lengthTitle": "Use comprimento para divisรฃo",
+ "outputSeparatorDescription": "Caractere que serรก colocado entre os blocos divididos.\n(Por padrรฃo, รฉ a quebra de linha \"\\n\".)",
+ "outputSeparatorOptions": "Opรงรตes de separador de saรญda",
+ "regexDescription": "Expressรฃo regular que serรก usada para dividir o texto em partes.\n(Vรกrios espaรงos por padrรฃo.)",
+ "regexTitle": "Use um Regex para Divisรฃo",
+ "resultTitle": "Pedaรงos de texto",
+ "shortDescription": "Dividir o texto em vรกrias partes usando um separador",
+ "splitSeparatorOptions": "Opรงรตes de separador de divisรฃo",
+ "symbolDescription": "Caractere que serรก usado para dividir o texto em partes.\n(Espaรงo por padrรฃo.)",
+ "symbolTitle": "Use um sรญmbolo para dividir",
+ "title": "Dividir"
+ },
+ "statistic": {
+ "characterFrequencyAnalysis": "Anรกlise de Frequรชncia de Caracteres",
+ "characterFrequencyAnalysisDescription": "Conte com que frequรชncia cada caractere aparece no texto",
+ "delimitersOptions": "Opรงรตes de delimitadores",
+ "description": "Analise texto e gere estatรญsticas abrangentes.",
+ "includeEmptyLines": "Incluir linhas vazias",
+ "includeEmptyLinesDescription": "Incluir linhas em branco ao contar linhas",
+ "inputTitle": "Texto de entrada",
+ "resultTitle": "Estatรญsticas de texto",
+ "sentenceDelimitersDescription": "Insira caracteres personalizados usados para delimitar frases no seu idioma (separados por vรญrgula) ou deixe em branco para o padrรฃo.",
+ "sentenceDelimitersPlaceholder": "por exemplo ., !, ?, ...",
+ "shortDescription": "Obtenha estatรญsticas sobre seu texto",
+ "statisticsOptions": "Opรงรตes de estatรญsticas",
+ "title": "Estatรญsticas de texto",
+ "toolInfo": {
+ "description": "Esta ferramenta permite que vocรช analise texto e gere estatรญsticas abrangentes, incluindo contagem de caracteres, contagem de palavras, contagem de linhas e anรกlise de frequรชncia de caracteres e palavras.",
+ "title": "O que รฉ um {{title}}?"
+ },
+ "wordDelimitersDescription": "Insira uma Regex personalizada para contar palavras ou deixe em branco para o padrรฃo.",
+ "wordDelimitersPlaceholder": "por exemplo. \\s.,;:!?\"ยซยป()โฆ",
+ "wordFrequencyAnalysis": "Anรกlise de frequรชncia de palavras",
+ "wordFrequencyAnalysisDescription": "Conte com que frequรชncia cada palavra aparece no texto"
+ },
+ "textReplacer": {
+ "description": "Substitua padrรตes de texto por novo conteรบdo.",
+ "findPatternInText": "Encontre este padrรฃo no texto",
+ "findPatternUsingRegexp": "Encontre um padrรฃo usando uma RegExp",
+ "inputTitle": "Texto para substituir",
+ "newTextPlaceholder": "Novo texto",
+ "regexpDescription": "Insira a expressรฃo regular que vocรช deseja substituir.",
+ "replacePatternDescription": "Digite o padrรฃo a ser usado para substituiรงรฃo.",
+ "replaceText": "Substituir texto",
+ "resultTitle": "Texto com substituiรงรตes",
+ "searchPatternDescription": "Digite o padrรฃo de texto que vocรช deseja substituir.",
+ "searchText": "Pesquisar texto",
+ "shortDescription": "Substitua rapidamente o texto em seu conteรบdo",
+ "title": "Substituidor de texto",
+ "toolInfo": {
+ "description": "Substitua facilmente textos especรญficos em seu conteรบdo com esta ferramenta simples para navegador. Basta inserir o texto, definir o texto que deseja substituir e o valor de substituiรงรฃo e obter a versรฃo atualizada instantaneamente.",
+ "title": "Substituidor de texto"
+ }
+ },
+ "toMorse": {
+ "dashSymbolDescription": "Sรญmbolo que corresponderรก ao travessรฃo no cรณdigo Morse.",
+ "description": "Converta texto em cรณdigo Morse.",
+ "dotSymbolDescription": "Sรญmbolo que corresponderรก ao ponto no cรณdigo Morse.",
+ "longSignal": "Sinal longo",
+ "resultTitle": "cรณdigo Morse",
+ "shortDescription": "Codifique rapidamente o texto para Morse",
+ "shortSignal": "Sinal curto",
+ "title": "String para Morse"
+ },
+ "truncate": {
+ "addTruncationIndicator": "Adicionar Indicador de Truncamento",
+ "charactersPlaceholder": "Personagens",
+ "description": "Encurte o texto para um comprimento especificado.",
+ "indicatorDescription": "Caracteres a serem adicionados ao final (ou inรญcio) do texto. Observaรงรฃo: eles contam para o comprimento.",
+ "inputTitle": "Texto de entrada",
+ "leftSideDescription": "Remova caracteres do inรญcio do texto.",
+ "leftSideTruncation": "Truncamento do lado esquerdo",
+ "lengthAndLines": "Comprimento e Linhas",
+ "lineByLineDescription": "Trunque cada linha separadamente.",
+ "lineByLineTruncating": "Truncamento linha por linha",
+ "maxLengthDescription": "Nรบmero de caracteres a deixar no texto.",
+ "numberPlaceholder": "Nรบmero",
+ "resultTitle": "Texto truncado",
+ "rightSideDescription": "Remova caracteres do final do texto.",
+ "rightSideTruncation": "Truncamento do lado direito",
+ "shortDescription": "Truncar texto para um comprimento especificado",
+ "suffixAndAffix": "Sufixo e Afixo",
+ "title": "Truncar texto",
+ "toolInfo": {
+ "description": "Carregue seu texto no formulรกrio de entrada ร esquerda e vocรช obterรก automaticamente o texto truncado ร direita.",
+ "title": "Truncar texto"
+ },
+ "truncationSide": "Lado de truncamento"
+ },
+ "uppercase": {
+ "description": "Converta texto em letras maiรบsculas.",
+ "inputTitle": "Texto de entrada",
+ "resultTitle": "Texto em maiรบsculas",
+ "shortDescription": "Converter texto em letras maiรบsculas",
+ "title": "Converter para maiรบsculas"
+ }
+}
diff --git a/public/locales/pt/time.json b/public/locales/pt/time.json
new file mode 100644
index 0000000..ad6f4d1
--- /dev/null
+++ b/public/locales/pt/time.json
@@ -0,0 +1,100 @@
+{
+ "checkLeapYears": {
+ "description": "Verifique se um ano รฉ bissexto e obtenha informaรงรตes sobre o ano bissexto.",
+ "inputTitle": "Ano de entrada",
+ "resultTitle": "Resultado do ano bissexto",
+ "shortDescription": "Verifique se um ano รฉ bissexto",
+ "title": "Verifique os anos bissextos",
+ "toolInfo": {
+ "description": "Um ano bissexto รฉ um ano que contรฉm um dia adicional (29 de fevereiro) para manter o ano civil sincronizado com o ano astronรดmico. Anos bissextos ocorrem a cada 4 anos, exceto anos divisรญveis por 100, mas nรฃo por 400.",
+ "title": "O que รฉ um ano bissexto?"
+ }
+ },
+ "convertDaysToHours": {
+ "addHoursName": "Adicionar nome das horas",
+ "addHoursNameDescription": "Adicionar a string horas aos valores de saรญda",
+ "description": "Converta dias em horas com opรงรตes personalizรกveis.",
+ "hoursName": "Nome das horas",
+ "shortDescription": "Converter dias em horas",
+ "title": "Converter dias em horas",
+ "toolInfo": {
+ "description": "Esta ferramenta permite converter dias em horas. Vocรช pode inserir dias como nรบmeros ou unidades, e a ferramenta os converterรก para horas. Vocรช tambรฉm pode optar por adicionar o sufixo \"horas\" aos valores de saรญda.",
+ "title": "Converter dias em horas"
+ }
+ },
+ "convertHoursToDays": {
+ "addDaysName": "Adicionar nome dos dias",
+ "addDaysNameDescription": "Adicione a string days aos valores de saรญda",
+ "daysName": "Nome dos dias",
+ "description": "Converta horas em dias com opรงรตes personalizรกveis.",
+ "shortDescription": "Converter horas em dias",
+ "title": "Converter horas em dias",
+ "toolInfo": {
+ "description": "Esta ferramenta permite converter horas em dias. Vocรช pode inserir horas como nรบmeros ou com unidades, e a ferramenta as converterรก para dias. Vocรช tambรฉm pode optar por adicionar o sufixo \"dias\" aos valores de saรญda.",
+ "title": "Converter horas em dias"
+ }
+ },
+ "convertSecondsToTime": {
+ "addPadding": "Adicionar preenchimento",
+ "addPaddingDescription": "Adicione preenchimento zero ร s horas, minutos e segundos.",
+ "description": "Converta os segundos para um formato de hora legรญvel (horas:minutos:segundos). Insira o nรบmero de segundos para obter a hora formatada.",
+ "shortDescription": "Converter segundos para o formato de hora",
+ "timePadding": "Preenchimento de tempo",
+ "title": "Converter segundos em tempo",
+ "toolInfo": {
+ "title": "O que รฉ um {{title}}?"
+ }
+ },
+ "convertTimeToSeconds": {
+ "description": "Converter hora formatada (HH:MM:SS) em segundos.",
+ "inputTitle": "Tempo de entrada",
+ "resultTitle": "Segundos",
+ "shortDescription": "Converter formato de hora em segundos",
+ "title": "Converter tempo em segundos",
+ "toolInfo": {
+ "description": "Esta ferramenta permite converter sequรชncias de tempo formatadas (HH:MM:SS) em segundos. ร รบtil para calcular duraรงรตes e intervalos de tempo.",
+ "title": "Converter tempo em segundos"
+ }
+ },
+ "crontabGuru": {
+ "description": "Gere e compreenda expressรตes cron. Crie agendamentos cron para tarefas automatizadas e trabalhos do sistema.",
+ "shortDescription": "Gerar e compreender expressรตes cron",
+ "title": "Guru Crontab"
+ },
+ "timeBetweenDates": {
+ "description": "Calcule a diferenรงa de tempo entre duas datas. Obtenha a duraรงรฃo exata em dias, horas, minutos e segundos.",
+ "endDate": "Data de tรฉrmino",
+ "endDateTime": "Data e hora de tรฉrmino",
+ "endTime": "Fim dos tempos",
+ "endTimezone": "Fim do fuso horรกrio",
+ "shortDescription": "Calcular o tempo entre duas datas",
+ "startDate": "Data de inรญcio",
+ "startDateTime": "Data e hora de inรญcio",
+ "startTime": "Hora de inรญcio",
+ "startTimezone": "Fuso horรกrio de inรญcio",
+ "title": "Tempo entre datas",
+ "toolInfo": {
+ "description": "Calcule a diferenรงa horรกria exata entre duas datas e horas, com suporte para diferentes fusos horรกrios. Esta ferramenta fornece uma anรกlise detalhada da diferenรงa horรกria em vรกrias unidades (anos, meses, dias, horas, minutos e segundos).",
+ "title": "Calculadora de tempo entre datas"
+ }
+ },
+ "truncateClockTime": {
+ "description": "Trunque o horรกrio do relรณgio para remover segundos ou minutos. Arredonde o horรกrio para a hora, minuto ou intervalo personalizado mais prรณximo.",
+ "printDroppedComponents": "Imprimir componentes descartados",
+ "shortDescription": "Truncar o tempo do relรณgio para a precisรฃo especificada",
+ "timePadding": "Preenchimento de tempo",
+ "title": "Truncar o tempo do relรณgio",
+ "toolInfo": {
+ "title": "O que รฉ um {{title}}?"
+ },
+ "truncateMinutesAndSeconds": "Truncar minutos e segundos",
+ "truncateMinutesAndSecondsDescription": "Elimine ambos โ os componentes de minutos e segundos de cada relรณgio.",
+ "truncateOnlySeconds": "Truncar apenas segundos",
+ "truncateOnlySecondsDescription": "Retire o componente de segundos de cada hora do relรณgio.",
+ "truncationSide": "Lado de truncamento",
+ "useZeroPadding": "Usar preenchimento zero",
+ "zeroPaddingDescription": "Faรงa com que todos os componentes de tempo tenham sempre dois dรญgitos de largura.",
+ "zeroPrintDescription": "Exibe as partes descartadas como valores zero \"00\".",
+ "zeroPrintTruncatedParts": "Partes truncadas com impressรฃo zero"
+ }
+}
diff --git a/public/locales/pt/translation.json b/public/locales/pt/translation.json
new file mode 100644
index 0000000..066bf84
--- /dev/null
+++ b/public/locales/pt/translation.json
@@ -0,0 +1,250 @@
+{
+ "audio": {
+ "changeSpeed": {
+ "description": "Altere a velocidade de reproduรงรฃo dos arquivos de รกudio. Acelere ou desacelere o รกudio, mantendo o tom.",
+ "name": "Alterar velocidade do รกudio",
+ "shortDescription": "Alterar a velocidade dos arquivos de รกudio"
+ },
+ "extractAudio": {
+ "description": "Extraia a faixa de รกudio de um arquivo de vรญdeo e salve-a como um arquivo de รกudio separado no formato escolhido (AAC, MP3, WAV).",
+ "name": "Extrair รกudio",
+ "shortDescription": "Extraia รกudio de arquivos de vรญdeo (MP4, MOV, etc.) para AAC, MP3 ou WAV."
+ }
+ },
+ "baseFileInput": {
+ "copyFailed": "Falha ao copiar: {{error}}",
+ "dropFileHere": "Largue o seu {{type}} aqui",
+ "fileCopied": "Arquivo copiado",
+ "selectFileDescription": "Clique aqui para selecionar um {{type}} do seu dispositivo, pressione Ctrl+V para usar um {{type}} da sua รกrea de transferรชncia ou arraste e solte um arquivo da รกrea de trabalho"
+ },
+ "categories": {
+ "audio": {
+ "description": "Ferramentas para trabalhar com รกudio โ extrair รกudio de vรญdeo, ajustar a velocidade do รกudio, mesclar vรกrios arquivos de รกudio e muito mais.",
+ "title": "Ferramentas de รกudio"
+ },
+ "csv": {
+ "description": "Ferramentas para trabalhar com arquivos CSV - converta CSV para diferentes formatos, manipule dados CSV, valide a estrutura CSV e processe arquivos CSV com eficiรชncia.",
+ "title": "Ferramentas CSV"
+ },
+ "gif": {
+ "description": "Ferramentas para trabalhar com animaรงรตes GIF โ crie GIFs transparentes, extraia quadros de GIF, adicione texto ao GIF, corte, gire, inverta GIFs e muito mais.",
+ "title": "Ferramentas GIF"
+ },
+ "image-generic": {
+ "description": "Ferramentas para trabalhar com imagens โ compactar, redimensionar, cortar, converter para JPG, girar, remover fundo e muito mais.",
+ "title": "Ferramentas de imagem"
+ },
+ "json": {
+ "description": "Ferramentas para trabalhar com estruturas de dados JSON โ embelezar e minimizar objetos JSON, achatar matrizes JSON, transformar valores JSON em strings, analisar dados e muito mais",
+ "title": "Ferramentas JSON"
+ },
+ "list": {
+ "description": "Ferramentas para trabalhar com listas โ classificar, reverter, randomizar listas, encontrar itens de lista exclusivos e duplicados, alterar separadores de itens de lista e muito mais.",
+ "title": "Ferramentas de lista"
+ },
+ "number": {
+ "description": "Ferramentas para trabalhar com nรบmeros โ gerar sequรชncias numรฉricas, converter nรบmeros em palavras e palavras em nรบmeros, classificar, arredondar, fatorar nรบmeros e muito mais.",
+ "title": "Ferramentas numรฉricas"
+ },
+ "pdf": {
+ "description": "Ferramentas para trabalhar com arquivos PDF - extraia texto de PDFs, converta PDFs para outros formatos, manipule PDFs e muito mais.",
+ "title": "Ferramentas de PDF"
+ },
+ "png": {
+ "description": "Ferramentas para trabalhar com imagens PNG โ converta PNGs em JPGs, crie PNGs transparentes, altere cores de PNG, corte, gire, redimensione PNGs e muito mais.",
+ "title": "Ferramentas PNG"
+ },
+ "seeAll": "Ver tudo {{title}}",
+ "string": {
+ "description": "Ferramentas para trabalhar com texto โ converter texto em imagens, localizar e substituir texto, dividir texto em fragmentos, unir linhas de texto, repetir texto e muito mais.",
+ "title": "Ferramentas de texto"
+ },
+ "time": {
+ "description": "Ferramentas para trabalhar com hora e data โ calcule diferenรงas de horรกrio, converta entre fusos horรกrios, formate datas, gere sequรชncias de datas e muito mais.",
+ "title": "Ferramentas de tempo"
+ },
+ "try": "Tentar {{title}}",
+ "video": {
+ "description": "Ferramentas para trabalhar com vรญdeos โ extraia quadros de vรญdeos, crie GIFs de vรญdeos, converta vรญdeos para diferentes formatos e muito mais.",
+ "title": "Ferramentas de vรญdeo"
+ },
+ "xml": {
+ "description": "Ferramentas para trabalhar com estruturas de dados XML - visualizador, embelezador, validador e muito mais",
+ "title": "Ferramentas XML"
+ }
+ },
+ "csv": {
+ "findIncompleteCsvRecords": {
+ "description": "Basta enviar seu arquivo CSV no formulรกrio abaixo e esta ferramenta verificarรก automaticamente se nenhuma das linhas ou colunas contรฉm valores ausentes. Nas opรงรตes da ferramenta, vocรช pode ajustar o formato do arquivo de entrada (especifique o delimitador, o caractere de aspas e o caractere de comentรกrio). Alรฉm disso, vocรช pode ativar a verificaรงรฃo de valores vazios, ignorar linhas vazias e definir um limite para o nรบmero de mensagens de erro na saรญda.",
+ "name": "Encontre registros CSV incompletos",
+ "shortDescription": "Encontre rapidamente linhas e colunas em CSV que nรฃo tenham valores."
+ }
+ },
+ "hero": {
+ "brand": "OmniTools",
+ "description": "Aumente sua produtividade com o OmniTools, o kit de ferramentas definitivo para fazer as coisas rapidamente! Acesse milhares de utilitรกrios fรกceis de usar para editar imagens, textos, listas e dados, tudo diretamente do seu navegador.",
+ "examples": {
+ "calculateNumberSum": "Calcular soma numรฉrica",
+ "changeGifSpeed": "Alterar velocidade do GIF",
+ "compressPng": "Comprimir PNG",
+ "createTransparentImage": "Crie uma imagem transparente",
+ "prettifyJson": "Embeleze JSON",
+ "sortList": "Classificar uma lista",
+ "splitPdf": "Dividir PDF",
+ "splitText": "Dividir um texto",
+ "trimVideo": "Cortar vรญdeo"
+ },
+ "searchPlaceholder": "Pesquisar todas as ferramentas",
+ "title": "Faรงa as coisas rapidamente com"
+ },
+ "inputFooter": {
+ "clear": "Claro",
+ "copyToClipboard": "Copiar para a รกrea de transferรชncia",
+ "importFromFile": "Importar de arquivo"
+ },
+ "list": {
+ "group": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para agrupar itens de lista. Insira sua lista e especifique critรฉrios de agrupamento para organizar os itens em grupos lรณgicos. Perfeito para categorizar dados, organizar informaรงรตes ou criar listas estruturadas. Suporta separadores personalizados e diversas opรงรตes de agrupamento.",
+ "name": "Grupo",
+ "shortDescription": "Agrupar itens da lista por propriedades comuns"
+ },
+ "reverse": {
+ "description": "Este รฉ um aplicativo super simples baseado em navegador que imprime todos os itens da lista em ordem inversa. Os itens de entrada podem ser separados por qualquer sรญmbolo e vocรช tambรฉm pode alterar o separador dos itens da lista em ordem inversa.",
+ "name": "Reverter",
+ "shortDescription": "Inverter uma lista rapidamente"
+ },
+ "sort": {
+ "description": "Este รฉ um aplicativo super simples baseado em navegador que classifica itens em uma lista e os organiza em ordem crescente ou decrescente. Vocรช pode classificar os itens em ordem alfabรฉtica, numรฉrica ou por tamanho. Vocรช tambรฉm pode remover itens duplicados e vazios, bem como cortar itens individuais com espaรงos em branco. Vocรช pode usar qualquer caractere separador para separar os itens da lista de entrada ou, alternativamente, usar uma expressรฃo regular para separรก-los. Alรฉm disso, vocรช pode criar um novo delimitador para a lista de saรญda classificada.",
+ "name": "Organizar",
+ "shortDescription": "Classifique uma lista rapidamente"
+ }
+ },
+ "navbar": {
+ "buyMeACoffee": "Compre-me um cafรฉ",
+ "home": "Lar",
+ "tools": "Ferramentas"
+ },
+ "number": {
+ "generate": {
+ "description": "Calcule rapidamente uma lista de nรบmeros inteiros no seu navegador. Para obter sua lista, basta especificar o primeiro nรบmero inteiro, alterar o valor e a contagem total nas opรงรตes abaixo, e este utilitรกrio gerarรก essa quantidade de nรบmeros inteiros.",
+ "name": "Gerar nรบmeros",
+ "shortDescription": "Calcule rapidamente uma lista de inteiros no seu navegador"
+ },
+ "sum": {
+ "description": "Este รฉ um aplicativo super simples para navegador que soma nรบmeros. Os nรบmeros inseridos podem ser separados por qualquer sรญmbolo e vocรช tambรฉm pode alterar o separador dos nรบmeros somados.",
+ "name": "Somar nรบmeros",
+ "shortDescription": "Some rapidamente uma lista de nรบmeros"
+ }
+ },
+ "numericInputWithUnit": {
+ "unit": "Unidade"
+ },
+ "pdf": {
+ "compressPdf": {
+ "description": "Reduza o tamanho do arquivo PDF mantendo a qualidade usando Ghostscript",
+ "name": "Comprimir PDF",
+ "shortDescription": "Compacte arquivos PDF com seguranรงa no seu navegador"
+ },
+ "mergePdf": {
+ "description": "Combine vรกrios arquivos PDF em um รบnico documento.",
+ "name": "Mesclar PDF",
+ "shortDescription": "Mesclar vรกrios arquivos PDF em um รบnico documento"
+ },
+ "pdfToEpub": {
+ "description": "Transforme documentos PDF em arquivos EPUB para melhor compatibilidade com leitores eletrรดnicos.",
+ "name": "PDF para EPUB",
+ "shortDescription": "Converter arquivos PDF para o formato EPUB"
+ },
+ "protectPdf": {
+ "description": "Adicione proteรงรฃo por senha aos seus arquivos PDF com seguranรงa no seu navegador",
+ "name": "Proteger PDF",
+ "shortDescription": "Proteja arquivos PDF com senha com seguranรงa"
+ },
+ "splitPdf": {
+ "description": "Extraia pรกginas especรญficas de um arquivo PDF usando nรบmeros de pรกgina ou intervalos (por exemplo, 1,5-8)",
+ "name": "Dividir PDF",
+ "shortDescription": "Extrair pรกginas especรญficas de um arquivo PDF"
+ }
+ },
+ "resultFooter": {
+ "copy": "Copiar para a รกrea de transferรชncia",
+ "download": "Download"
+ },
+ "string": {
+ "createPalindrome": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para criar palรญndromos a partir de qualquer texto. Insira texto e transforme-o instantaneamente em um palรญndromo com a mesma leitura de trรกs para frente. Perfeito para jogos de palavras, criaรงรฃo de padrรตes de texto simรฉtricos ou exploraรงรฃo de curiosidades linguรญsticas.",
+ "name": "Criar palรญndromo",
+ "shortDescription": "Crie um texto que seja lido da mesma forma para frente e para trรกs"
+ },
+ "palindrome": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para verificar se um texto รฉ um palรญndromo. Verifique instantaneamente se o seu texto รฉ lido da mesma forma, de trรกs para frente. Perfeito para quebra-cabeรงas de palavras, anรกlise linguรญstica ou validaรงรฃo de padrรตes de texto simรฉtricos. Suporta vรกrios delimitadores e detecรงรฃo de palรญndromos de vรกrias palavras.",
+ "name": "Palรญndromo",
+ "shortDescription": "Verifique se o texto รฉ lido da mesma forma para frente e para trรกs"
+ },
+ "repeat": {
+ "description": "Esta ferramenta permite que vocรช repita um determinado texto vรกrias vezes com um separador opcional.",
+ "name": "Repetir texto",
+ "shortDescription": "Repita o texto vรกrias vezes"
+ },
+ "reverse": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para inverter texto. Insira qualquer texto e inverta-o instantaneamente, caractere por caractere. Perfeito para criar texto espelhado, analisar palรญndromos ou brincar com padrรตes de texto. Preserva espaรงos e caracteres especiais durante a inversรฃo.",
+ "name": "Reverter",
+ "shortDescription": "Inverter qualquer texto caractere por caractere"
+ },
+ "toMorse": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para converter texto em cรณdigo Morse. Carregue seu texto no formulรกrio de entrada ร esquerda e vocรช obterรก o cรณdigo Morse instantaneamente na รกrea de saรญda. Poderoso, gratuito e rรกpido. Carregue texto โ obtenha cรณdigo Morse.",
+ "name": "String para Morse",
+ "shortDescription": "Codifique rapidamente o texto para Morse"
+ },
+ "uppercase": {
+ "description": "O utilitรกrio baseado em navegador mais simples do mundo para converter texto em letras maiรบsculas. Basta inserir o texto e ele serรก convertido automaticamente para letras maiรบsculas. Perfeito para criar tรญtulos, enfatizar texto ou padronizar o formato de texto. Suporta vรกrios formatos de texto e preserva caracteres especiais.",
+ "name": "Maiรบsculas",
+ "shortDescription": "Converter texto em letras maiรบsculas"
+ }
+ },
+ "toolExamples": {
+ "subtitle": "Clique para experimentar!",
+ "title": "{{title}} Exemplos"
+ },
+ "toolFileResult": {
+ "copied": "Arquivo copiado",
+ "copyFailed": "Falha ao copiar: {{error}}",
+ "loading": "Carregando... Isso pode demorar um momento.",
+ "result": "Resultado"
+ },
+ "toolHeader": {
+ "seeExamples": "Veja exemplos"
+ },
+ "toolLayout": {
+ "allToolsTitle": "Todos {{type}}"
+ },
+ "toolMultiFileResult": {
+ "copied": "Arquivo copiado",
+ "copyFailed": "Falha ao copiar: {{error}}",
+ "loading": "Carregando... Isso pode demorar um momento.",
+ "result": "Resultado"
+ },
+ "toolMultipleAudioInput": {
+ "inputTitle": "Entrada {{type}}",
+ "noFilesSelected": "Nenhum arquivo selecionado"
+ },
+ "toolMultiplePdfInput": {
+ "inputTitle": "Entrada {{type}}",
+ "noFilesSelected": "Nenhum arquivo selecionado"
+ },
+ "toolOptions": {
+ "title": "Opรงรตes de ferramentas"
+ },
+ "toolTextInput": {
+ "copied": "Texto copiado",
+ "copyFailed": "Falha ao copiar: {{error}}",
+ "input": "Texto de entrada",
+ "placeholder": "Digite seu texto aqui..."
+ },
+ "toolTextResult": {
+ "copied": "Texto copiado",
+ "copyFailed": "Falha ao copiar: {{error}}",
+ "loading": "Carregando... Isso pode demorar um momento.",
+ "result": "Resultado"
+ }
+}
diff --git a/public/locales/pt/video.json b/public/locales/pt/video.json
new file mode 100644
index 0000000..19f9077
--- /dev/null
+++ b/public/locales/pt/video.json
@@ -0,0 +1,113 @@
+{
+ "changeSpeed": {
+ "defaultMultiplier": "Multiplicador padrรฃo: 2 significa 2x mais rรกpido",
+ "description": "Altere a velocidade de reproduรงรฃo de arquivos de vรญdeo. Acelere ou desacelere vรญdeos, mantendo a sincronizaรงรฃo do รกudio. Suporta vรกrios multiplicadores de velocidade e formatos de vรญdeo comuns.",
+ "inputTitle": "Entrada de vรญdeo",
+ "newVideoSpeed": "Nova velocidade de vรญdeo",
+ "resultTitle": "Vรญdeo editado",
+ "settingSpeed": "Definindo a velocidade",
+ "shortDescription": "Alterar a velocidade de reproduรงรฃo do vรญdeo",
+ "title": "Alterar velocidade do vรญdeo",
+ "toolInfo": {
+ "title": "O que รฉ um {{title}}?"
+ }
+ },
+ "compress": {
+ "default": "Padrรฃo",
+ "description": "Compacte vรญdeos dimensionando-os para diferentes resoluรงรตes, como 240p, 480p, 720p, etc. Esta ferramenta ajuda a reduzir o tamanho do arquivo, mantendo uma qualidade aceitรกvel. Suporta formatos de vรญdeo comuns, como MP4, WebM e OGG.",
+ "inputTitle": "Entrada de vรญdeo",
+ "loadingText": "Compactando vรญdeo...",
+ "lossless": "Sem perdas",
+ "quality": "Qualidade (CRF)",
+ "resolution": "Resoluรงรฃo",
+ "resultTitle": "Vรญdeo compactado",
+ "shortDescription": "Comprimir vรญdeos dimensionando-os para diferentes resoluรงรตes",
+ "title": "Comprimir vรญdeo",
+ "worst": "Pior"
+ },
+ "cropVideo": {
+ "cropCoordinates": "Coordenadas de corte",
+ "croppingVideo": "Recortando vรญdeo",
+ "description": "Corte o vรญdeo para remover รกreas indesejadas.",
+ "errorBeyondHeight": "A รกrea de corte se estende alรฉm da altura do vรญdeo ({{height}}px)",
+ "errorBeyondWidth": "A รกrea de corte se estende alรฉm da largura do vรญdeo ({{width}}px)",
+ "errorCroppingVideo": "Erro ao cortar o vรญdeo. Verifique os parรขmetros e o arquivo de vรญdeo.",
+ "errorLoadingDimensions": "Falha ao carregar as dimensรตes do vรญdeo",
+ "errorNonNegativeCoordinates": "As coordenadas X e Y devem ser nรฃo negativas",
+ "errorPositiveDimensions": "Largura e altura devem ser positivas",
+ "height": "Altura",
+ "inputTitle": "Entrada de vรญdeo",
+ "loadVideoForDimensions": "Carregue um vรญdeo para ver as dimensรตes",
+ "resultTitle": "Vรญdeo recortado",
+ "shortDescription": "Recorte o vรญdeo para remover รกreas indesejadas",
+ "title": "Cortar vรญdeo",
+ "toolInfo": {
+ "description": "Esta ferramenta permite cortar arquivos de vรญdeo para remover รกreas indesejadas. Vocรช pode especificar a รกrea de corte definindo as coordenadas X, Y e as dimensรตes de largura e altura.",
+ "title": "Cortar vรญdeo"
+ },
+ "videoDimensions": "Dimensรตes do vรญdeo: {{width}} ร {{height}} pixels",
+ "videoInformation": "Informaรงรตes do vรญdeo",
+ "width": "Largura",
+ "xCoordinate": "X (esquerda)",
+ "yCoordinate": "Y (topo)"
+ },
+ "flip": {
+ "description": "Inverta arquivos de vรญdeo horizontal ou verticalmente. Espelhe vรญdeos para obter efeitos especiais ou corrigir problemas de orientaรงรฃo.",
+ "flippingVideo": "Invertendo o vรญdeo",
+ "horizontalLabel": "Horizontal (Espelho)",
+ "inputTitle": "Entrada de vรญdeo",
+ "orientation": "Orientaรงรฃo",
+ "resultTitle": "Vรญdeo invertido",
+ "shortDescription": "Inverter o vรญdeo horizontalmente ou verticalmente",
+ "title": "Flip Video",
+ "verticalLabel": "Vertical (de cabeรงa para baixo)"
+ },
+ "gif": {
+ "changeSpeed": {
+ "description": "Altere a velocidade de reproduรงรฃo de animaรงรตes GIF. Acelere ou desacelere GIFs, mantendo a animaรงรฃo suave.",
+ "shortDescription": "Alterar a velocidade da animaรงรฃo GIF",
+ "title": "Alterar velocidade do GIF"
+ }
+ },
+ "loop": {
+ "description": "Crie um vรญdeo em loop repetindo o vรญdeo original vรกrias vezes.",
+ "inputTitle": "Entrada de vรญdeo",
+ "loopingVideo": "Vรญdeo em loop",
+ "loops": "Laรงos",
+ "numberOfLoops": "Nรบmero de Loops",
+ "resultTitle": "Vรญdeo em loop",
+ "shortDescription": "Crie arquivos de vรญdeo em loop",
+ "title": "Vรญdeo em loop",
+ "toolInfo": {
+ "description": "Esta ferramenta permite criar um vรญdeo em loop repetindo o vรญdeo original vรกrias vezes. Vocรช pode especificar quantas vezes o vรญdeo deve ser repetido.",
+ "title": "O que รฉ um {{title}}?"
+ }
+ },
+ "rotate": {
+ "180Degrees": "180ยฐ (de cabeรงa para baixo)",
+ "270Degrees": "270ยฐ (90ยฐ sentido anti-horรกrio)",
+ "90Degrees": "90ยฐ no sentido horรกrio",
+ "description": "Gire arquivos de vรญdeo em 90, 180 ou 270 graus. Corrija a orientaรงรฃo do vรญdeo ou crie efeitos especiais com controle de rotaรงรฃo preciso.",
+ "inputTitle": "Entrada de vรญdeo",
+ "resultTitle": "Vรญdeo girado",
+ "rotatingVideo": "Vรญdeo rotativo",
+ "rotation": "Rotaรงรฃo",
+ "shortDescription": "Girar o vรญdeo em graus especificados",
+ "title": "Girar vรญdeo"
+ },
+ "trim": {
+ "description": "Corte arquivos de vรญdeo especificando os horรกrios de inรญcio e tรฉrmino. Remova trechos indesejados do inรญcio ou do fim dos vรญdeos.",
+ "endTime": "Fim dos tempos",
+ "inputTitle": "Entrada de vรญdeo",
+ "resultTitle": "Vรญdeo recortado",
+ "shortDescription": "Corte o vรญdeo removendo seรงรตes indesejadas",
+ "startTime": "Hora de inรญcio",
+ "timestamps": "Carimbos de data e hora",
+ "title": "Cortar vรญdeo"
+ },
+ "videoToGif": {
+ "description": "Converta arquivos de vรญdeo para o formato GIF animado. Extraia intervalos de tempo especรญficos e crie imagens animadas compartilhรกveis.",
+ "shortDescription": "Converter vรญdeo em GIF animado",
+ "title": "Vรญdeo para GIF"
+ }
+}
diff --git a/public/locales/pt/xml.json b/public/locales/pt/xml.json
new file mode 100644
index 0000000..4e6b12d
--- /dev/null
+++ b/public/locales/pt/xml.json
@@ -0,0 +1,38 @@
+{
+ "xmlBeautifier": {
+ "description": "Formate XML com recuo e espaรงamento adequados.",
+ "indentation": "Recuo",
+ "inputTitle": "XML de entrada",
+ "resultTitle": "XML embelezado",
+ "shortDescription": "Formate e embeleze o cรณdigo XML",
+ "title": "Embelezador XML",
+ "toolInfo": {
+ "description": "Esta ferramenta permite formatar dados XML com recuo e espaรงamento adequados, tornando-os mais legรญveis e fรกceis de trabalhar.",
+ "title": "Embelezador XML"
+ },
+ "useSpaces": "Use Espaรงos",
+ "useSpacesDescription": "Recuar a saรญda com espaรงos",
+ "useTabs": "Usar guias",
+ "useTabsDescription": "Recuar a saรญda com tabulaรงรตes."
+ },
+ "xmlValidator": {
+ "description": "Valide a sintaxe e a estrutura do XML.",
+ "placeholder": "Cole ou importe XML aqui...",
+ "shortDescription": "Validar cรณdigo XML para erros",
+ "title": "Validador XML",
+ "toolInfo": {
+ "description": "Esta ferramenta permite validar a sintaxe e a estrutura do XML. Ela verifica se o XML estรก bem formado e fornece mensagens de erro detalhadas para quaisquer problemas encontrados.",
+ "title": "Validador XML"
+ }
+ },
+ "xmlViewer": {
+ "description": "Visualize e explore a estrutura XML em formato de รกrvore.",
+ "inputTitle": "XML de entrada",
+ "resultTitle": "Visualizaรงรฃo em รกrvore XML",
+ "title": "Visualizador XML",
+ "toolInfo": {
+ "description": "Esta ferramenta permite que vocรช visualize dados XML em um formato de รกrvore hierรกrquica, facilitando a exploraรงรฃo e a compreensรฃo da estrutura de documentos XML.",
+ "title": "Visualizador XML"
+ }
+ }
+}
diff --git a/public/locales/ru/audio.json b/public/locales/ru/audio.json
new file mode 100644
index 0000000..cab0caa
--- /dev/null
+++ b/public/locales/ru/audio.json
@@ -0,0 +1,42 @@
+{
+ "changeSpeed": {
+ "description": "ะะทะผะตะฝะธัะต ัะบะพัะพััั ะฒะพัะฟัะพะธะทะฒะตะดะตะฝะธั ะฐัะดะธะพัะฐะนะปะพะฒ. ะฃัะบะพัััะต ะธะปะธ ะทะฐะผะตะดะปะธัะต ะทะฒัะบ, ัะพั
ัะฐะฝัั ะฒััะพัั ะทะฒัะบะฐ.",
+ "inputTitle": "ะั
ะพะดะฝะพะน ะฐัะดะธะพัะธะณะฝะฐะป",
+ "newAudioSpeed": "ะะพะฒะฐั ัะบะพัะพััั ะทะฒัะบะฐ",
+ "outputFormat": "ะคะพัะผะฐั ะฒัะฒะพะดะฐ",
+ "resultTitle": "ะััะตะดะฐะบัะธัะพะฒะฐะฝะฝัะน ะฐัะดะธะพัะฐะนะป",
+ "settingSpeed": "ะกะบะพัะพััั ัััะฐะฝะพะฒะบะธ",
+ "shortDescription": "ะะทะผะตะฝะธัั ัะบะพัะพััั ะฐัะดะธะพัะฐะนะปะพะฒ",
+ "speedDescription": "ะะฝะพะถะธัะตะปั ะฟะพ ัะผะพะปัะฐะฝะธั: 2 ะพะทะฝะฐัะฐะตั ะฒ 2 ัะฐะทะฐ ะฑััััะตะต",
+ "title": "ะะทะผะตะฝะธัั ัะบะพัะพััั ะทะฒัะบะฐ",
+ "toolInfo": {
+ "title": "ะงัะพ ัะฐะบะพะต {{title}}?"
+ }
+ },
+ "extractAudio": {
+ "description": "ะะทะฒะปะตัั ะทะฒัะบะพะฒัั ะดะพัะพะถะบั ะธะท ะฒะธะดะตะพัะฐะนะปะพะฒ.",
+ "extractingAudio": "ะะทะฒะปะตัะตะฝะธะต ะฐัะดะธะพ",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะฒะธะดะตะพ",
+ "outputFormat": "ะคะพัะผะฐั ะฒัะฒะพะดะฐ",
+ "outputFormatDescription": "ะัะฑะตัะธัะต ัะพัะผะฐั, ะฒ ะบะพัะพัะพะผ ะฑัะดะตั ะธะทะฒะปะตัะตะฝ ะฐัะดะธะพัะฐะนะป.",
+ "resultTitle": "ะะทะฒะปะตัะตะฝะฝัะน ะฐัะดะธะพัะฐะนะป",
+ "shortDescription": "ะะทะฒะปะตะบะฐะนัะต ะฐัะดะธะพ ะธะท ะฒะธะดะตะพัะฐะนะปะพะฒ (MP4, MOV ะธ ั. ะด.) ะฒ ัะพัะผะฐัั AAC, MP3 ะธะปะธ WAV.",
+ "title": "ะะทะฒะปะตัั ะฐัะดะธะพ ะธะท ะฒะธะดะตะพ",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะธะทะฒะปะตะบะฐัั ะทะฒัะบะพะฒัั ะดะพัะพะถะบั ะธะท ะฒะธะดะตะพัะฐะนะปะพะฒ. ะั ะผะพะถะตัะต ะฒัะฑัะฐัั ัะฐะทะปะธัะฝัะต ะฐัะดะธะพัะพัะผะฐัั, ะฒะบะปััะฐั AAC, MP3 ะธ WAV.",
+ "title": "ะงัะพ ัะฐะบะพะต {{title}}?"
+ }
+ },
+ "mergeAudio": {
+ "description": "ะะฑัะตะดะธะฝะธัะต ะฝะตัะบะพะปัะบะพ ะฐัะดะธะพัะฐะนะปะพะฒ ะฒ ะพะดะธะฝ, ะพะฑัะตะดะธะฝะธะฒ ะธั
ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพ.",
+ "longDescription": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะพะฑัะตะดะธะฝะธัั ะฝะตัะบะพะปัะบะพ ะฐัะดะธะพัะฐะนะปะพะฒ ะฒ ะพะดะธะฝ, ะพะฑัะตะดะธะฝัั ะธั
ะฒ ะฟะพััะดะบะต ะทะฐะณััะทะบะธ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะพะฑัะตะดะธะฝะตะฝะธั ััะฐะณะผะตะฝัะพะฒ ะฟะพะดะบะฐััะพะฒ, ะผัะทัะบะฐะปัะฝัั
ััะตะบะพะฒ ะธ ะปัะฑัั
ะดััะณะธั
ะฐัะดะธะพัะฐะนะปะพะฒ, ะบะพัะพััะต ะฝะตะพะฑั
ะพะดะธะผะพ ะพะฑัะตะดะธะฝะธัั. ะะพะดะดะตัะถะธะฒะฐะตั ัะฐะทะปะธัะฝัะต ะฐัะดะธะพัะพัะผะฐัั, ะฒะบะปััะฐั MP3, AAC ะธ WAV.",
+ "shortDescription": "ะะฑัะตะดะธะฝะธัั ะฝะตัะบะพะปัะบะพ ะฐัะดะธะพัะฐะนะปะพะฒ ะฒ ะพะดะธะฝ (MP3, AAC, WAV).",
+ "title": "ะะฑัะตะดะธะฝะธัั ะฐัะดะธะพ"
+ },
+ "trim": {
+ "description": "ะััะตะทะฐะนัะต ะธ ะพะฑัะตะทะฐะนัะต ะฐัะดะธะพัะฐะนะปั, ััะพะฑั ะธะทะฒะปะตัั ะพะฟัะตะดะตะปะตะฝะฝัะต ัะตะณะผะตะฝัั, ัะบะฐะทะฐะฒ ะฒัะตะผั ะฝะฐัะฐะปะฐ ะธ ะพะบะพะฝัะฐะฝะธั.",
+ "longDescription": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะพะฑัะตะทะฐัั ะฐัะดะธะพัะฐะนะปั, ัะบะฐะทะฐะฒ ะฝะฐัะฐะปัะฝะพะต ะธ ะบะพะฝะตัะฝะพะต ะฒัะตะผั. ะั ะผะพะถะตัะต ะธะทะฒะปะตะบะฐัั ะพัะดะตะปัะฝัะต ััะฐะณะผะตะฝัั ะธะท ะดะปะธะฝะฝัั
ะฐัะดะธะพัะฐะนะปะพะฒ, ัะดะฐะปััั ะฝะตะฝัะถะฝัะต ััะฐะณะผะตะฝัั ะธะปะธ ัะพะทะดะฐะฒะฐัั ะฑะพะปะตะต ะบะพัะพัะบะธะต ะบะปะธะฟั. ะะพะดะดะตัะถะธะฒะฐะตั ัะฐะทะปะธัะฝัะต ะฐัะดะธะพัะพัะผะฐัั, ะฒะบะปััะฐั MP3, AAC ะธ WAV. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะตะดะฐะบัะธัะพะฒะฐะฝะธั ะฟะพะดะบะฐััะพะฒ, ัะพะทะดะฐะฝะธั ะผัะทัะบะธ ะธ ะปัะฑัั
ะดััะณะธั
ะทะฐะดะฐั ะฐัะดะธะพะผะพะฝัะฐะถะฐ.",
+ "shortDescription": "ะะฑัะตะทะฐะนัะต ะฐัะดะธะพัะฐะนะปั, ะธะทะฒะปะตะบะฐั ะพะฟัะตะดะตะปะตะฝะฝัะต ะฒัะตะผะตะฝะฝัะต ัะตะณะผะตะฝัั (MP3, AAC, WAV).",
+ "title": "ะะฑัะตะทะฐัั ะฐัะดะธะพ"
+ }
+}
diff --git a/public/locales/ru/csv.json b/public/locales/ru/csv.json
new file mode 100644
index 0000000..1ce4f2d
--- /dev/null
+++ b/public/locales/ru/csv.json
@@ -0,0 +1,114 @@
+{
+ "changeCsvSeparator": {
+ "description": "ะะทะผะตะฝะธัะต ัะฐะทะดะตะปะธัะตะปั/ัะฐะทะดะตะปะธัะตะปั ะฒ CSV-ัะฐะนะปะฐั
. ะะพะฝะฒะตััะธััะนัะต ะดะฐะฝะฝัะต ะผะตะถะดั ัะฐะทะปะธัะฝัะผะธ ัะพัะผะฐัะฐะผะธ CSV, ัะฐะบะธะผะธ ะบะฐะบ ะทะฐะฟััะฐั, ัะพัะบะฐ ั ะทะฐะฟััะพะน, ัะฐะฑัะปััะธั ะธะปะธ ะฟะพะปัะทะพะฒะฐัะตะปััะบะธะต ัะฐะทะดะตะปะธัะตะปะธ.",
+ "shortDescription": "ะะทะผะตะฝะธัั ัะฐะทะดะตะปะธัะตะปั CSV-ัะฐะนะปะฐ",
+ "title": "ะะทะผะตะฝะธัั ัะฐะทะดะตะปะธัะตะปั CSV"
+ },
+ "csvRowsToColumns": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟัะตะพะฑัะฐะทัะตั ัััะพะบะธ CSV-ัะฐะนะปะฐ (ะทะฝะฐัะตะฝะธั, ัะฐะทะดะตะปัะฝะฝัะต ะทะฐะฟัััะผะธ) ะฒ ััะพะปะฑัั. ะะฝ ะธะทะฒะปะตะบะฐะตั ะณะพัะธะทะพะฝัะฐะปัะฝัะต ัััะพะบะธ ะธะท ะฒั
ะพะดะฝะพะณะพ CSV-ัะฐะนะปะฐ ะพะดะฝั ะทะฐ ะดััะณะพะน, ะฟะพะฒะพัะฐัะธะฒะฐะตั ะธั
ะฝะฐ 90 ะณัะฐะดััะพะฒ ะธ ะฒัะฒะพะดะธั ะฒ ะฒะธะดะต ะฒะตััะธะบะฐะปัะฝัั
ััะพะปะฑัะพะฒ, ัะฐะทะดะตะปัะฝะฝัั
ะทะฐะฟัััะผะธ.', longDescription: 'ะญัะพั ะธะฝััััะผะตะฝั ะฟัะตะพะฑัะฐะทัะตั ัััะพะบะธ CSV-ัะฐะนะปะฐ (ะทะฝะฐัะตะฝะธั, ัะฐะทะดะตะปัะฝะฝัะต ะทะฐะฟัััะผะธ) ะฒ ััะพะปะฑัั. ะะฐะฟัะธะผะตั, ะตัะปะธ ะฒั
ะพะดะฝัะต ะดะฐะฝะฝัะต CSV-ัะฐะนะปะฐ ัะพะดะตัะถะฐั 6 ัััะพะบ, ัะพ ะธ ะฒัั
ะพะดะฝัะต ะดะฐะฝะฝัะต ะฑัะดัั ัะพะดะตัะถะฐัั 6 ััะพะปะฑัะพะฒ, ะฐ ัะปะตะผะตะฝัั ัััะพะบ ะฑัะดัั ัะฐัะฟะพะปะพะถะตะฝั ัะฒะตัั
ั ะฒะฝะธะท. ะ ะฟัะฐะฒะธะปัะฝะพ ััะพัะผะธัะพะฒะฐะฝะฝะพะผ CSV-ัะฐะนะปะต ะบะพะปะธัะตััะฒะพ ะทะฝะฐัะตะฝะธะน ะฒ ะบะฐะถะดะพะน ัััะพะบะต ะพะดะธะฝะฐะบะพะฒะพ. ะะดะฝะฐะบะพ, ะตัะปะธ ะฒ ัััะพะบะฐั
ะพััััััะฒััั ะฟะพะปั, ะฟัะพะณัะฐะผะผะฐ ะผะพะถะตั ะธั
ะธัะฟัะฐะฒะธัั, ะธ ะฒั ะผะพะถะตัะต ะฒัะฑัะฐัั ะพะดะธะฝ ะธะท ะดะพัััะฟะฝัั
ะฒะฐัะธะฐะฝัะพะฒ: ะทะฐะฟะพะปะฝะธัั ะพััััััะฒัััะธะต ะดะฐะฝะฝัะต ะฟััััะผะธ ัะปะตะผะตะฝัะฐะผะธ ะธะปะธ ะทะฐะผะตะฝะธัั ะพััััััะฒัััะธะต ะดะฐะฝะฝัะต ะฟะพะปัะทะพะฒะฐัะตะปััะบะธะผะธ ัะปะตะผะตะฝัะฐะผะธ, ัะฐะบะธะผะธ ะบะฐะบ ยซmissingยป, ยซ?ยป ะธะปะธ ยซxยป. ะ ะฟัะพัะตััะต ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธั ะธะฝััััะผะตะฝั ัะฐะบะถะต ะพัะธัะฐะตั CSV-ัะฐะนะป ะพั ะฝะตะฝัะถะฝะพะน ะธะฝัะพัะผะฐัะธะธ, ัะฐะบะพะน ะบะฐะบ ะฟััััะต ัััะพะบะธ (ัััะพะบะธ ะฑะตะท ะฒะธะดะธะผะพะน ะธะฝัะพัะผะฐัะธะธ) ะธ ะบะพะผะผะตะฝัะฐัะธะธ. ะงัะพะฑั ะธะฝััััะผะตะฝั ะฟัะฐะฒะธะปัะฝะพ ัะฐัะฟะพะทะฝะฐะฒะฐะป ะบะพะผะผะตะฝัะฐัะธะธ, ะฒ ะฝะฐัััะพะนะบะฐั
ะผะพะถะฝะพ ัะบะฐะทะฐัั ัะธะผะฒะพะป ะฒ ะฝะฐัะฐะปะต ัััะพะบะธ, ั ะบะพัะพัะพะน ะฝะฐัะธะฝะฐะตััั ะบะพะผะผะตะฝัะฐัะธะน. ะะฑััะฝะพ ััะพ ัะตัััะบะฐ ยซ#ยป ะธะปะธ ะดะฒะพะนะฝะพะน ัะปะตั ยซ//ยป. CSV-abulous!",
+ "longDescription": "ะญัะพั ะธะฝััััะผะตะฝั ะฟัะตะพะฑัะฐะทัะตั ัััะพะบะธ CSV-ัะฐะนะปะฐ (ัะฐะนะป ั ัะฐะทะดะตะปะธัะตะปัะผะธ-ะทะฐะฟัััะผะธ) ะฒ ััะพะปะฑัั. ะะฐะฟัะธะผะตั, ะตัะปะธ ะฒั
ะพะดะฝัะต ะดะฐะฝะฝัะต CSV-ัะฐะนะปะฐ ัะพะดะตัะถะฐั 6 ัััะพะบ, ะฒัั
ะพะดะฝัะต ะดะฐะฝะฝัะต ะฑัะดัั ัะพะดะตัะถะฐัั 6 ััะพะปะฑัะพะฒ, ะฐ ัะปะตะผะตะฝัั ัััะพะบ ะฑัะดัั ัะฐัะฟะพะปะพะถะตะฝั ัะฒะตัั
ั ะฒะฝะธะท. ะ ะฟัะฐะฒะธะปัะฝะพ ััะพัะผะธัะพะฒะฐะฝะฝะพะผ CSV-ัะฐะนะปะต ะบะพะปะธัะตััะฒะพ ะทะฝะฐัะตะฝะธะน ะฒ ะบะฐะถะดะพะน ัััะพะบะต ะพะดะธะฝะฐะบะพะฒะพ. ะะดะฝะฐะบะพ, ะตัะปะธ ะฒ ัััะพะบะฐั
ะพััััััะฒััั ะฟะพะปั, ะฟัะพะณัะฐะผะผะฐ ะผะพะถะตั ะธั
ะธัะฟัะฐะฒะธัั, ะธ ะฒั ะผะพะถะตัะต ะฒัะฑัะฐัั ะพะดะธะฝ ะธะท ะดะพัััะฟะฝัั
ะฒะฐัะธะฐะฝัะพะฒ: ะทะฐะฟะพะปะฝะธัั ะพััััััะฒัััะธะต ะดะฐะฝะฝัะต ะฟััััะผะธ ัะปะตะผะตะฝัะฐะผะธ ะธะปะธ ะทะฐะผะตะฝะธัั ะพััััััะฒัััะธะต ะดะฐะฝะฝัะต ะฟะพะปัะทะพะฒะฐัะตะปััะบะธะผะธ ัะปะตะผะตะฝัะฐะผะธ, ะฝะฐะฟัะธะผะตั,",
+ "shortDescription": "ะัะตะพะฑัะฐะทะพะฒะฐัั ัััะพะบะธ CSV ะฒ ััะพะปะฑัั.",
+ "title": "ะัะตะพะฑัะฐะทะพะฒะฐะฝะธะต ัััะพะบ CSV ะฒ ััะพะปะฑัั"
+ },
+ "csvToJson": {
+ "columnSeparator": "ะ ะฐะทะดะตะปะธัะตะปั ััะพะปะฑัะพะฒ (ะฝะฐะฟัะธะผะตั, , ; \\t)",
+ "commentSymbol": "ะกะธะผะฒะพะป ะบะพะผะผะตะฝัะฐัะธั (ะฝะฐะฟัะธะผะตั, #)",
+ "conversionOptions": "ะะฐัะธะฐะฝัั ะบะพะฝะฒะตััะฐัะธะธ",
+ "description": "ะะพะฝะฒะตััะธััะนัะต CSV-ัะฐะนะปั ะฒ ัะพัะผะฐั JSON ั ะฝะฐัััะฐะธะฒะฐะตะผัะผะธ ะฟะฐัะฐะผะตััะฐะผะธ ัะฐะทะดะตะปะธัะตะปะตะน, ะบะฐะฒััะตะบ ะธ ัะพัะผะฐัะธัะพะฒะฐะฝะธั ะฒัะฒะพะดะฐ. ะะพะดะดะตัะถะบะฐ ะทะฐะณะพะปะพะฒะบะพะฒ, ะบะพะผะผะตะฝัะฐัะธะตะฒ ะธ ะดะธะฝะฐะผะธัะตัะบะพะณะพ ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธั ัะธะฟะพะฒ.",
+ "dynamicTypes": "ะะธะฝะฐะผะธัะตัะบะธะต ัะธะฟั",
+ "dynamicTypesDescription": "ะะฒัะพะผะฐัะธัะตัะบะธ ะฟัะตะพะฑัะฐะทะพะฒัะฒะฐัั ัะธัะปะฐ ะธ ะปะพะณะธัะตัะบะธะต ะทะฝะฐัะตะฝะธั",
+ "errorParsing": "ะัะธะฑะบะฐ ะฐะฝะฐะปะธะทะฐ CSV: {{error}}",
+ "fieldQuote": "ะะพะปะต ะฆะธัะฐัะฐ (ะฝะฐะฟัะธะผะตั, \")",
+ "inputCsvFormat": "ะั
ะพะดะฝะพะน ัะพัะผะฐั CSV",
+ "inputTitle": "ะั
ะพะดะฝะพะน CSV-ัะฐะนะป",
+ "resultTitle": "ะัั
ะพะดะฝะพะน JSON",
+ "shortDescription": "ะะพะฝะฒะตััะธััะนัะต ะดะฐะฝะฝัะต CSV ะฒ ัะพัะผะฐั JSON.",
+ "skipEmptyLines": "ะัะพะฟััะบะฐัั ะฟััััะต ัััะพะบะธ",
+ "skipEmptyLinesDescription": "ะะณะฝะพัะธัะพะฒะฐัั ะฟััััะต ัััะพะบะธ ะฒะพ ะฒั
ะพะดะฝะพะผ CSV-ัะฐะนะปะต",
+ "title": "ะะพะฝะฒะตััะธัะพะฒะฐัั CSV ะฒ JSON",
+ "useHeaders": "ะัะฟะพะปัะทะพะฒะฐัั ะทะฐะณะพะปะพะฒะบะธ",
+ "useHeadersDescription": "ะัะฝะพัะธัััั ะบ ะฟะตัะฒะพะน ัััะพะบะต ะบะฐะบ ะบ ะทะฐะณะพะปะพะฒะบะฐะผ ััะพะปะฑัะพะฒ"
+ },
+ "csvToTsv": {
+ "description": "ะะฐะณััะทะธัะต CSV-ัะฐะนะป ะฒ ัะพัะผั ะฝะธะถะต, ะธ ะพะฝ ะฑัะดะตั ะฐะฒัะพะผะฐัะธัะตัะบะธ ะฟัะตะพะฑัะฐะทะพะฒะฐะฝ ะฒ TSV-ัะฐะนะป. ะ ะฝะฐัััะพะนะบะฐั
ะธะฝััััะผะตะฝัะฐ ะฒั ะผะพะถะตัะต ะฝะฐัััะพะธัั ัะพัะผะฐั ะฒั
ะพะดะฝะพะณะพ CSV-ัะฐะนะปะฐ: ัะบะฐะทะฐัั ัะฐะทะดะตะปะธัะตะปั ะฟะพะปะตะน, ัะธะผะฒะพะป ะบะฐะฒััะตะบ ะธ ัะธะผะฒะพะป ะบะพะผะผะตะฝัะฐัะธั, ะฐ ัะฐะบะถะต ะฒะบะปััะธัั ะฟัะพะฟััะบ ะฟััััั
ัััะพะบ CSV-ัะฐะนะปะฐ ะธ ะฒัะฑัะฐัั, ัะพั
ัะฐะฝััั ะปะธ ะทะฐะณะพะปะพะฒะบะธ ััะพะปะฑัะพะฒ CSV-ัะฐะนะปะฐ.",
+ "longDescription": "ะญัะพั ะธะฝััััะผะตะฝั ะฟัะตะพะฑัะฐะทัะตั ะดะฐะฝะฝัะต ะธะท ัะพัะผะฐัะฐ CSV (Comma Separated Values) ะฒ ะดะฐะฝะฝัะต ะธะท ัะพัะผะฐัะฐ TSV (Tab Separated Values). CSV ะธ TSV โ ะฟะพะฟัะปััะฝัะต ัะพัะผะฐัั ัะฐะนะปะพะฒ ะดะปั ั
ัะฐะฝะตะฝะธั ัะฐะฑะปะธัะฝัั
ะดะฐะฝะฝัั
, ะฝะพ ะฒ ะฝะธั
ะธัะฟะพะปัะทััััั ัะฐะทะฝัะต ัะฐะทะดะตะปะธัะตะปะธ ะดะปั ัะฐะทะดะตะปะตะฝะธั ะทะฝะฐัะตะฝะธะน: ะฒ CSV ะธัะฟะพะปัะทััััั ะทะฐะฟัััะต (",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั ะดะฐะฝะฝัะต CSV ะฒ ัะพัะผะฐั TSV.",
+ "title": "ะะพะฝะฒะตััะธัะพะฒะฐัั CSV ะฒ TSV"
+ },
+ "csvToXml": {
+ "description": "ะะพะฝะฒะตััะธััะนัะต CSV-ัะฐะนะปั ะฒ ัะพัะผะฐั XML ั ะฝะฐัััะฐะธะฒะฐะตะผัะผะธ ะฟะฐัะฐะผะตััะฐะผะธ.",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั ะดะฐะฝะฝัะต CSV ะฒ ัะพัะผะฐั XML.",
+ "title": "ะะพะฝะฒะตััะธัะพะฒะฐัั CSV ะฒ XML"
+ },
+ "csvToYaml": {
+ "description": "ะัะพััะพ ะทะฐะณััะทะธัะต CSV-ัะฐะนะป ะฒ ัะพัะผั ะฝะธะถะต, ะธ ะพะฝ ะฐะฒัะพะผะฐัะธัะตัะบะธ ะฑัะดะตั ะฟัะตะพะฑัะฐะทะพะฒะฐะฝ ะฒ YAML-ัะฐะนะป. ะ ะฝะฐัััะพะนะบะฐั
ะธะฝััััะผะตะฝัะฐ ะฒั ะผะพะถะตัะต ัะบะฐะทะฐัั ัะธะผะฒะพะป ัะฐะทะดะตะปะธัะตะปั ะฟะพะปะตะน, ัะธะผะฒะพะป ะบะฐะฒััะบะธ ะธ ัะธะผะฒะพะป ะบะพะผะผะตะฝัะฐัะธั, ััะพะฑั ะฐะดะฐะฟัะธัะพะฒะฐัั ะธะฝััััะผะตะฝั ะบ ะฟะพะปัะทะพะฒะฐัะตะปััะบะธะผ ัะพัะผะฐัะฐะผ CSV. ะัะพะผะต ัะพะณะพ, ะฒั ะผะพะถะตัะต ะฒัะฑัะฐัั ะฒัั
ะพะดะฝะพะน ัะพัะผะฐั YAML: ั ัะพั
ัะฐะฝะตะฝะธะตะผ ะทะฐะณะพะปะพะฒะบะพะฒ CSV ะธะปะธ ะฑะตะท ะฝะธั
.",
+ "longDescription": "ะญัะพั ะธะฝััััะผะตะฝั ะฟัะตะพะฑัะฐะทัะตั ะดะฐะฝะฝัะต CSV (ะทะฝะฐัะตะฝะธั, ัะฐะทะดะตะปะตะฝะฝัะต ะทะฐะฟัััะผะธ) ะฒ ะดะฐะฝะฝัะต YAML (ะตัะต ะพะดะธะฝ ัะทัะบ ัะฐะทะผะตัะบะธ). CSV โ ััะพ ะฟัะพััะพะน ัะฐะฑะปะธัะฝัะน ัะพัะผะฐั, ะธัะฟะพะปัะทัะตะผัะน ะดะปั ะฟัะตะดััะฐะฒะปะตะฝะธั ะผะฐััะธัะฝัั
ัะธะฟะพะฒ ะดะฐะฝะฝัั
, ัะพััะพััะธั
ะธะท ัััะพะบ ะธ ััะพะปะฑัะพะฒ. YAML, ั ะดััะณะพะน ััะพัะพะฝั, โ ะฑะพะปะตะต ะฟัะพะดะฒะธะฝัััะน ัะพัะผะฐั (ัะฐะบัะธัะตัะบะธ, ะฝะฐะดะผะฝะพะถะตััะฒะพ JSON), ะบะพัะพััะน ัะพะทะดะฐะตั ะฑะพะปะตะต ัะดะพะฑะพัะธัะฐะตะผัะต ะดะฐะฝะฝัะต ะดะปั ัะตัะธะฐะปะธะทะฐัะธะธ ะธ ะฟะพะดะดะตัะถะธะฒะฐะตั ัะฟะธัะบะธ, ัะปะพะฒะฐัะธ ะธ ะฒะปะพะถะตะฝะฝัะต ะพะฑัะตะบัั. ะญัะฐ ะฟัะพะณัะฐะผะผะฐ ะฟะพะดะดะตัะถะธะฒะฐะตั ัะฐะทะปะธัะฝัะต ัะพัะผะฐัั ะฒั
ะพะดะฝัั
CSV: ะฒั
ะพะดะฝัะต ะดะฐะฝะฝัะต ะผะพะณัั ะฑััั ัะฐะทะดะตะปะตะฝั ะทะฐะฟัััะผะธ (ะฟะพ ัะผะพะปัะฐะฝะธั), ัะพัะบะพะน ั ะทะฐะฟััะพะน, ะฒะตััะธะบะฐะปัะฝะพะน ัะตััะพะน ะธะปะธ ะธัะฟะพะปัะทะพะฒะฐัั ัะพะฒะตััะตะฝะฝะพ ะดััะณะพะน ัะฐะทะดะตะปะธัะตะปั. ะั ะผะพะถะตัะต ัะบะฐะทะฐัั ัะพัะฝัะน ัะฐะทะดะตะปะธัะตะปั, ะบะพัะพััะน ะฑัะดัั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะฐัะธ ะดะฐะฝะฝัะต, ะฒ ะฟะฐัะฐะผะตััะฐั
. ะะฝะฐะปะพะณะธัะฝะพ, ะฒ ะฟะฐัะฐะผะตััะฐั
ะฒั ะผะพะถะตัะต ัะบะฐะทะฐัั ัะธะผะฒะพะป ะบะฐะฒััะตะบ, ะบะพัะพััะน ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัััั ะดะปั ะฟะตัะตะฝะพัะฐ ะฟะพะปะตะน CSV (ะฟะพ ัะผะพะปัะฐะฝะธั ััะพ ัะธะผะฒะพะป ะดะฒะพะนะฝะพะน ะบะฐะฒััะบะธ). ะั ัะฐะบะถะต ะผะพะถะตัะต ะฟัะพะฟััะบะฐัั ัััะพะบะธ, ะฝะฐัะธะฝะฐััะธะตัั ั ะบะพะผะผะตะฝัะฐัะธะตะฒ, ัะบะฐะทะฐะฒ ัะธะผะฒะพะปั ะบะพะผะผะตะฝัะฐัะธะตะฒ ะฒ ะฟะฐัะฐะผะตััะฐั
. ะญัะพ ะฟะพะทะฒะพะปัะตั ะฟะพะดะดะตัะถะธะฒะฐัั ัะธััะพัั ะดะฐะฝะฝัั
, ะฟัะพะฟััะบะฐั ะฝะตะฝัะถะฝัะต ัััะพะบะธ. ะกััะตััะฒัะตั ะดะฒะฐ ัะฟะพัะพะฑะฐ ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธั CSV ะฒ YAML. ะะตัะฒัะน ะผะตัะพะด ะฟัะตะพะฑัะฐะทัะตั ะบะฐะถะดัั ัััะพะบั CSV ะฒ ัะฟะธัะพะบ YAML. ะัะพัะพะน ะผะตัะพะด ะธะทะฒะปะตะบะฐะตั ะทะฐะณะพะปะพะฒะบะธ ะธะท ะฟะตัะฒะพะน ัััะพะบะธ CSV ะธ ัะพะทะดะฐะตั ะพะฑัะตะบัั YAML ั ะบะปััะฐะผะธ ะฝะฐ ะพัะฝะพะฒะต ััะธั
ะทะฐะณะพะปะพะฒะบะพะฒ. ะั ัะฐะบะถะต ะผะพะถะตัะต ะฝะฐัััะพะธัั ะฒัั
ะพะดะฝะพะน ัะพัะผะฐั YAML, ัะบะฐะทะฐะฒ ะบะพะปะธัะตััะฒะพ ะฟัะพะฑะตะปะพะฒ ะดะปั ะพััััะฟะพะฒ ะฒ ััััะบัััะฐั
YAML. ะัะปะธ ะฒะฐะผ ะฝะตะพะฑั
ะพะดะธะผะพ ะฒัะฟะพะปะฝะธัั ะพะฑัะฐัะฝะพะต ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธะต, ัะพ ะตััั ะฟัะตะพะฑัะฐะทะพะฒะฐัั YAML ะฒ CSV, ะฒั ะผะพะถะตัะต ะฒะพัะฟะพะปัะทะพะฒะฐัััั ะฝะฐัะธะผ ะธะฝััััะผะตะฝัะพะผ ะดะปั ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธั YAML ะฒ CSV. Csv-abulous!",
+ "shortDescription": "ะััััะพ ะบะพะฝะฒะตััะธััะนัะต CSV-ัะฐะนะป ะฒ YAML-ัะฐะนะป.",
+ "title": "ะะพะฝะฒะตััะธัะพะฒะฐัั CSV ะฒ YAML"
+ },
+ "findIncompleteCsvRecords": {
+ "checkingOptions": "ะัะพะฒะตัะบะฐ ะฟะฐัะฐะผะตััะพะฒ",
+ "commentCharacterDescription": "ะะฒะตะดะธัะต ัะธะผะฒะพะป ะฝะฐัะฐะปะฐ ัััะพะบะธ ะบะพะผะผะตะฝัะฐัะธั. ะกััะพะบะธ, ะฝะฐัะธะฝะฐััะธะตัั ั ััะพะณะพ ัะธะผะฒะพะปะฐ, ะฑัะดัั ะฟัะพะฟััะตะฝั.",
+ "csvInputOptions": "ะะฐัะฐะผะตััั ะฒะฒะพะดะฐ CSV",
+ "csvSeparatorDescription": "ะะฒะตะดะธัะต ัะธะผะฒะพะป, ะธัะฟะพะปัะทัะตะผัะน ะดะปั ัะฐะทะดะตะปะตะฝะธั ััะพะปะฑัะพะฒ ะฒะพ ะฒั
ะพะดะฝะพะผ CSV-ัะฐะนะปะต.",
+ "deleteLinesWithNoData": "ะฃะดะฐะปะธัั ัััะพะบะธ ะฑะตะท ะดะฐะฝะฝัั
",
+ "deleteLinesWithNoDataDescription": "ะฃะดะฐะปะธัั ะฟััััะต ัััะพะบะธ ะธะท ะฒั
ะพะดะฝะพะณะพ CSV-ัะฐะนะปะฐ.",
+ "description": "ะัะพััะพ ะทะฐะณััะทะธัะต CSV-ัะฐะนะป ะฒ ัะพัะผั ะฝะธะถะต, ะธ ััะพั ะธะฝััััะผะตะฝั ะฐะฒัะพะผะฐัะธัะตัะบะธ ะฟัะพะฒะตัะธั ะฝะฐะปะธัะธะต ะฒัะตั
ะฟัะพะฟััะตะฝะฝัั
ะทะฝะฐัะตะฝะธะน ะฒ ัััะพะบะฐั
ะธ ััะพะปะฑัะฐั
. ะ ะฝะฐัััะพะนะบะฐั
ะธะฝััััะผะตะฝัะฐ ะผะพะถะฝะพ ะฝะฐัััะพะธัั ัะพัะผะฐั ะฒั
ะพะดะฝะพะณะพ ัะฐะนะปะฐ (ัะบะฐะทะฐัั ัะฐะทะดะตะปะธัะตะปั, ัะธะผะฒะพะป ะบะฐะฒััะบะธ ะธ ัะธะผะฒะพะป ะบะพะผะผะตะฝัะฐัะธั). ะัะพะผะต ัะพะณะพ, ะผะพะถะฝะพ ะฒะบะปััะธัั ะฟัะพะฒะตัะบั ะฝะฐ ะฝะฐะปะธัะธะต ะฟััััั
ะทะฝะฐัะตะฝะธะน, ะฟัะพะฟััะบะฐัั ะฟััััะต ัััะพะบะธ ะธ ัััะฐะฝะพะฒะธัั ะพะณัะฐะฝะธัะตะฝะธะต ะฝะฐ ะบะพะปะธัะตััะฒะพ ัะพะพะฑัะตะฝะธะน ะพะฑ ะพัะธะฑะบะฐั
ะฒ ะฒัั
ะพะดะฝัั
ะดะฐะฝะฝัั
.",
+ "findEmptyValues": "ะะฐะนัะธ ะฟััััะต ะทะฝะฐัะตะฝะธั",
+ "findEmptyValuesDescription": "ะัะฒะตััะธ ัะพะพะฑัะตะฝะธะต ะพ ะฟััััั
ะฟะพะปัั
CSV (ััะพ ะฝะต ะพััััััะฒัััะธะต ะฟะพะปั, ะฐ ะฟะพะปั, ะบะพัะพััะต ะฝะธัะตะณะพ ะฝะต ัะพะดะตัะถะฐั).",
+ "inputTitle": "ะั
ะพะดะฝะพะน CSV-ัะฐะนะป",
+ "limitNumberOfMessages": "ะะณัะฐะฝะธัะธัั ะบะพะปะธัะตััะฒะพ ัะพะพะฑัะตะฝะธะน",
+ "messageLimitDescription": "ะฃััะฐะฝะพะฒะธัะต ะพะณัะฐะฝะธัะตะฝะธะต ะฝะฐ ะบะพะปะธัะตััะฒะพ ัะพะพะฑัะตะฝะธะน ะฒ ะฒัะฒะพะดะต.",
+ "quoteCharacterDescription": "ะะฒะตะดะธัะต ัะธะผะฒะพะป ะบะฐะฒััะตะบ, ะธัะฟะพะปัะทัะตะผัะน ะดะปั ะทะฐะบะปััะตะฝะธั ะฒ ะบะฐะฒััะบะธ ะฟะพะปะตะน ะฒะฒะพะดะฐ CSV.",
+ "resultTitle": "ะกัะฐััั CSV",
+ "shortDescription": "ะััััะพ ะฝะฐั
ะพะดะธัะต ัััะพะบะธ ะธ ััะพะปะฑัั ะฒ CSV-ัะฐะนะปะต, ะฒ ะบะพัะพััั
ะพััััััะฒััั ะทะฝะฐัะตะฝะธั.",
+ "title": "ะะฐะนัะธ ะฝะตะฟะพะปะฝัะต ะทะฐะฟะธัะธ CSV",
+ "toolInfo": {
+ "title": "ะงัะพ ัะฐะบะพะต {{title}}?"
+ }
+ },
+ "insertCsvColumns": {
+ "appendColumns": "ะะพะฑะฐะฒะธัั ััะพะปะฑัั",
+ "commentCharacterDescription": "ะะฒะตะดะธัะต ัะธะผะฒะพะป ะฝะฐัะฐะปะฐ ัััะพะบะธ ะบะพะผะผะตะฝัะฐัะธั. ะกััะพะบะธ, ะฝะฐัะธะฝะฐััะธะตัั ั ััะพะณะพ ัะธะผะฒะพะปะฐ, ะฑัะดัั ะฟัะพะฟััะตะฝั.",
+ "csvOptions": "ะะฐัะฐะผะตััั CSV",
+ "csvSeparator": "CSV-ัะฐะทะดะตะปะธัะตะปั",
+ "csvToInsert": "CSV ะดะปั ะฒััะฐะฒะบะธ",
+ "csvToInsertDescription": "ะะฒะตะดะธัะต ะพะดะธะฝ ะธะปะธ ะฝะตัะบะพะปัะบะพ ััะพะปะฑัะพะฒ, ะบะพัะพััะต ะฒั ั
ะพัะธัะต ะฒััะฐะฒะธัั ะฒ CSV-ัะฐะนะป. ะกะธะผะฒะพะป, ะธัะฟะพะปัะทัะตะผัะน ะดะปั ัะฐะทะดะตะปะตะฝะธั ััะพะปะฑัะพะฒ, ะดะพะปะถะตะฝ ัะพะฒะฟะฐะดะฐัั ั ัะธะผะฒะพะปะพะผ ะฒะพ ะฒั
ะพะดะฝะพะผ CSV-ัะฐะนะปะต. P.S. ะััััะต ัััะพะบะธ ะฑัะดัั ะธะณะฝะพัะธัะพะฒะฐัััั.",
+ "customFillDescription": "ะัะปะธ ะฒั
ะพะดะฝะพะน CSV-ัะฐะนะป ะฝะตะฟะพะปะฝัะน (ะพััััััะฒััั ะทะฝะฐัะตะฝะธั), ัะพ ะผะพะถะฝะพ ะปะธ ะดะพะฑะฐะฒะธัั ะฟััััะต ะฟะพะปั ะธะปะธ ะฟะพะปัะทะพะฒะฐัะตะปััะบะธะต ัะธะผะฒะพะปั ะฒ ะทะฐะฟะธัะธ, ััะพะฑั ัะพะทะดะฐัั ะฟัะฐะฒะธะปัะฝะพ ััะพัะผะธัะพะฒะฐะฝะฝัะน CSV-ัะฐะนะป?",
+ "customFillValueDescription": "ะัะฟะพะปัะทัะนัะต ััะพ ะฟะพะปัะทะพะฒะฐัะตะปััะบะพะต ะทะฝะฐัะตะฝะธะต ะดะปั ะทะฐะฟะพะปะฝะตะฝะธั ะพััััััะฒัััะธั
ะฟะพะปะตะน. (ะ ะฐะฑะพัะฐะตั ัะพะปัะบะพ ั ัะตะถะธะผะพะผ ยซะะพะปัะทะพะฒะฐัะตะปััะบะธะต ะทะฝะฐัะตะฝะธัยป, ะพะฟะธัะฐะฝะฝัะผ ะฒััะต.)",
+ "customPosition": "ะะพะปัะทะพะฒะฐัะตะปััะบะฐั ะฟะพะทะธัะธั",
+ "customPositionOptionsDescription": "ะัะฑะตัะธัะต ัะฟะพัะพะฑ ะฒััะฐะฒะบะธ ััะพะปะฑัะพะฒ ะฒ CSV-ัะฐะนะป.",
+ "description": "ะะพะฑะฐะฒะธัั ะฝะพะฒัะต ััะพะปะฑัั ะฒ ะดะฐะฝะฝัะต CSV ะฒ ัะบะฐะทะฐะฝะฝัั
ะฟะพะทะธัะธัั
.",
+ "fillWithCustomValues": "ะะฐะฟะพะปะฝะธัั ัะฐะผะพะถะตะฝะฝัะต ะทะฝะฐัะตะฝะธั",
+ "fillWithEmptyValues": "ะะฐะฟะพะปะฝะธัั ะฟััััะผะธ ะทะฝะฐัะตะฝะธัะผะธ",
+ "headerName": "ะะผั ะทะฐะณะพะปะพะฒะบะฐ",
+ "headerNameDescription": "ะะฐะณะพะปะพะฒะพะบ ััะพะปะฑัะฐ, ะฟะพัะปะต ะบะพัะพัะพะณะพ ะฒั ั
ะพัะธัะต ะฒััะฐะฒะธัั ััะพะปะฑัั.",
+ "inputTitle": "ะั
ะพะดะฝะพะน CSV-ัะฐะนะป",
+ "insertingPositionDescription": "ะฃะบะฐะถะธัะต, ะบัะดะฐ ะฒััะฐะฒะปััั ััะพะปะฑัั ะฒ CSV-ัะฐะนะปะต.",
+ "position": "ะะพะทะธัะธั",
+ "positionOptions": "ะะฐัะธะฐะฝัั ะฟะพะทะธัะธะน",
+ "prependColumns": "ะะพะฑะฐะฒะธัั ััะพะปะฑัั",
+ "quoteCharDescription": "ะะฒะตะดะธัะต ัะธะผะฒะพะป ะบะฐะฒััะตะบ, ะธัะฟะพะปัะทัะตะผัะน ะดะปั ะทะฐะบะปััะตะฝะธั ะฒ ะบะฐะฒััะบะธ ะฟะพะปะตะน ะฒะฒะพะดะฐ CSV.",
+ "resultTitle": "ะัะฒะพะด CSV",
+ "rowNumberDescription": "ะะพะผะตั ััะพะปะฑัะฐ, ะฟะพัะปะต ะบะพัะพัะพะณะพ ะฒั ั
ะพัะธัะต ะฒััะฐะฒะธัั ััะพะปะฑัั.",
+ "separatorDescription": "ะะฒะตะดะธัะต ัะธะผะฒะพะป, ะธัะฟะพะปัะทัะตะผัะน ะดะปั ัะฐะทะดะตะปะตะฝะธั ััะพะปะฑัะพะฒ ะฒะพ ะฒั
ะพะดะฝะพะผ CSV-ัะฐะนะปะต.",
+ "shortDescription": "ะััััะพ ะฒััะฐะฒะปัะนัะต ะพะดะธะฝ ะธะปะธ ะฝะตัะบะพะปัะบะพ ะฝะพะฒัั
ััะพะปะฑัะพะฒ ะฒ ะปัะฑะพะต ะผะตััะพ CSV-ัะฐะนะปะฐ.",
+ "title": "ะััะฐะฒะธัั ััะพะปะฑัั CSV",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะดะพะฑะฐะฒะปััั ะฝะพะฒัะต ััะพะปะฑัั ะฒ CSV-ะดะฐะฝะฝัะต ะฒ ะทะฐะดะฐะฝะฝัั
ะฟะพะทะธัะธัั
. ะั ะผะพะถะตัะต ะดะพะฑะฐะฒะปััั ััะพะปะฑัั ะฒ ะฝะฐัะฐะปะพ, ะบะพะฝะตั ะธะปะธ ะฒััะฐะฒะปััั ะธั
ะฒ ะฟัะพะธะทะฒะพะปัะฝัะต ะฟะพะทะธัะธะธ, ะธัะฟะพะปัะทัั ะฝะฐะทะฒะฐะฝะธั ะทะฐะณะพะปะพะฒะบะพะฒ ะธะปะธ ะฝะพะผะตัะฐ ััะพะปะฑัะพะฒ.",
+ "title": "ะััะฐะฒะธัั ััะพะปะฑัั CSV"
+ }
+ },
+ "swapCsvColumns": {
+ "description": "ะัะพััะพ ะทะฐะณััะทะธัะต CSV-ัะฐะนะป ะฒ ัะพัะผั ะฝะธะถะต, ัะบะฐะถะธัะต ััะพะปะฑัั ะดะปั ะทะฐะผะตะฝั, ะธ ะธะฝััััะผะตะฝั ะฐะฒัะพะผะฐัะธัะตัะบะธ ะธะทะผะตะฝะธั ะฟะพะปะพะถะตะฝะธะต ัะบะฐะทะฐะฝะฝัั
ััะพะปะฑัะพะฒ ะฒ ะฒัั
ะพะดะฝะพะผ ัะฐะนะปะต. ะ ะฝะฐัััะพะนะบะฐั
ะธะฝััััะผะตะฝัะฐ ะฒั ะผะพะถะตัะต ัะบะฐะทะฐัั ะฟะพะปะพะถะตะฝะธะต ะธะปะธ ะฝะฐะทะฒะฐะฝะธั ััะพะปะฑัะพะฒ, ะบะพัะพััะต ั
ะพัะธัะต ะทะฐะผะตะฝะธัั, ะฐ ัะฐะบะถะต ะธัะฟัะฐะฒะธัั ะฝะตะฟะพะปะฝัะต ะดะฐะฝะฝัะต ะธ ะฟัะธ ะฝะตะพะฑั
ะพะดะธะผะพััะธ ัะดะฐะปะธัั ะฟััััะต ะธ ะทะฐะบะพะผะผะตะฝัะธัะพะฒะฐะฝะฝัะต ะทะฐะฟะธัะธ.",
+ "longDescription": "ะญัะพั ะธะฝััััะผะตะฝั ัะตะพัะณะฐะฝะธะทัะตั ะดะฐะฝะฝัะต CSV, ะผะตะฝัั ะผะตััะฐะผะธ ััะพะปะฑัั. ะะตัะตััะฐะฝะพะฒะบะฐ ััะพะปะฑัะพะฒ ะผะพะถะตั ัะปัััะธัั ัะธัะฐะตะผะพััั CSV-ัะฐะนะปะฐ, ัะฐะทะผะตัะฐั ัะฐััะพ ะธัะฟะพะปัะทัะตะผัะต ะดะฐะฝะฝัะต ะฒะผะตััะต ะธะปะธ ะฒ ะฝะฐัะฐะปะต ะดะปั ะฑะพะปะตะต ัะดะพะฑะฝะพะณะพ ััะฐะฒะฝะตะฝะธั ะธ ัะตะดะฐะบัะธัะพะฒะฐะฝะธั. ะะฐะฟัะธะผะตั, ะผะพะถะฝะพ ะฟะพะผะตะฝััั ะผะตััะฐะผะธ ะฟะตัะฒัะน ััะพะปะฑะตั ั ะฟะพัะปะตะดะฝะธะผ ะธะปะธ ะฒัะพัะพะน ััะพะปะฑะตั ั ััะตััะธะผ. ะงัะพะฑั ะฟะพะผะตะฝััั ะผะตััะฐะผะธ ััะพะปะฑัั, ะฒัะฑะตัะธัะต",
+ "shortDescription": "ะะทะผะตะฝะธัั ะฟะพััะดะพะบ ััะพะปะฑัะพะฒ CSV.",
+ "title": "ะะพะผะตะฝััั ะผะตััะฐะผะธ ััะพะปะฑัั CSV"
+ },
+ "transposeCsv": {
+ "description": "ะัะพััะพ ะทะฐะณััะทะธัะต ัะฒะพะน CSV-ัะฐะนะป ะฒ ัะพัะผั ะฝะธะถะต, ะธ ััะพั ะธะฝััััะผะตะฝั ะฐะฒัะพะผะฐัะธัะตัะบะธ ััะฐะฝัะฟะพะฝะธััะตั ะตะณะพ. ะ ะฝะฐัััะพะนะบะฐั
ะธะฝััััะผะตะฝัะฐ ะฒั ะผะพะถะตัะต ัะบะฐะทะฐัั ัะธะผะฒะพะป, ั ะบะพัะพัะพะณะพ ะฝะฐัะธะฝะฐัััั ัััะพะบะธ ะบะพะผะผะตะฝัะฐัะธะตะฒ ะฒ CSV-ัะฐะนะปะต, ััะพะฑั ัะดะฐะปะธัั ะธั
. ะัะพะผะต ัะพะณะพ, ะตัะปะธ CSV-ัะฐะนะป ะฝะตะฟะพะปะฝัะน (ัะพะดะตัะถะฐั ะฟัะพะฟััะตะฝะฝัะต ะทะฝะฐัะตะฝะธั), ะฒั ะผะพะถะตัะต ะทะฐะผะตะฝะธัั ะฟัะพะฟััะตะฝะฝัะต ะทะฝะฐัะตะฝะธั ะฟััััะผ ัะธะผะฒะพะปะพะผ ะธะปะธ ะฟะพะปัะทะพะฒะฐัะตะปััะบะธะผ ัะธะผะฒะพะปะพะผ.",
+ "longDescription": "ะญัะพั ะธะฝััััะผะตะฝั ััะฐะฝัะฟะพะฝะธััะตั ะดะฐะฝะฝัะต, ัะฐะทะดะตะปะตะฝะฝัะต ะทะฐะฟัััะผะธ (CSV). ะะฝ ะพะฑัะฐะฑะฐััะฒะฐะตั CSV ะบะฐะบ ะผะฐััะธัั ะดะฐะฝะฝัั
ะธ ะฟะตัะตะฒะพัะฐัะธะฒะฐะตั ะฒัะต ัะปะตะผะตะฝัั ะฟะพ ะณะปะฐะฒะฝะพะน ะดะธะฐะณะพะฝะฐะปะธ. ะัั
ะพะดะฝัะต ะดะฐะฝะฝัะต ัะพะดะตัะถะฐั ัะต ะถะต ะดะฐะฝะฝัะต CSV, ััะพ ะธ ะฒั
ะพะดะฝัะต, ะฝะพ ัะตะฟะตัั ะฒัะต ัััะพะบะธ ััะฐะปะธ ััะพะปะฑัะฐะผะธ, ะฐ ะฒัะต ััะพะปะฑัั โ ัััะพะบะฐะผะธ. ะะพัะปะต ััะฐะฝัะฟะพะฝะธัะพะฒะฐะฝะธั CSV-ัะฐะนะป ะฑัะดะตั ะธะผะตัั ะฟัะพัะธะฒะพะฟะพะปะพะถะฝัะต ัะฐะทะผะตัั. ะะฐะฟัะธะผะตั, ะตัะปะธ ะฒั
ะพะดะฝะพะน ัะฐะนะป ัะพะดะตัะถะธั 4 ััะพะปะฑัะฐ ะธ 3 ัััะพะบะธ, ะฒัั
ะพะดะฝะพะน ัะฐะนะป ะฑัะดะตั ัะพะดะตัะถะฐัั 3 ััะพะปะฑัะฐ ะธ 4 ัััะพะบะธ. ะะพ ะฒัะตะผั ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธั ะฟัะพะณัะฐะผะผะฐ ัะฐะบะถะต ะพัะธัะฐะตั ะดะฐะฝะฝัะต ะพั ะฝะตะฝัะถะฝัั
ัััะพะบ ะธ ะธัะฟัะฐะฒะปัะตั ะฝะตะฟะพะปะฝัะต ะดะฐะฝะฝัะต. ะ ัะฐััะฝะพััะธ, ะธะฝััััะผะตะฝั ะฐะฒัะพะผะฐัะธัะตัะบะธ ัะดะฐะปัะตั ะฒัะต ะฟััััะต ะทะฐะฟะธัะธ ะธ ะบะพะผะผะตะฝัะฐัะธะธ, ะฝะฐัะธะฝะฐััะธะตัั ั ะพะฟัะตะดะตะปะตะฝะฝะพะณะพ ัะธะผะฒะพะปะฐ, ะบะพัะพััะน ะผะพะถะฝะพ ะทะฐะดะฐัั ะฒ ะฝะฐัััะพะนะบะฐั
. ะัะพะผะต ัะพะณะพ, ะฒ ัะปััะฐะต ะฟะพะฒัะตะถะดะตะฝะธั ะธะปะธ ะฟะพัะตัะธ ะดะฐะฝะฝัั
CSV-ัะฐะนะปะฐ ััะธะปะธัะฐ ะดะพะฟะพะปะฝัะตั ัะฐะนะป ะฟััััะผะธ ะฟะพะปัะผะธ ะธะปะธ ะฟะพะปัะทะพะฒะฐัะตะปััะบะธะผะธ ะฟะพะปัะผะธ, ะบะพัะพััะต ะผะพะถะฝะพ ัะบะฐะทะฐัั ะฒ ะฝะฐัััะพะนะบะฐั
. CSV-abulous!",
+ "shortDescription": "ะััััะพ ััะฐะฝัะฟะพะฝะธััะนัะต CSV-ัะฐะนะป.",
+ "title": "ะขัะฐะฝัะฟะพะฝะธัะพะฒะฐัั CSV"
+ }
+}
diff --git a/public/locales/ru/image.json b/public/locales/ru/image.json
new file mode 100644
index 0000000..5726b00
--- /dev/null
+++ b/public/locales/ru/image.json
@@ -0,0 +1,98 @@
+{
+ "changeColors": {
+ "description": "ะะธั",
+ "shortDescription": "ะััััะพ ะฟะพะผะตะฝัะนัะต ัะฒะตัะฐ ะฝะฐ ะธะทะพะฑัะฐะถะตะฝะธะธ",
+ "title": "ะะทะผะตะฝะธัั ัะฒะตัะฐ ะฝะฐ ะธะทะพะฑัะฐะถะตะฝะธะธ"
+ },
+ "changeOpacity": {
+ "description": "ะะตะณะบะพ ะฝะฐัััะฐะธะฒะฐะนัะต ะฟัะพะทัะฐัะฝะพััั ะธะทะพะฑัะฐะถะตะฝะธะน. ะัะพััะพ ะทะฐะณััะทะธัะต ะธะทะพะฑัะฐะถะตะฝะธะต, ัััะฐะฝะพะฒะธัะต ะถะตะปะฐะตะผัะน ััะพะฒะตะฝั ะฝะตะฟัะพะทัะฐัะฝะพััะธ ั ะฟะพะผะพััั ะฟะพะปะทัะฝะบะฐ ะพั 0 (ะฟะพะปะฝะพัััั ะฟัะพะทัะฐัะฝะพ) ะดะพ 1 (ะฟะพะปะฝะพัััั ะฝะตะฟัะพะทัะฐัะฝะพ) ะธ ัะบะฐัะฐะนัะต ะธะทะผะตะฝัะฝะฝะพะต ะธะทะพะฑัะฐะถะตะฝะธะต.",
+ "shortDescription": "ะััะตะณัะปะธััะนัะต ะฟัะพะทัะฐัะฝะพััั ะธะทะพะฑัะฐะถะตะฝะธะน",
+ "title": "ะะทะผะตะฝะธัั ะฝะตะฟัะพะทัะฐัะฝะพััั ะธะทะพะฑัะฐะถะตะฝะธั"
+ },
+ "compress": {
+ "description": "ะฃะผะตะฝััะธัะต ัะฐะทะผะตั ัะฐะนะปะฐ ะธะทะพะฑัะฐะถะตะฝะธั, ัะพั
ัะฐะฝะธะฒ ะบะฐัะตััะฒะพ.",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะธะทะพะฑัะฐะถะตะฝะธะต",
+ "resultTitle": "ะกะถะฐัะพะต ะธะทะพะฑัะฐะถะตะฝะธะต",
+ "shortDescription": "ะกะถะธะผะฐะนัะต ะธะทะพะฑัะฐะถะตะฝะธั, ััะพะฑั ัะผะตะฝััะธัั ัะฐะทะผะตั ัะฐะนะปะฐ, ัะพั
ัะฐะฝัั ะฟัะธ ััะพะผ ะฟัะธะตะผะปะตะผะพะต ะบะฐัะตััะฒะพ.",
+ "title": "ะกะถะฐัั ะธะทะพะฑัะฐะถะตะฝะธะต"
+ },
+ "compressPng": {
+ "description": "ะญัะพ ะฟัะพะณัะฐะผะผะฐ ะดะปั ัะถะฐัะธั ะธะทะพะฑัะฐะถะตะฝะธะน ะฒ ัะพัะผะฐัะต PNG. ะะพัะปะต ัะพะณะพ, ะบะฐะบ ะฒั ะฒััะฐะฒะธัะต ะธะทะพะฑัะฐะถะตะฝะธะต ะฒ ะฟะพะปะต ะฒะฒะพะดะฐ, ะฟัะพะณัะฐะผะผะฐ ัะพะถะผัั ะตะณะพ ะธ ะพัะพะฑัะฐะทะธั ัะตะทัะปััะฐั ะฒ ะฟะพะปะต ะฒัะฒะพะดะฐ. ะ ะฝะฐัััะพะนะบะฐั
ะผะพะถะฝะพ ะฝะฐัััะพะธัั ััะตะฟะตะฝั ัะถะฐัะธั, ะฐ ัะฐะบะถะต ะฟะพัะผะพััะตัั ััะฐััะน ะธ ะฝะพะฒัะน ัะฐะทะผะตัั ัะฐะนะปะฐ ะธะทะพะฑัะฐะถะตะฝะธั.",
+ "shortDescription": "ะััััะพ ัะถะฐัั PNG",
+ "title": "ะกะถะฐัั png"
+ },
+ "convertJgpToPng": {
+ "description": "ะััััะพ ะบะพะฝะฒะตััะธััะนัะต ะธะทะพะฑัะฐะถะตะฝะธั JPG ะฒ PNG. ะัะพััะพ ะธะผะฟะพััะธััะนัะต ะธะทะพะฑัะฐะถะตะฝะธะต PNG ะฒ ัะตะดะฐะบัะพั ัะปะตะฒะฐ.",
+ "shortDescription": "ะััััะพ ะบะพะฝะฒะตััะธััะนัะต ะธะทะพะฑัะฐะถะตะฝะธั JPG ะฒ PNG",
+ "title": "ะะพะฝะฒะตััะธัะพะฒะฐัั JPG ะฒ PNG"
+ },
+ "convertToJpg": {
+ "description": "ะะพะฝะฒะตััะธััะนัะต ัะฐะทะปะธัะฝัะต ัะพัะผะฐัั ะธะทะพะฑัะฐะถะตะฝะธะน (PNG, GIF, TIF, PSD, SVG, WEBP, HEIC, RAW) ะฒ JPG ั ะฝะฐัััะฐะธะฒะฐะตะผัะผะธ ะฟะฐัะฐะผะตััะฐะผะธ ะบะฐัะตััะฒะฐ ะธ ัะฒะตัะฐ ัะพะฝะฐ.",
+ "shortDescription": "ะะพะฝะฒะตััะธััะนัะต ะธะทะพะฑัะฐะถะตะฝะธั ะฒ JPG ั ะบะพะฝััะพะปะตะผ ะบะฐัะตััะฒะฐ",
+ "title": "ะะพะฝะฒะตััะธัะพะฒะฐัั ะธะทะพะฑัะฐะถะตะฝะธั ะฒ JPG"
+ },
+ "createTransparent": {
+ "description": "ะะธั",
+ "shortDescription": "ะััััะพ ัะดะตะปะฐัั ะธะทะพะฑัะฐะถะตะฝะธะต ะฟัะพะทัะฐัะฝัะผ",
+ "title": "ะกะพะทะดะฐัั ะฟัะพะทัะฐัะฝัะน PNG"
+ },
+ "crop": {
+ "description": "ะะฑัะตะทะฐะนัะต ะธะทะพะฑัะฐะถะตะฝะธั, ััะพะฑั ัะดะฐะปะธัั ะฝะตะถะตะปะฐัะตะปัะฝัะต ะพะฑะปะฐััะธ.",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะธะทะพะฑัะฐะถะตะฝะธะต",
+ "resultTitle": "ะะฑัะตะทะฐะฝะฝะพะต ะธะทะพะฑัะฐะถะตะฝะธะต",
+ "shortDescription": "ะััััะพ ะพะฑัะตะทะฐะนัะต ะธะทะพะฑัะฐะถะตะฝะธั.",
+ "title": "ะะฑัะตะทะฐัั ะธะทะพะฑัะฐะถะตะฝะธะต"
+ },
+ "editor": {
+ "description": "ะ ะฐััะธัะตะฝะฝัะน ัะตะดะฐะบัะพั ะธะทะพะฑัะฐะถะตะฝะธะน ั ะธะฝััััะผะตะฝัะฐะผะธ ะดะปั ะพะฑัะตะทะบะธ, ะฟะพะฒะพัะพัะฐ, ะฐะฝะฝะพัะธัะพะฒะฐะฝะธั, ะฝะฐัััะพะนะบะธ ัะฒะตัะพะฒ ะธ ะดะพะฑะฐะฒะปะตะฝะธั ะฒะพะดัะฝัั
ะทะฝะฐะบะพะฒ. ะ ะตะดะฐะบัะธััะนัะต ะธะทะพะฑัะฐะถะตะฝะธั ั ะฟะพะผะพััั ะฟัะพัะตััะธะพะฝะฐะปัะฝัั
ะธะฝััััะผะตะฝัะพะฒ ะฟััะผะพ ะฒ ะฑัะฐัะทะตัะต.",
+ "shortDescription": "ะ ะตะดะฐะบัะธััะนัะต ะธะทะพะฑัะฐะถะตะฝะธั ั ะฟะพะผะพััั ัะฐััะธัะตะฝะฝัั
ะธะฝััััะผะตะฝัะพะฒ ะธ ััะฝะบัะธะน",
+ "title": "ะ ะตะดะฐะบัะพั ะธะทะพะฑัะฐะถะตะฝะธะน"
+ },
+ "imageToText": {
+ "description": "ะะทะฒะปะตะบะฐะนัะต ัะตะบัั ะธะท ะธะทะพะฑัะฐะถะตะฝะธะน (JPG, PNG) ั ะฟะพะผะพััั ะพะฟัะธัะตัะบะพะณะพ ัะฐัะฟะพะทะฝะฐะฒะฐะฝะธั ัะธะผะฒะพะปะพะฒ (OCR).",
+ "shortDescription": "ะะทะฒะปะตะบะฐะนัะต ัะตะบัั ะธะท ะธะทะพะฑัะฐะถะตะฝะธะน ั ะฟะพะผะพััั OCR.",
+ "title": "ะะทะพะฑัะฐะถะตะฝะธะต ะฒ ัะตะบัั (OCR)"
+ },
+ "qrCode": {
+ "description": "ะกะพะทะดะฐะฒะฐะนัะต QR-ะบะพะดั ะดะปั ัะฐะทะปะธัะฝัั
ัะธะฟะพะฒ ะดะฐะฝะฝัั
: URL, ัะตะบัั, ัะปะตะบััะพะฝะฝะฐั ะฟะพััะฐ, ัะตะปะตัะพะฝ, SMS, Wi-Fi, vCard ะธ ั. ะด.",
+ "shortDescription": "ะกะพะทะดะฐะฒะฐะนัะต ะธะฝะดะธะฒะธะดัะฐะปัะฝัะต QR-ะบะพะดั ะดะปั ัะฐะทะปะธัะฝัั
ัะพัะผะฐัะพะฒ ะดะฐะฝะฝัั
.",
+ "title": "ะะตะฝะตัะฐัะพั QR-ะบะพะดะฐ"
+ },
+ "removeBackground": {
+ "description": "ะะธั",
+ "shortDescription": "ะะฒัะพะผะฐัะธัะตัะบะธ ัะดะฐะปััั ัะพะฝั ั ะธะทะพะฑัะฐะถะตะฝะธะน",
+ "title": "ะฃะดะฐะปะธัั ัะพะฝ ะธะท ะธะทะพะฑัะฐะถะตะฝะธั"
+ },
+ "resize": {
+ "description": "ะะทะผะตะฝัะนัะต ัะฐะทะผะตัั ะธะทะพะฑัะฐะถะตะฝะธะน ะดะพ ัะฐะทะฝัั
ัะฐะทะผะตัะพะฒ.",
+ "dimensionType": "ะขะธะฟ ะธะทะผะตัะตะฝะธั",
+ "heightDescription": "ะััะพัะฐ (ะฒ ะฟะธะบัะตะปัั
)",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะธะทะพะฑัะฐะถะตะฝะธะต",
+ "maintainAspectRatio": "ะกะพั
ัะฐะฝััั ัะพะพัะฝะพัะตะฝะธะต ััะพัะพะฝ",
+ "maintainAspectRatioDescription": "ะกะพั
ัะฐะฝะธัะต ะธัั
ะพะดะฝะพะต ัะพะพัะฝะพัะตะฝะธะต ััะพัะพะฝ ะธะทะพะฑัะฐะถะตะฝะธั.",
+ "percentage": "ะัะพัะตะฝั",
+ "percentageDescription": "ะัะพัะตะฝั ะพั ะธัั
ะพะดะฝะพะณะพ ัะฐะทะผะตัะฐ (ะฝะฐะฟัะธะผะตั, 50 ะดะปั ะฟะพะปะพะฒะธะฝะฝะพะณะพ ัะฐะทะผะตัะฐ, 200 ะดะปั ะดะฒะพะนะฝะพะณะพ ัะฐะทะผะตัะฐ)",
+ "resizeByPercentage": "ะะทะผะตะฝะธัั ัะฐะทะผะตั ะฒ ะฟัะพัะตะฝัะฐั
",
+ "resizeByPercentageDescription": "ะะทะผะตะฝะธัะต ัะฐะทะผะตั, ัะบะฐะทะฐะฒ ะฟัะพัะตะฝั ะพั ะธัั
ะพะดะฝะพะณะพ ัะฐะทะผะตัะฐ.",
+ "resizeByPixels": "ะะทะผะตะฝะธัั ัะฐะทะผะตั ะฟะพ ะฟะธะบัะตะปัะผ",
+ "resizeByPixelsDescription": "ะะทะผะตะฝะธัะต ัะฐะทะผะตั, ัะบะฐะทะฐะฒ ัะฐะทะผะตัั ะฒ ะฟะธะบัะตะปัั
.",
+ "resizeMethod": "ะะตัะพะด ะธะทะผะตะฝะตะฝะธั ัะฐะทะผะตัะฐ",
+ "resultTitle": "ะะทะผะตะฝะตะฝะฝะพะต ะธะทะพะฑัะฐะถะตะฝะธะต",
+ "setHeight": "ะฃััะฐะฝะพะฒะธัั ะฒััะพัั",
+ "setHeightDescription": "ะฃะบะฐะถะธัะต ะฒััะพัั ะฒ ะฟะธะบัะตะปัั
ะธ ัะฐัััะธัะฐะนัะต ัะธัะธะฝั ะฝะฐ ะพัะฝะพะฒะต ัะพะพัะฝะพัะตะฝะธั ััะพัะพะฝ.",
+ "setWidth": "ะฃััะฐะฝะพะฒะธัั ัะธัะธะฝั",
+ "setWidthDescription": "ะฃะบะฐะถะธัะต ัะธัะธะฝั ะฒ ะฟะธะบัะตะปัั
ะธ ัะฐัััะธัะฐะนัะต ะฒััะพัั ะฝะฐ ะพัะฝะพะฒะต ัะพะพัะฝะพัะตะฝะธั ััะพัะพะฝ.",
+ "shortDescription": "ะะตะณะบะพ ะธะทะผะตะฝัะนัะต ัะฐะทะผะตั ะธะทะพะฑัะฐะถะตะฝะธะน.",
+ "title": "ะะทะผะตะฝะธัั ัะฐะทะผะตั ะธะทะพะฑัะฐะถะตะฝะธั",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะธะทะผะตะฝััั ัะฐะทะผะตั ะธะทะพะฑัะฐะถะตะฝะธะน JPG, PNG, SVG ะธะปะธ GIF. ะ ะฐะทะผะตั ะผะพะถะฝะพ ะธะทะผะตะฝััั, ัะบะฐะทัะฒะฐั ะทะฝะฐัะตะฝะธั ะฒ ะฟะธะบัะตะปัั
ะธะปะธ ะฟัะพัะตะฝัะฐั
, ั ะฒะพะทะผะพะถะฝะพัััั ัะพั
ัะฐะฝะตะฝะธั ะธัั
ะพะดะฝะพะณะพ ัะพะพัะฝะพัะตะฝะธั ััะพัะพะฝ.",
+ "title": "ะะทะผะตะฝะธัั ัะฐะทะผะตั ะธะทะพะฑัะฐะถะตะฝะธั"
+ },
+ "widthDescription": "ะจะธัะธะฝะฐ (ะฒ ะฟะธะบัะตะปัั
)"
+ },
+ "rotate": {
+ "description": "ะะพะฒะตัะฝััั ะธะทะพะฑัะฐะถะตะฝะธะต ะฝะฐ ัะบะฐะทะฐะฝะฝัะน ัะณะพะป.",
+ "shortDescription": "ะะตะณะบะพ ะฟะพะฒะพัะฐัะธะฒะฐะนัะต ะธะทะพะฑัะฐะถะตะฝะธะต.",
+ "title": "ะะพะฒะตัะฝััั ะธะทะพะฑัะฐะถะตะฝะธะต"
+ }
+}
diff --git a/public/locales/ru/json.json b/public/locales/ru/json.json
new file mode 100644
index 0000000..b6bc6c2
--- /dev/null
+++ b/public/locales/ru/json.json
@@ -0,0 +1,62 @@
+{
+ "escapeJson": {
+ "description": "ะญะบัะฐะฝะธััะนัะต ัะฟะตัะธะฐะปัะฝัะต ัะธะผะฒะพะปั ะฒ ัััะพะบะฐั
JSON. ะัะตะพะฑัะฐะทัะนัะต ะดะฐะฝะฝัะต JSON ะฒ ะบะพััะตะบัะฝะพ ัะบัะฐะฝะธัะพะฒะฐะฝะฝัะน ัะพัะผะฐั ะดะปั ะฑะตะทะพะฟะฐัะฝะพะน ะฟะตัะตะดะฐัะธ ะธ ั
ัะฐะฝะตะฝะธั.",
+ "shortDescription": "ะญะบัะฐะฝะธัะพะฒะฐะฝะธะต ัะฟะตัะธะฐะปัะฝัั
ัะธะผะฒะพะปะพะฒ ะฒ JSON",
+ "title": "Escape JSON"
+ },
+ "jsonToXml": {
+ "description": "ะัะตะพะฑัะฐะทัะนัะต ะดะฐะฝะฝัะต JSON ะฒ ัะพัะผะฐั XML. ะัะตะพะฑัะฐะทัะนัะต ััััะบัััะธัะพะฒะฐะฝะฝัะต ะพะฑัะตะบัั JSON ะฒ ะบะพััะตะบัะฝัะต XML-ะดะพะบัะผะตะฝัั.",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั ัะพัะผะฐั JSON ะฒ XML",
+ "title": "JSON ะฒ XML"
+ },
+ "minify": {
+ "description": "ะฃะดะฐะปะธัะต ะฒัะต ะฝะตะฝัะถะฝัะต ะฟัะพะฑะตะปั ะธะท JSON.",
+ "inputTitle": "ะั
ะพะดะฝะพะน JSON",
+ "resultTitle": "ะะธะฝะธะผะธะทะธัะพะฒะฐะฝะฝัะน JSON",
+ "shortDescription": "ะะธะฝะธะผะธะทะธััะนัะต JSON, ัะดะฐะปะธะฒ ะฟัะพะฑะตะปั",
+ "title": "ะะธะฝะธัะธัะธัะพะฒะฐัั JSON",
+ "toolInfo": {
+ "description": "ะะธะฝะธัะธะบะฐัะธั JSON โ ััะพ ะฟัะพัะตัั ัะดะฐะปะตะฝะธั ะฒัะตั
ะฝะตะฝัะถะฝัั
ะฟัะพะฑะตะปะพะฒ ะธะท JSON-ะดะฐะฝะฝัั
ั ัะพั
ัะฐะฝะตะฝะธะตะผ ะธั
ะบะพััะตะบัะฝะพััะธ. ะญัะพ ะฒะบะปััะฐะตั ะฒ ัะตะฑั ัะดะฐะปะตะฝะธะต ะฟัะพะฑะตะปะพะฒ, ะฟะตัะตะฝะพัะพะฒ ัััะพะบ ะธ ะพััััะฟะพะฒ, ะบะพัะพััะต ะฝะต ััะตะฑััััั ะดะปั ะบะพััะตะบัะฝะพะณะพ ะฐะฝะฐะปะธะทะฐ JSON-ะดะฐะฝะฝัั
. ะะธะฝะธัะธะบะฐัะธั ัะผะตะฝััะฐะตั ัะฐะทะผะตั JSON-ะดะฐะฝะฝัั
, ะดะตะปะฐั ะธั
ะฑะพะปะตะต ัััะตะบัะธะฒะฝัะผะธ ะดะปั ั
ัะฐะฝะตะฝะธั ะธ ะฟะตัะตะดะฐัะธ, ัะพั
ัะฐะฝัั ะฟัะธ ััะพะผ ะฟัะตะถะฝัั ััััะบัััั ะดะฐะฝะฝัั
ะธ ะทะฝะฐัะตะฝะธั.",
+ "title": "ะงัะพ ัะฐะบะพะต ะผะธะฝะธัะธะบะฐัะธั JSON?"
+ }
+ },
+ "prettify": {
+ "description": "ะััะพัะผะฐัะธััะนัะต JSON ั ะฟัะฐะฒะธะปัะฝัะผะธ ะพััััะฟะฐะผะธ ะธ ะฟัะพะฑะตะปะฐะผะธ.",
+ "indentation": "ะััััะฟ",
+ "inputTitle": "ะั
ะพะดะฝะพะน JSON",
+ "resultTitle": "ะฃะฟัะพัะตะฝะฝัะน JSON",
+ "shortDescription": "ะคะพัะผะฐัะธััะนัะต ะธ ัะบัะฐัะฐะนัะต JSON-ะบะพะด",
+ "title": "ะฃะฟัะพัะตะฝะธะต JSON",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ัะพัะผะฐัะธัะพะฒะฐัั ะดะฐะฝะฝัะต JSON ั ะฟัะฐะฒะธะปัะฝัะผะธ ะพััััะฟะฐะผะธ ะธ ะธะฝัะตัะฒะฐะปะฐะผะธ, ััะพ ะดะตะปะฐะตั ะธั
ะฑะพะปะตะต ัะธัะฐะฑะตะปัะฝัะผะธ ะธ ัะดะพะฑะฝัะผะธ ะดะปั ัะฐะฑะพัั.",
+ "title": "ะฃะฟัะพัะตะฝะธะต JSON"
+ },
+ "useSpaces": "ะัะฟะพะปัะทัะนัะต ะฟัะพะฑะตะปั",
+ "useSpacesDescription": "ะััััะฟ ะฒัะฒะพะดะฐ ั ะฟัะพะฑะตะปะฐะผะธ",
+ "useTabs": "ะัะฟะพะปัะทะพะฒะฐัั ะฒะบะปะฐะดะบะธ",
+ "useTabsDescription": "ะััััะฟ ะฒัะฒะพะดะฐ ั ะฟะพะผะพััั ัะฐะฑัะปััะธะธ."
+ },
+ "stringify": {
+ "description": "ะัะตะพะฑัะฐะทัะนัะต ะพะฑัะตะบัั JavaScript ะฒ ัััะพะบะธ ัะพัะผะฐัะฐ JSON. ะกะตัะธะฐะปะธะทัะนัะต ััััะบัััั ะดะฐะฝะฝัั
ะฒ ัััะพะบะธ JSON ะดะปั ั
ัะฐะฝะตะฝะธั ะธะปะธ ะฟะตัะตะดะฐัะธ.",
+ "shortDescription": "ะัะตะพะฑัะฐะทะพะฒะฐะฝะธะต ะพะฑัะตะบัะพะฒ ะฒ ัััะพะบั JSON",
+ "title": "ะกััะพะบะธัะธะบะฐัะธั JSON"
+ },
+ "tsvToJson": {
+ "description": "ะัะตะพะฑัะฐะทัะนัะต ะดะฐะฝะฝัะต TSV (ะทะฝะฐัะตะฝะธั, ัะฐะทะดะตะปะตะฝะฝัะต ัะฐะฑัะปััะธะตะน) ะฒ ัะพัะผะฐั JSON. ะัะตะพะฑัะฐะทัะนัะต ัะฐะฑะปะธัะฝัะต ะดะฐะฝะฝัะต ะฒ ััััะบัััะธัะพะฒะฐะฝะฝัะต ะพะฑัะตะบัั JSON.",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั ัะพัะผะฐั TSV ะฒ JSON",
+ "title": "TSV ะฒ JSON"
+ },
+ "validateJson": {
+ "description": "ะัะพะฒะตัััะต ะบะพััะตะบัะฝะพััั ะธ ะฟัะฐะฒะธะปัะฝะพััั ัะพัะผะฐัะฐ JSON.",
+ "inputTitle": "ะั
ะพะดะฝะพะน JSON",
+ "invalidJson": "โ {{error}}",
+ "resultTitle": "ะ ะตะทัะปััะฐั ะฟัะพะฒะตัะบะธ",
+ "shortDescription": "ะัะพะฒะตัะธัั JSON-ะบะพะด ะฝะฐ ะฝะฐะปะธัะธะต ะพัะธะฑะพะบ",
+ "title": "ะัะพะฒะตัะธัั JSON",
+ "toolInfo": {
+ "description": "JSON (JavaScript Object Notation) โ ััะพ ะพะฑะปะตะณััะฝะฝัะน ัะพัะผะฐั ะพะฑะผะตะฝะฐ ะดะฐะฝะฝัะผะธ. ะัะพะฒะตัะบะฐ JSON ะณะฐัะฐะฝัะธััะตั ัะพะพัะฒะตัััะฒะธะต ััััะบัััั ะดะฐะฝะฝัั
ััะฐะฝะดะฐััั JSON. ะะพััะตะบัะฝัะน ะพะฑัะตะบั JSON ะดะพะปะถะตะฝ ะธะผะตัั: - ะะผะตะฝะฐ ัะฒะพะนััะฒ, ะทะฐะบะปัััะฝะฝัะต ะฒ ะดะฒะพะนะฝัะต ะบะฐะฒััะบะธ. - ะัะฐะฒะธะปัะฝะพ ัะฑะฐะปะฐะฝัะธัะพะฒะฐะฝะฝัะต ัะธะณััะฝัะต ัะบะพะฑะบะธ {}. - ะััััััะฒะธะต ะทะฐะฟัััั
ะฟะพัะปะต ะฟะพัะปะตะดะฝะตะน ะฟะฐัั ยซะบะปัั-ะทะฝะฐัะตะฝะธะตยป. - ะะพััะตะบัะฝัั ะฒะปะพะถะตะฝะฝะพััั ะพะฑัะตะบัะพะฒ ะธ ะผะฐััะธะฒะพะฒ. ะญัะพั ะธะฝััััะผะตะฝั ะฟัะพะฒะตััะตั ะฒั
ะพะดะฝะพะน JSON ะธ ะฟัะตะดะพััะฐะฒะปัะตั ะพะฑัะฐัะฝัั ัะฒัะทั, ะฟะพะผะพะณะฐัััั ะฒััะฒะปััั ะธ ะธัะฟัะฐะฒะปััั ัะฐัะฟัะพัััะฐะฝัะฝะฝัะต ะพัะธะฑะบะธ.",
+ "title": "ะงัะพ ัะฐะบะพะต ะฒะฐะปะธะดะฐัะธั JSON?"
+ },
+ "validJson": "โ
ะะตะนััะฒะธัะตะปัะฝัะน JSON"
+ }
+}
diff --git a/public/locales/ru/list.json b/public/locales/ru/list.json
new file mode 100644
index 0000000..dd7a407
--- /dev/null
+++ b/public/locales/ru/list.json
@@ -0,0 +1,208 @@
+{
+ "duplicate": {
+ "concatenate": "ะะฑัะตะดะธะฝะธัั",
+ "concatenateDescription": "ะะฑัะตะดะธะฝะธัั ะบะพะฟะธะธ (ะตัะปะธ ััะพั ัะปะฐะถะพะบ ะฝะต ัััะฐะฝะพะฒะปะตะฝ, ัะปะตะผะตะฝัั ะฑัะดัั ะฟะตัะตะฟะปะตัะตะฝั)",
+ "copyDescription": "ะะพะปะธัะตััะฒะพ ะบะพะฟะธะน (ะผะพะถะตั ะฑััั ะดัะพะฑะฝัะผ)",
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะบะพะฟะธัะพะฒะฐะฝะธั ัะปะตะผะตะฝัะพะฒ ัะฟะธัะบะฐ. ะะฒะตะดะธัะต ัะฟะธัะพะบ ะธ ัะบะฐะถะธัะต ะบัะธัะตัะธะธ ะบะพะฟะธัะพะฒะฐะฝะธั, ััะพะฑั ัะพะทะดะฐัั ะบะพะฟะธะธ ัะปะตะผะตะฝัะพะฒ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะฐััะธัะตะฝะธั ะดะฐะฝะฝัั
, ัะตััะธัะพะฒะฐะฝะธั ะธะปะธ ัะพะทะดะฐะฝะธั ะฟะพะฒัะพััััะธั
ัั ัะฐะฑะปะพะฝะพะฒ.",
+ "duplicationOptions": "ะะฐัะธะฐะฝัั ะดัะฑะปะธัะพะฒะฐะฝะธั",
+ "examples": {
+ "fractional": {
+ "description": "ะ ััะพะผ ะฟัะธะผะตัะต ะฟะพะบะฐะทะฐะฝะพ, ะบะฐะบ ะดัะฑะปะธัะพะฒะฐัั ัะฟะธัะพะบ ั ะดัะพะฑะฝัะผ ัะธัะปะพะผ ะบะพะฟะธะน.",
+ "title": "ะัะพะฑะฝะพะต ะดัะฑะปะธัะพะฒะฐะฝะธะต"
+ },
+ "interweave": {
+ "description": "ะ ััะพะผ ะฟัะธะผะตัะต ะฟะพะบะฐะทะฐะฝะพ, ะบะฐะบ ะฟะตัะตะฟะปะตัะฐัั ัะปะตะผะตะฝัั, ะฐ ะฝะต ะพะฑัะตะดะธะฝััั ะธั
.",
+ "title": "ะะตัะตะฟะปะตัะตะฝะธะต ะฟัะตะดะผะตัะพะฒ"
+ },
+ "reverse": {
+ "description": "ะ ััะพะผ ะฟัะธะผะตัะต ะฟะพะบะฐะทะฐะฝะพ, ะบะฐะบ ะดัะฑะปะธัะพะฒะฐัั ัะฟะธัะพะบ ะฒ ะพะฑัะฐัะฝะพะผ ะฟะพััะดะบะต.",
+ "title": "ะะฑัะฐัะฝะพะต ะดัะฑะปะธัะพะฒะฐะฝะธะต"
+ },
+ "simple": {
+ "description": "ะ ััะพะผ ะฟัะธะผะตัะต ะฟะพะบะฐะทะฐะฝะพ, ะบะฐะบ ะดัะฑะปะธัะพะฒะฐัั ัะฟะธัะพะบ ัะปะพะฒ.",
+ "title": "ะัะพััะพะต ะดัะฑะปะธัะพะฒะฐะฝะธะต"
+ }
+ },
+ "inputTitle": "ะกะฟะธัะพะบ ะฒั
ะพะดะฝัั
ะดะฐะฝะฝัั
",
+ "joinSeparatorDescription": "ะ ะฐะทะดะตะปะธัะตะปั ะดะปั ะฟัะธัะพะตะดะธะฝะตะฝะธั ะบ ะดัะฑะปะธัะพะฒะฐะฝะฝะพะผั ัะฟะธัะบั",
+ "resultTitle": "ะัะฑะปะธัะพะฒะฐะฝะฝัะน ัะฟะธัะพะบ",
+ "reverse": "ะะฑะตัะฟะตัะธัั ัะตะณัะตัั",
+ "reverseDescription": "ะัะผะตะฝะธัั ะดัะฑะปะธััััะธะตัั ัะปะตะผะตะฝัั",
+ "shortDescription": "ะัะฑะปะธัะพะฒะฐัั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ั ัะบะฐะทะฐะฝะฝัะผะธ ะบัะธัะตัะธัะผะธ",
+ "splitByRegex": "ะ ะฐะทะดะตะปะธัั ะฟะพ ัะตะณัะปััะฝะพะผั ะฒััะฐะถะตะฝะธั",
+ "splitBySymbol": "ะ ะฐะทะดะตะปะธัั ะฟะพ ัะธะผะฒะพะปั",
+ "splitOptions": "ะะฐัะธะฐะฝัั ัะฐะทะดะตะปะตะฝะธั",
+ "splitSeparatorDescription": "ะ ะฐะทะดะตะปะธัะตะปั ะดะปั ัะฐะทะดะตะปะตะฝะธั ัะฟะธัะบะฐ",
+ "title": "ะัะฑะปะธะบะฐั",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะดัะฑะปะธัะพะฒะฐัั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ. ะั ะผะพะถะตัะต ัะบะฐะทะฐัั ะบะพะปะธัะตััะฒะพ ะบะพะฟะธะน (ะฒะบะปััะฐั ะดัะพะฑะฝัะต ะทะฝะฐัะตะฝะธั), ัะฟัะฐะฒะปััั ะพะฑัะตะดะธะฝะตะฝะธะตะผ ะธะปะธ ะฟะตัะตะฟะปะตัะตะฝะธะตะผ ัะปะตะผะตะฝัะพะฒ ะธ ะดะฐะถะต ะธะฝะฒะตััะธัะพะฒะฐัั ะดัะฑะปะธัะพะฒะฐะฝะฝัะต ัะปะตะผะตะฝัั. ะะฝ ะฟะพะปะตะทะตะฝ ะดะปั ัะพะทะดะฐะฝะธั ะฟะพะฒัะพััััะธั
ัั ัะฐะฑะปะพะฝะพะฒ, ะณะตะฝะตัะฐัะธะธ ัะตััะพะฒัั
ะดะฐะฝะฝัั
ะธะปะธ ัะฐััะธัะตะฝะธั ัะฟะธัะบะพะฒ ั ะฟัะตะดัะบะฐะทัะตะผัะผ ัะพะดะตัะถะธะผัะผ.",
+ "title": "ะัะฑะปะธัะพะฒะฐะฝะธะต ัะฟะธัะบะฐ"
+ }
+ },
+ "findMostPopular": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฟะพะธัะบะฐ ัะฐะผัั
ะฟะพะฟัะปััะฝัั
ัะปะตะผะตะฝัะพะฒ ะฒ ัะฟะธัะบะต. ะะฒะตะดะธัะต ะดะฐะฝะฝัะต ะธะท ัะฟะธัะบะฐ ะธ ะผะณะฝะพะฒะตะฝะฝะพ ะฟะพะปััะธัะต ัะปะตะผะตะฝัั, ะบะพัะพััะต ะฒัััะตัะฐัััั ัะฐัะต ะฒัะตะณะพ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะฐะฝะฐะปะธะทะฐ ะดะฐะฝะฝัั
, ะฒััะฒะปะตะฝะธั ัะตะฝะดะตะฝัะธะน ะธะปะธ ะฟะพะธัะบะฐ ะพะฑัะธั
ัะปะตะผะตะฝัะพะฒ.",
+ "shortDescription": "ะะฐะนัะธ ะฝะฐะธะฑะพะปะตะต ัะฐััะพ ะฒัััะตัะฐััะธะตัั ัะปะตะผะตะฝัั",
+ "title": "ะะฐะนัะธ ัะฐะผัะต ะฟะพะฟัะปััะฝัะต"
+ },
+ "findUnique": {
+ "caseSensitiveItems": "ะญะปะตะผะตะฝัั, ััะฒััะฒะธัะตะปัะฝัะต ะบ ัะตะณะธัััั",
+ "caseSensitiveItemsDescription": "ะัะฒะพะดะธัั ัะปะตะผะตะฝัั ั ัะฐะทะฝัะผ ัะตะณะธัััะพะผ ะบะฐะบ ัะฝะธะบะฐะปัะฝัะต ัะปะตะผะตะฝัั ะฒ ัะฟะธัะบะต.",
+ "delimiterDescription": "ะฃััะฐะฝะพะฒะธัะต ัะฐะทะดะตะปะธัะตะปัะฝัะน ัะธะผะฒะพะป ะธะปะธ ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต.",
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฟะพะธัะบะฐ ัะฝะธะบะฐะปัะฝัั
ัะปะตะผะตะฝัะพะฒ ะฒ ัะฟะธัะบะต. ะะฒะตะดะธัะต ะดะฐะฝะฝัะต ะธะท ัะฟะธัะบะฐ ะธ ะผะณะฝะพะฒะตะฝะฝะพ ะฟะพะปััะธัะต ะฒัะต ัะฝะธะบะฐะปัะฝัะต ะทะฝะฐัะตะฝะธั, ัะดะฐะปะธะฒ ะดัะฑะปะธะบะฐัั. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะพัะธััะบะธ ะดะฐะฝะฝัั
, ะดะตะดัะฟะปะธะบะฐัะธะธ ะธะปะธ ะฟะพะธัะบะฐ ัะฝะธะบะฐะปัะฝัั
ัะปะตะผะตะฝัะพะฒ.",
+ "findAbsolutelyUniqueItems": "ะะฐะนะดะธัะต ะฐะฑัะพะปััะฝะพ ัะฝะธะบะฐะปัะฝัะต ะฟัะตะดะผะตัั",
+ "findAbsolutelyUniqueItemsDescription": "ะัะพะฑัะฐะถะฐัั ัะพะปัะบะพ ัะต ัะปะตะผะตะฝัั ัะฟะธัะบะฐ, ะบะพัะพััะต ัััะตััะฒััั ะฒ ะตะดะธะฝััะฒะตะฝะฝะพะผ ัะบะทะตะผะฟะปััะต.",
+ "inputListDelimiter": "ะ ะฐะทะดะตะปะธัะตะปั ะฒั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ",
+ "inputTitle": "ะกะฟะธัะพะบ ะฒั
ะพะดะฝัั
ะดะฐะฝะฝัั
",
+ "outputListDelimiter": "ะ ะฐะทะดะตะปะธัะตะปั ะฒัั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ",
+ "resultTitle": "ะฃะฝะธะบะฐะปัะฝัะต ะฟัะตะดะผะตัั",
+ "shortDescription": "ะะฐะนัะธ ัะฝะธะบะฐะปัะฝัะต ัะปะตะผะตะฝัั ะฒ ัะฟะธัะบะต",
+ "skipEmptyItems": "ะัะพะฟัััะธัั ะฟััััะต ัะปะตะผะตะฝัั",
+ "skipEmptyItemsDescription": "ะะต ะฒะบะปััะฐะนัะต ะฟััััะต ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะฒ ะฒัะฒะพะด.",
+ "title": "ะะฐะนัะธ ัะฝะธะบะฐะปัะฝัะน",
+ "trimItems": "ะญะปะตะผะตะฝัั ัะฟะธัะบะฐ ะพะฑัะตะทะบะธ",
+ "trimItemsDescription": "ะะตัะตะด ััะฐะฒะฝะตะฝะธะตะผ ัะปะตะผะตะฝัะพะฒ ัะดะฐะปะธัะต ะฝะฐัะฐะปัะฝัะต ะธ ะบะพะฝะตัะฝัะต ะฟัะพะฑะตะปั.",
+ "uniqueItemOptions": "ะฃะฝะธะบะฐะปัะฝัะต ะฟะฐัะฐะผะตััั ะฟัะตะดะผะตัะฐ"
+ },
+ "group": {
+ "deleteEmptyItems": "ะฃะดะฐะปะธัั ะฟััััะต ัะปะตะผะตะฝัั",
+ "deleteEmptyItemsDescription": "ะะณะฝะพัะธััะนัะต ะฟััััะต ัะปะตะผะตะฝัั ะธ ะฝะต ะฒะบะปััะฐะนัะต ะธั
ะฒ ะณััะฟะฟั.",
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะณััะฟะฟะธัะพะฒะบะธ ัะปะตะผะตะฝัะพะฒ ัะฟะธัะบะฐ. ะะฒะตะดะธัะต ัะฟะธัะพะบ ะธ ัะบะฐะถะธัะต ะบัะธัะตัะธะธ ะณััะฟะฟะธัะพะฒะบะธ, ััะพะฑั ะพัะณะฐะฝะธะทะพะฒะฐัั ัะปะตะผะตะฝัั ะฒ ะปะพะณะธัะตัะบะธะต ะณััะฟะฟั. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะบะฐัะตะณะพัะธะทะฐัะธะธ ะดะฐะฝะฝัั
, ะพัะณะฐะฝะธะทะฐัะธะธ ะธะฝัะพัะผะฐัะธะธ ะธ ัะพะทะดะฐะฝะธั ััััะบัััะธัะพะฒะฐะฝะฝัั
ัะฟะธัะบะพะฒ. ะะพะดะดะตัะถะธะฒะฐะตั ะฝะฐัััะฐะธะฒะฐะตะผัะต ัะฐะทะดะตะปะธัะตะปะธ ะธ ัะฐะทะปะธัะฝัะต ะฒะฐัะธะฐะฝัั ะณััะฟะฟะธัะพะฒะบะธ.",
+ "emptyItemsAndPadding": "ะััััะต ะฟัะตะดะผะตัั ะธ ะทะฐะฟะพะปะฝะตะฝะธะต",
+ "groupNumberDescription": "ะะพะปะธัะตััะฒะพ ะฟัะตะดะผะตัะพะฒ ะฒ ะณััะฟะฟะต",
+ "groupSeparatorDescription": "ะกะธะผะฒะพะป ัะฐะทะดะตะปะธัะตะปั ะณััะฟะฟ",
+ "groupSizeAndSeparators": "ะ ะฐะทะผะตั ะณััะฟะฟั ะธ ัะฐะทะดะตะปะธัะตะปะธ",
+ "inputItemSeparator": "ะ ะฐะทะดะตะปะธัะตะปั ะฒั
ะพะดะฝัั
ัะปะตะผะตะฝัะพะฒ",
+ "inputTitle": "ะกะฟะธัะพะบ ะฒั
ะพะดะฝัั
ะดะฐะฝะฝัั
",
+ "itemSeparatorDescription": "ะกะธะผะฒะพะป ัะฐะทะดะตะปะธัะตะปั ัะปะตะผะตะฝัะพะฒ",
+ "leftWrapDescription": "ะกะธะผะฒะพะป ะปะตะฒะพะณะพ ะฟะตัะตะฝะพัะฐ ะณััะฟะฟั.",
+ "padNonFullGroups": "ะััะฟะฟั ั ะฝะตะฟะพะปะฝัะผ ะทะฐะฟะพะปะฝะตะฝะธะตะผ",
+ "padNonFullGroupsDescription": "ะะฐะฟะพะปะฝะธัะต ะฝะตะฟะพะปะฝัะต ะณััะฟะฟั ะฟะพะปัะทะพะฒะฐัะตะปััะบะธะผ ัะปะตะผะตะฝัะพะผ (ะฒะฒะตะดะธัะต ะฝะธะถะต).",
+ "paddingCharDescription": "ะัะฟะพะปัะทัะนัะต ััะพั ัะธะผะฒะพะป ะธะปะธ ัะปะตะผะตะฝั ะดะปั ะทะฐะฟะพะปะฝะตะฝะธั ะฝะตะฟะพะปะฝัั
ะณััะฟะฟ.",
+ "resultTitle": "ะกะณััะฟะฟะธัะพะฒะฐะฝะฝัะต ัะปะตะผะตะฝัั",
+ "rightWrapDescription": "ะัะฐะฒัะน ัะธะผะฒะพะป ะฟะตัะตะฝะพัะฐ ะณััะฟะฟั.",
+ "shortDescription": "ะััะฟะฟะธัะพะฒะฐัั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะฟะพ ะพะฑัะธะผ ัะฒะพะนััะฒะฐะผ",
+ "splitOperators": {
+ "regex": {
+ "description": "ะ ะฐะทะดะตะปะธัะต ัะปะตะผะตะฝัั ะฒั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ ั ะฟะพะผะพััั ัะตะณัะปััะฝะพะณะพ ะฒััะฐะถะตะฝะธั.",
+ "title": "ะัะฟะพะปัะทัะนัะต ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต ะดะปั ัะฐะทะดะตะปะตะฝะธั"
+ },
+ "symbol": {
+ "description": "ะ ะฐะทะดะตะปะธัะต ัะปะตะผะตะฝัั ะฒั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ ัะธะผะฒะพะปะพะผ.",
+ "title": "ะัะฟะพะปัะทัะนัะต ัะธะผะฒะพะป ะดะปั ัะฐะทะดะตะปะตะฝะธั"
+ }
+ },
+ "splitSeparatorDescription": "ะฃััะฐะฝะพะฒะธัะต ัะฐะทะดะตะปะธัะตะปัะฝัะน ัะธะผะฒะพะป ะธะปะธ ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต.",
+ "title": "ะััะฟะฟะฐ"
+ },
+ "reverse": {
+ "description": "ะญัะพ ะพัะตะฝั ะฟัะพััะพะต ะฑัะฐัะทะตัะฝะพะต ะฟัะธะปะพะถะตะฝะธะต, ะบะพัะพัะพะต ะฒัะฒะพะดะธั ะฒัะต ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะฒ ะพะฑัะฐัะฝะพะผ ะฟะพััะดะบะต. ะญะปะตะผะตะฝัั ะฒะฒะพะดะฐ ะผะพะถะฝะพ ัะฐะทะดะตะปััั ะปัะฑัะผ ัะธะผะฒะพะปะพะผ, ะธ ะฒั ัะฐะบะถะต ะผะพะถะตัะต ะธะทะผะตะฝะธัั ัะฐะทะดะตะปะธัะตะปั ะดะปั ัะปะตะผะตะฝัะพะฒ ะฟะตัะตะฒััะฝััะพะณะพ ัะฟะธัะบะฐ.",
+ "inputTitle": "ะกะฟะธัะพะบ ะฒั
ะพะดะฝัั
ะดะฐะฝะฝัั
",
+ "itemSeparator": "ะ ะฐะทะดะตะปะธัะตะปั ัะปะตะผะตะฝัะพะฒ",
+ "itemSeparatorDescription": "ะฃััะฐะฝะพะฒะธัะต ัะฐะทะดะตะปะธัะตะปัะฝัะน ัะธะผะฒะพะป ะธะปะธ ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต.",
+ "outputListOptions": "ะะฐัะฐะผะตััั ะฒัั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ",
+ "outputSeparatorDescription": "ะ ะฐะทะดะตะปะธัะตะปั ัะปะตะผะตะฝัะพะฒ ะฒัั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ.",
+ "resultTitle": "ะะฑัะฐัะฝัะน ัะฟะธัะพะบ",
+ "shortDescription": "ะััััะพ ะฟะตัะตะฒะตัะฝััั ัะฟะธัะพะบ",
+ "splitOperators": {
+ "regex": {
+ "description": "ะ ะฐะทะดะตะปะธัะต ัะปะตะผะตะฝัั ะฒั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ ั ะฟะพะผะพััั ัะตะณัะปััะฝะพะณะพ ะฒััะฐะถะตะฝะธั.",
+ "title": "ะัะฟะพะปัะทัะนัะต ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต ะดะปั ัะฐะทะดะตะปะตะฝะธั"
+ },
+ "symbol": {
+ "description": "ะ ะฐะทะดะตะปัะนัะต ัะปะตะผะตะฝัั ะฒั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ ัะธะผะฒะพะปะฐะผะธ.",
+ "title": "ะัะฟะพะปัะทัะนัะต ัะธะผะฒะพะป ะดะปั ัะฐะทะดะตะปะตะฝะธั"
+ }
+ },
+ "splitterMode": "ะ ะตะถะธะผ ัะฐะทะดะตะปะธัะตะปั",
+ "title": "ะะฑะตัะฟะตัะธัั ัะตะณัะตัั",
+ "toolInfo": {
+ "description": "ะก ะฟะพะผะพััั ััะพะน ััะธะปะธัั ะฒั ะผะพะถะตัะต ะธะทะผะตะฝะธัั ะฟะพััะดะพะบ ัะปะตะผะตะฝัะพะฒ ะฒ ัะฟะธัะบะต ะฝะฐ ะพะฑัะฐัะฝัะน. ะฃัะธะปะธัะฐ ัะฝะฐัะฐะปะฐ ัะฐะทะฑะธะฒะฐะตั ะฒั
ะพะดะฝะพะน ัะฟะธัะพะบ ะฝะฐ ะพัะดะตะปัะฝัะต ัะปะตะผะตะฝัั, ะฐ ะทะฐัะตะผ ะฟัะพั
ะพะดะธั ะฟะพ ะฝะธะผ ะพั ะฟะพัะปะตะดะฝะตะณะพ ะบ ะฟะตัะฒะพะผั, ะฒัะฒะพะดั ะบะฐะถะดัะน ัะปะตะผะตะฝั ะฝะฐ ะฒัั
ะพะด. ะั
ะพะดะฝะพะน ัะฟะธัะพะบ ะผะพะถะตั ัะพะดะตัะถะฐัั ะปัะฑัะต ัะตะบััะพะฒัะต ะดะฐะฝะฝัะต, ะฒะบะปััะฐั ัะธััั, ัะธัะปะฐ, ัััะพะบะธ, ัะปะพะฒะฐ, ะฟัะตะดะปะพะถะตะฝะธั ะธ ั. ะด. ะ ะฐะทะดะตะปะธัะตะปะตะผ ัะปะตะผะตะฝัะพะฒ ะฒั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ ัะฐะบะถะต ะผะพะถะตั ะฑััั ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต. ะะฐะฟัะธะผะตั, ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต /[;,]/ ะฟะพะทะฒะพะปะธั ะธัะฟะพะปัะทะพะฒะฐัั ัะปะตะผะตะฝัั, ัะฐะทะดะตะปัะฝะฝัะต ะทะฐะฟัััะผะธ ะธะปะธ ัะพัะบะพะน ั ะทะฐะฟััะพะน. ะ ะฐะทะดะตะปะธัะตะปะธ ัะปะตะผะตะฝัะพะฒ ะฒั
ะพะดะฝะพะณะพ ะธ ะฒัั
ะพะดะฝะพะณะพ ัะฟะธัะบะพะฒ ะผะพะถะฝะพ ะฝะฐัััะพะธัั ะฒ ะฟะฐัะฐะผะตััะฐั
. ะะพ ัะผะพะปัะฐะฝะธั ะบะฐะบ ะฒั
ะพะดะฝะพะน, ัะฐะบ ะธ ะฒัั
ะพะดะฝะพะน ัะฟะธัะบะธ ัะฐะทะดะตะปััััั ะทะฐะฟัััะผะธ. Listabulous!",
+ "title": "ะงัะพ ัะฐะบะพะต ัะตะฒะตัั ัะฟะธัะบะฐ?"
+ }
+ },
+ "rotate": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฟะพะฒะพัะพัะฐ ัะปะตะผะตะฝัะพะฒ ัะฟะธัะบะฐ. ะะฒะตะดะธัะต ัะฟะธัะพะบ ะธ ัะบะฐะถะธัะต ะฒะตะปะธัะธะฝั ะฟะพะฒะพัะพัะฐ, ััะพะฑั ัะผะตััะธัั ัะปะตะผะตะฝัั ะฝะฐ ัะบะฐะทะฐะฝะฝะพะต ะบะพะปะธัะตััะฒะพ ะฟะพะทะธัะธะน. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะพะฑัะฐะฑะพัะบะธ ะดะฐะฝะฝัั
, ัะธะบะปะธัะตัะบะธั
ัะดะฒะธะณะพะฒ ะธะปะธ ะธะทะผะตะฝะตะฝะธั ะฟะพััะดะบะฐ ัะฟะธัะบะพะฒ.",
+ "shortDescription": "ะะพะฒะตัะฝััั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะฟะพ ัะบะฐะทะฐะฝะฝัะผ ะฟะพะทะธัะธัะผ",
+ "title": "ะะพะฒะตัะฝััั"
+ },
+ "shuffle": {
+ "delimiterDescription": "ะฃััะฐะฝะพะฒะธัะต ัะฐะทะดะตะปะธัะตะปัะฝัะน ัะธะผะฒะพะป ะธะปะธ ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต.",
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฟะตัะตะผะตัะธะฒะฐะฝะธั ัะปะตะผะตะฝัะพะฒ ัะฟะธัะบะฐ. ะะฒะตะดะธัะต ัะฒะพะน ัะฟะธัะพะบ ะธ ะผะณะฝะพะฒะตะฝะฝะพ ะฟะพะปััะธัะต ะตะณะพ ัะปััะฐะนะฝัั ะฒะตััะธั ั ัะปะตะผะตะฝัะฐะผะธ ะฒ ัะปััะฐะนะฝะพะผ ะฟะพััะดะบะต. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะพะทะดะฐะฝะธั ัะฐะทะฝะพะพะฑัะฐะทะธั, ะฟัะพะฒะตัะบะธ ัะปััะฐะนะฝะพััะธ ะธะปะธ ะฟะตัะตะผะตัะธะฒะฐะฝะธั ัะฟะพััะดะพัะตะฝะฝัั
ะดะฐะฝะฝัั
.",
+ "inputListSeparator": "ะ ะฐะทะดะตะปะธัะตะปั ะฒั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ",
+ "inputTitle": "ะกะฟะธัะพะบ ะฒั
ะพะดะฝัั
ะดะฐะฝะฝัั
",
+ "joinSeparatorDescription": "ะัะฟะพะปัะทัะนัะต ััะพั ัะฐะทะดะตะปะธัะตะปั ะฒ ัะฐะฝะดะพะผะธะทะธัะพะฒะฐะฝะฝะพะผ ัะฟะธัะบะต.",
+ "outputLengthDescription": "ะัะฒะตััะธ ััะพะปัะบะพ ัะปััะฐะนะฝัั
ัะปะตะผะตะฝัะพะฒ",
+ "resultTitle": "ะะตัะตะผะตัะฐะฝะฝัะน ัะฟะธัะพะบ",
+ "shortDescription": "ะ ะฐัะฟะพะปะพะถะธัั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะฒ ัะปััะฐะนะฝะพะผ ะฟะพััะดะบะต",
+ "shuffledListLength": "ะะปะธะฝะฐ ะฟะตัะตะผะตัะฐะฝะฝะพะณะพ ัะฟะธัะบะฐ",
+ "shuffledListSeparator": "ะ ะฐะทะดะตะปะธัะตะปั ะฟะตัะตะผะตัะฐะฝะฝะพะณะพ ัะฟะธัะบะฐ",
+ "title": "ะะตัะตะผะตัะฐัั"
+ },
+ "sort": {
+ "caseSensitive": "ะกะพััะธัะพะฒะบะฐ ั ััะตัะพะผ ัะตะณะธัััะฐ",
+ "caseSensitiveDescription": "ะกะพััะธััะนัะต ัะปะตะผะตะฝัั ั ะทะฐะณะปะฐะฒะฝัะผะธ ะธ ัััะพัะฝัะผะธ ะฑัะบะฒะฐะผะธ ะพัะดะตะปัะฝะพ. ะะฐะณะปะฐะฒะฝัะต ะฑัะบะฒั ัะฐัะฟะพะปะฐะณะฐัััั ะฟะตัะตะด ัััะพัะฝัะผะธ ะฒ ัะฟะธัะบะต ะฟะพ ะฒะพะทัะฐััะฐะฝะธั. (ะ ะฐะฑะพัะฐะตั ัะพะปัะบะพ ะฒ ัะตะถะธะผะต ัะพััะธัะพะฒะบะธ ะฟะพ ะฐะปัะฐะฒะธัั.)",
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ัะพััะธัะพะฒะบะธ ัะปะตะผะตะฝัะพะฒ ัะฟะธัะบะฐ. ะะฒะตะดะธัะต ัะฟะธัะพะบ ะธ ัะบะฐะถะธัะต ะบัะธัะตัะธะธ ัะพััะธัะพะฒะบะธ, ััะพะฑั ัะฟะพััะดะพัะธัั ัะปะตะผะตะฝัั ะฟะพ ะฒะพะทัะฐััะฐะฝะธั ะธะปะธ ัะฑัะฒะฐะฝะธั. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะพัะณะฐะฝะธะทะฐัะธะธ ะดะฐะฝะฝัั
, ะพะฑัะฐะฑะพัะบะธ ัะตะบััะฐ ะธ ัะพะทะดะฐะฝะธั ัะฟะพััะดะพัะตะฝะฝัั
ัะฟะธัะบะพะฒ.",
+ "inputItemSeparator": "ะ ะฐะทะดะตะปะธัะตะปั ะฒั
ะพะดะฝัั
ัะปะตะผะตะฝัะพะฒ",
+ "inputTitle": "ะกะฟะธัะพะบ ะฒั
ะพะดะฝัั
ะดะฐะฝะฝัั
",
+ "joinSeparatorDescription": "ะัะฟะพะปัะทัะนัะต ััะพั ัะธะผะฒะพะป ะดะปั ะพะฑัะตะดะธะฝะตะฝะธั ัะปะตะผะตะฝัะพะฒ ะฒ ะพััะพััะธัะพะฒะฐะฝะฝะพะผ ัะฟะธัะบะต.",
+ "orderDescription": "ะัะฑะตัะธัะต ะฟะพััะดะพะบ ัะพััะธัะพะฒะบะธ.",
+ "orderOptions": {
+ "decreasing": "ะ ะฟะพััะดะบะต ัะฑัะฒะฐะฝะธั",
+ "increasing": "ะะพ ะฒะพะทัะฐััะฐะฝะธั"
+ },
+ "removeDuplicates": "ะฃะดะฐะปะธัั ะดัะฑะปะธะบะฐัั",
+ "removeDuplicatesDescription": "ะฃะดะฐะปะธัั ะดัะฑะปะธััััะธะตัั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ.",
+ "resultTitle": "ะกะพััะธัะพะฒะฐะฝะฝัะน ัะฟะธัะพะบ",
+ "shortDescription": "ะกะพััะธัะพะฒะฐัั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะฒ ัะบะฐะทะฐะฝะฝะพะผ ะฟะพััะดะบะต",
+ "sortMethod": "ะะตัะพะด ัะพััะธัะพะฒะบะธ",
+ "sortMethodDescription": "ะัะฑะตัะธัะต ะผะตัะพะด ัะพััะธัะพะฒะบะธ.",
+ "sortOptions": {
+ "alphabetic": "ะกะพััะธัะพะฒะฐัั ะฟะพ ะฐะปัะฐะฒะธัั",
+ "length": "ะกะพััะธัะพะฒะฐัั ะฟะพ ะดะปะธะฝะต",
+ "numeric": "ะกะพััะธัะพะฒะบะฐ ะฟะพ ัะธัะปะฐะผ"
+ },
+ "sortedItemProperties": "ะกะพััะธัะพะฒะฐะฝะฝัะต ัะฒะพะนััะฒะฐ ัะปะตะผะตะฝัะพะฒ",
+ "splitOperators": {
+ "regex": {
+ "description": "ะ ะฐะทะดะตะปะธัะต ัะปะตะผะตะฝัั ะฒั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ ั ะฟะพะผะพััั ัะตะณัะปััะฝะพะณะพ ะฒััะฐะถะตะฝะธั.",
+ "title": "ะัะฟะพะปัะทัะนัะต ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต ะดะปั ัะฐะทะดะตะปะตะฝะธั"
+ },
+ "symbol": {
+ "description": "ะ ะฐะทะดะตะปัะนัะต ัะปะตะผะตะฝัั ะฒั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ ัะธะผะฒะพะปะฐะผะธ.",
+ "title": "ะัะฟะพะปัะทัะนัะต ัะธะผะฒะพะป ะดะปั ัะฐะทะดะตะปะตะฝะธั"
+ }
+ },
+ "splitSeparatorDescription": "ะฃััะฐะฝะพะฒะธัะต ัะฐะทะดะตะปะธัะตะปัะฝัะน ัะธะผะฒะพะป ะธะปะธ ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต.",
+ "title": "ะกะพััะธัะพะฒะฐัั"
+ },
+ "truncate": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะพะฑัะตะทะบะธ ัะฟะธัะบะพะฒ. ะะฒะตะดะธัะต ัะฟะธัะพะบ ะธ ัะบะฐะถะธัะต ะผะฐะบัะธะผะฐะปัะฝะพะต ะบะพะปะธัะตััะฒะพ ัะปะตะผะตะฝัะพะฒ, ะบะพัะพััะต ะฝัะถะฝะพ ัะพั
ัะฐะฝะธัั. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะพะฑัะฐะฑะพัะบะธ ะดะฐะฝะฝัั
, ัะฟัะฐะฒะปะตะฝะธั ัะฟะธัะบะฐะผะธ ะธะปะธ ะพะณัะฐะฝะธัะตะฝะธั ะดะปะธะฝั ะบะพะฝัะตะฝัะฐ.",
+ "shortDescription": "ะกะพะบัะฐัะธัั ัะฟะธัะพะบ ะดะพ ัะบะฐะทะฐะฝะฝะพะณะพ ะบะพะปะธัะตััะฒะฐ ัะปะตะผะตะฝัะพะฒ",
+ "title": "ะฃัะตัะตะฝะธะต"
+ },
+ "unwrap": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ัะฐะทะฒััััะฒะฐะฝะธั ัะปะตะผะตะฝัะพะฒ ัะฟะธัะบะฐ. ะะฒะตะดะธัะต ัะฒะพะน ัะฐะทะฒััะฝัััะน ัะฟะธัะพะบ ะธ ัะบะฐะถะธัะต ะบัะธัะตัะธะธ ัะฐะทะฒััััะฒะฐะฝะธั, ััะพะฑั ัะดะตะปะฐัั ัะฟะพััะดะพัะตะฝะฝัะต ัะปะตะผะตะฝัั ะฟะปะพัะบะธะผะธ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะพะฑัะฐะฑะพัะบะธ ะดะฐะฝะฝัั
, ัะฐะฑะพัั ั ัะตะบััะพะผ ะธะปะธ ะธะทะฒะปะตัะตะฝะธั ะบะพะฝัะตะฝัะฐ ะธะท ััััะบัััะธัะพะฒะฐะฝะฝัั
ัะฟะธัะบะพะฒ.",
+ "shortDescription": "ะะทะฒะปะตัั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะธะท ััััะบัััะธัะพะฒะฐะฝะฝะพะณะพ ัะพัะผะฐัะฐ",
+ "title": "ะ ะฐะทะฒะตัะฝััั"
+ },
+ "wrap": {
+ "description": "ะะพะฑะฐะฒััะต ัะตะบัั ะดะพ ะธ ะฟะพัะปะต ะบะฐะถะดะพะณะพ ัะปะตะผะตะฝัะฐ ัะฟะธัะบะฐ.",
+ "inputTitle": "ะกะฟะธัะพะบ ะฒั
ะพะดะฝัั
ะดะฐะฝะฝัั
",
+ "joinSeparatorDescription": "ะ ะฐะทะดะตะปะธัะตะปั ะดะปั ะฟัะธัะพะตะดะธะฝะตะฝะธั ะบ ัะฟะฐะบะพะฒะฐะฝะฝะพะผั ัะฟะธัะบั",
+ "leftTextDescription": "ะขะตะบัั, ะบะพัะพััะน ะฝัะถะฝะพ ะดะพะฑะฐะฒะธัั ะฟะตัะตะด ะบะฐะถะดัะผ ัะปะตะผะตะฝัะพะผ",
+ "removeEmptyItems": "ะฃะดะฐะปะธัั ะฟััััะต ัะปะตะผะตะฝัั",
+ "resultTitle": "ะะฑะตัะฝัััะน ัะฟะธัะพะบ",
+ "rightTextDescription": "ะขะตะบัั, ะบะพัะพััะน ะฝัะถะฝะพ ะดะพะฑะฐะฒะธัั ะฟะพัะปะต ะบะฐะถะดะพะณะพ ัะปะตะผะตะฝัะฐ",
+ "shortDescription": "ะะฑะตัะฝััั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะฟะพ ัะบะฐะทะฐะฝะฝัะผ ะบัะธัะตัะธัะผ",
+ "splitByRegex": "ะ ะฐะทะดะตะปะธัั ะฟะพ ัะตะณัะปััะฝะพะผั ะฒััะฐะถะตะฝะธั",
+ "splitBySymbol": "ะ ะฐะทะดะตะปะธัั ะฟะพ ัะธะผะฒะพะปั",
+ "splitOptions": "ะะฐัะธะฐะฝัั ัะฐะทะดะตะปะตะฝะธั",
+ "splitSeparatorDescription": "ะ ะฐะทะดะตะปะธัะตะปั ะดะปั ัะฐะทะดะตะปะตะฝะธั ัะฟะธัะบะฐ",
+ "title": "ะกะฒะพัะฐัะธะฒะฐัั",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะดะพะฑะฐะฒะปััั ัะตะบัั ะฟะตัะตะด ะบะฐะถะดัะผ ัะปะตะผะตะฝัะพะผ ัะฟะธัะบะฐ ะธ ะฟะพัะปะต ะฝะตะณะพ. ะั ะผะพะถะตัะต ัะบะฐะทะฐัั ัะฐะทะฝัะน ัะตะบัั ะดะปั ะปะตะฒะพะน ะธ ะฟัะฐะฒะพะน ัะฐััะตะน ัะฟะธัะบะฐ ะธ ัะฟัะฐะฒะปััั ะพะฑัะฐะฑะพัะบะพะน ัะฟะธัะบะฐ. ะะฝ ะฟะพะปะตะทะตะฝ ะดะปั ะดะพะฑะฐะฒะปะตะฝะธั ะบะฐะฒััะตะบ, ัะบะพะฑะพะบ ะธ ะดััะณะพะณะพ ัะพัะผะฐัะธัะพะฒะฐะฝะธั ัะปะตะผะตะฝัะพะฒ ัะฟะธัะบะฐ, ะฟะพะดะณะพัะพะฒะบะธ ะดะฐะฝะฝัั
ะดะปั ัะฐะทะปะธัะฝัั
ัะพัะผะฐัะพะฒ ะธะปะธ ัะพะทะดะฐะฝะธั ััััะบัััะธัะพะฒะฐะฝะฝะพะณะพ ัะตะบััะฐ.",
+ "title": "ะะตัะตะฝะพั ัะฟะธัะบะฐ"
+ },
+ "wrapOptions": "ะะฐัะธะฐะฝัั ะพะฑะตัััะฒะฐะฝะธั"
+ }
+}
diff --git a/public/locales/ru/number.json b/public/locales/ru/number.json
new file mode 100644
index 0000000..a9fdc89
--- /dev/null
+++ b/public/locales/ru/number.json
@@ -0,0 +1,89 @@
+{
+ "arithmeticSequence": {
+ "commonDifferenceDescription": "ะะฑัะตะต ัะฐะทะปะธัะธะต ะผะตะถะดั ัะตัะผะธะฝะฐะผะธ (ะณ)",
+ "description": "ะะตะฝะตัะฐัะธั ะฐัะธัะผะตัะธัะตัะบะธั
ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััะตะน ั ะฝะฐัััะฐะธะฒะฐะตะผัะผะธ ะฟะฐัะฐะผะตััะฐะผะธ.",
+ "firstTermDescription": "ะะตัะฒัะน ัะปะตะฝ ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััะธ (aโ)",
+ "numberOfTermsDescription": "ะะพะปะธัะตััะฒะพ ะณะตะฝะตัะธััะตะผัั
ัะตัะผะธะฝะพะฒ (n)",
+ "outputFormat": "ะคะพัะผะฐั ะฒัะฒะพะดะฐ",
+ "resultTitle": "ะกะณะตะฝะตัะธัะพะฒะฐะฝะฝะฐั ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััั",
+ "separatorDescription": "ะ ะฐะทะดะตะปะธัะตะปั ะผะตะถะดั ัะตัะผะธะฝะฐะผะธ",
+ "sequenceParameters": "ะะฐัะฐะผะตััั ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััะธ",
+ "shortDescription": "ะะตะฝะตัะฐัะธั ะฐัะธัะผะตัะธัะตัะบะธั
ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััะตะน",
+ "title": "ะัะธัะผะตัะธัะตัะบะฐั ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััั",
+ "toolInfo": {
+ "description": "ะัะธัะผะตัะธัะตัะบะฐั ะฟัะพะณัะตััะธั โ ััะพ ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััั ัะธัะตะป, ะฒ ะบะพัะพัะพะน ัะฐะทะฝะพััั ะผะตะถะดั ะบะฐะถะดัะผ ะฟะพัะปะตะดัััะธะผ ัะปะตะฝะพะผ ะฟะพััะพัะฝะฝะฐ. ะญัะฐ ะฟะพััะพัะฝะฝะฐั ัะฐะทะฝะพััั ะฝะฐะทัะฒะฐะตััั ัะฐะทะฝะพัััั. ะะฝะฐั ะฟะตัะฒัะน ัะปะตะฝ (aโ) ะธ ัะฐะทะฝะพััั (d), ะผะพะถะฝะพ ะฝะฐะนัะธ ะบะฐะถะดัะน ัะปะตะฝ, ะฟัะธะฑะฐะฒะธะฒ ัะฐะทะฝะพััั ะบ ะฟัะตะดัะดััะตะผั.",
+ "title": "ะงัะพ ัะฐะบะพะต ะฐัะธัะผะตัะธัะตัะบะฐั ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััั?"
+ }
+ },
+ "generate": {
+ "arithmeticSequenceOption": "ะะฐัะธะฐะฝั ะฐัะธัะผะตัะธัะตัะบะพะน ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััะธ",
+ "description": "ะกะณะตะฝะตัะธััะนัะต ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััั ัะธัะตะป ั ะฝะฐัััะฐะธะฒะฐะตะผัะผะธ ะฟะฐัะฐะผะตััะฐะผะธ.",
+ "numberOfElementsDescription": "ะะพะปะธัะตััะฒะพ ัะปะตะผะตะฝัะพะฒ ะฒ ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััะธ.",
+ "resultTitle": "ะกะณะตะฝะตัะธัะพะฒะฐะฝะฝัะต ัะธัะปะฐ",
+ "separator": "ะ ะฐะทะดะตะปะธัะตะปั",
+ "separatorDescription": "ะ ะฐะทะดะตะปะธัะต ัะปะตะผะตะฝัั ะฒ ะฐัะธัะผะตัะธัะตัะบะพะน ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััะธ ััะธะผ ัะธะผะฒะพะปะพะผ.",
+ "shortDescription": "ะะตะฝะตัะฐัะธั ัะปััะฐะนะฝัั
ัะธัะตะป ะฒ ัะบะฐะทะฐะฝะฝัั
ะดะธะฐะฟะฐะทะพะฝะฐั
",
+ "startSequenceDescription": "ะะฐัะฝะธัะต ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััั ั ััะพะณะพ ัะธัะปะฐ.",
+ "stepDescription": "ะฃะฒะตะปะธัััะต ะบะฐะถะดัะน ัะปะตะผะตะฝั ะฝะฐ ััั ะฒะตะปะธัะธะฝั",
+ "title": "ะะตะฝะตัะธัะพะฒะฐัั",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะณะตะฝะตัะธัะพะฒะฐัั ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััั ัะธัะตะป ั ะฝะฐัััะฐะธะฒะฐะตะผัะผะธ ะฟะฐัะฐะผะตััะฐะผะธ. ะั ะผะพะถะตัะต ัะบะฐะทะฐัั ะฝะฐัะฐะปัะฝะพะต ะทะฝะฐัะตะฝะธะต, ัะฐะทะผะตั ัะฐะณะฐ ะธ ะบะพะปะธัะตััะฒะพ ัะปะตะผะตะฝัะพะฒ.",
+ "title": "ะะตะฝะตัะธัะพะฒะฐัั ัะธัะปะฐ"
+ }
+ },
+ "ohmsLaw": {
+ "description": "ะ ะฐัััะธััะฒะฐะตั ะฝะฐะฟััะถะตะฝะธะต, ัะพะบ ะธ ัะพะฟัะพัะธะฒะปะตะฝะธะต",
+ "longDescription": "ะญัะพั ะบะฐะปัะบัะปััะพั ะธัะฟะพะปัะทัะตั ะทะฐะบะพะฝ ะะผะฐ (V = I ร R) ะดะปั ะพะฟัะตะดะตะปะตะฝะธั ะปัะฑะพะณะพ ะธะท ัััั
ัะปะตะบััะธัะตัะบะธั
ะฟะฐัะฐะผะตััะพะฒ ะฟัะธ ะธะทะฒะตััะฝัั
ะดะฒัั
ะดััะณะธั
. ะะฐะบะพะฝ ะะผะฐ โ ััะฝะดะฐะผะตะฝัะฐะปัะฝัะน ะฟัะธะฝัะธะฟ ัะปะตะบััะพัะตั
ะฝะธะบะธ, ะพะฟะธััะฒะฐััะธะน ะฒะทะฐะธะผะพัะฒัะทั ะผะตะถะดั ะฝะฐะฟััะถะตะฝะธะตะผ (V), ัะพะบะพะผ (I) ะธ ัะพะฟัะพัะธะฒะปะตะฝะธะตะผ (R). ะญัะพั ะธะฝััััะผะตะฝั ะฝะตะทะฐะผะตะฝะธะผ ะดะปั ะปัะฑะธัะตะปะตะน ัะปะตะบััะพะฝะธะบะธ, ะธะฝะถะตะฝะตัะพะฒ-ัะปะตะบััะธะบะพะฒ ะธ ัััะดะตะฝัะพะฒ, ัะฐะฑะพัะฐััะธั
ั ัะปะตะบััะธัะตัะบะธะผะธ ัั
ะตะผะฐะผะธ, ะดะปั ะฑััััะพะณะพ ะฝะฐั
ะพะถะดะตะฝะธั ะฝะตะธะทะฒะตััะฝัั
ะทะฝะฐัะตะฝะธะน ะฒ ัะฒะพะธั
ัะปะตะบััะธัะตัะบะธั
ัั
ะตะผะฐั
.",
+ "shortDescription": "ะ ะฐัััะธัะฐะนัะต ะฝะฐะฟััะถะตะฝะธะต, ัะพะบ ะธะปะธ ัะพะฟัะพัะธะฒะปะตะฝะธะต ะฒ ัะปะตะบััะธัะตัะบะธั
ัะตะฟัั
, ะธัะฟะพะปัะทัั ะทะฐะบะพะฝ ะะผะฐ.",
+ "title": "ะะฐะบะพะฝ ะะผะฐ"
+ },
+ "slackline": {
+ "description": "ะ ะฐัััะธััะฒะฐะตั ะฝะฐััะถะตะฝะธะต ัััะพะฟั",
+ "longDescription": "ะญัะพั ะบะฐะปัะบัะปััะพั ะฟัะตะดะฟะพะปะฐะณะฐะตั ะฝะฐะปะธัะธะต ะฝะฐะณััะทะบะธ ะฒ ัะตะฝััะต ััะพัะฐ.",
+ "shortDescription": "ะ ะฐัััะธัะฐะนัะต ะฟัะธะผะตัะฝะพะต ะฝะฐััะถะตะฝะธะต ัััะพะฟั ะธะปะธ ะฑะตะปัะตะฒะพะน ะฒะตัะตะฒะบะธ. ะะต ะฟะพะปะฐะณะฐะนัะตัั ะฝะฐ ััะพ ะฒ ะฒะพะฟัะพัะฐั
ะฑะตะทะพะฟะฐัะฝะพััะธ.",
+ "title": "ะะฐััะถะตะฝะธะต ัััะพะฟั"
+ },
+ "sphereArea": {
+ "description": "ะะปะพัะฐะดั ััะตัั",
+ "longDescription": "ะญัะพั ะบะฐะปัะบัะปััะพั ะฒััะธัะปัะตั ะฟะปะพัะฐะดั ะฟะพะฒะตัั
ะฝะพััะธ ััะตัั ะฟะพ ัะพัะผัะปะต A = 4ฯrยฒ. ะั ะผะพะถะตัะต ะปะธะฑะพ ะฒะฒะตััะธ ัะฐะดะธัั ะดะปั ะฝะฐั
ะพะถะดะตะฝะธั ะฟะปะพัะฐะดะธ ะฟะพะฒะตัั
ะฝะพััะธ, ะปะธะฑะพ ะฒะฒะตััะธ ะฟะปะพัะฐะดั ะฟะพะฒะตัั
ะฝะพััะธ ะดะปั ัะฐััััะฐ ะธัะบะพะผะพะณะพ ัะฐะดะธััะฐ. ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะปะตะทะตะฝ ะดะปั ัััะดะตะฝัะพะฒ, ะธะทััะฐััะธั
ะณะตะพะผะตััะธั, ะธะฝะถะตะฝะตัะพะฒ, ัะฐะฑะพัะฐััะธั
ัะพ ััะตัะธัะตัะบะธะผะธ ะพะฑัะตะบัะฐะผะธ, ะธ ะฒัะตั
, ะบะพะผั ะฝะตะพะฑั
ะพะดะธะผะพ ะฒัะฟะพะปะฝััั ัะฐััััั, ัะฒัะทะฐะฝะฝัะต ัะพ ััะตัะธัะตัะบะธะผะธ ะฟะพะฒะตัั
ะฝะพัััะผะธ.",
+ "shortDescription": "ะ ะฐัััะธัะฐะนัะต ะฟะปะพัะฐะดั ะฟะพะฒะตัั
ะฝะพััะธ ััะตัั ะฟะพ ะตะต ัะฐะดะธััั.",
+ "title": "ะะปะพัะฐะดั ััะตัั"
+ },
+ "sphereVolume": {
+ "description": "ะะฑัะตะผ ััะตัั",
+ "longDescription": "ะญัะพั ะบะฐะปัะบัะปััะพั ะฒััะธัะปัะตั ะพะฑััะผ ััะตัั ะฟะพ ัะพัะผัะปะต V = (4/3)ฯrยณ. ะั ะผะพะถะตัะต ะฒะฒะตััะธ ัะฐะดะธัั ะธะปะธ ะดะธะฐะผะตัั ะดะปั ัะฐััััะฐ ะพะฑััะผะฐ, ะปะธะฑะพ ะฒะฒะตััะธ ะพะฑััะผ ะดะปั ะพะฟัะตะดะตะปะตะฝะธั ะฝะตะพะฑั
ะพะดะธะผะพะณะพ ัะฐะดะธััะฐ. ะญัะพั ะธะฝััััะผะตะฝั ะฑัะดะตั ะฟะพะปะตะทะตะฝ ัััะดะตะฝัะฐะผ, ะธะฝะถะตะฝะตัะฐะผ ะธ ัะฟะตัะธะฐะปะธััะฐะผ, ัะฐะฑะพัะฐััะธะผ ัะพ ััะตัะธัะตัะบะธะผะธ ะพะฑัะตะบัะฐะผะธ ะฒ ัะฐะบะธั
ะพะฑะปะฐัััั
, ะบะฐะบ ัะธะทะธะบะฐ, ะธะฝะถะตะฝะตัะธั ะธ ะฟัะพะธะทะฒะพะดััะฒะพ.",
+ "shortDescription": "ะ ะฐัััะธัะฐะนัะต ะพะฑัะตะผ ััะตัั, ะธัะฟะพะปัะทัั ัะฐะดะธัั ะธะปะธ ะดะธะฐะผะตัั.",
+ "title": "ะะฑัะตะผ ััะตัั"
+ },
+ "sum": {
+ "description": "ะััะธัะปะธัะต ััะผะผั ัะฟะธัะบะฐ ัะธัะตะป. ะะฒะตะดะธัะต ัะธัะปะฐ, ัะฐะทะดะตะปะตะฝะฝัะต ะทะฐะฟัััะผะธ ะธะปะธ ัะธะผะฒะพะปะฐะผะธ ะฟะตัะตะฝะพัะฐ ัััะพะบะธ, ััะพะฑั ะฟะพะปััะธัั ะธั
ะพะฑััั ััะผะผั.",
+ "extractionTypes": {
+ "delimiter": {
+ "description": "ะะฐัััะพะนัะต ัะฐะทะดะตะปะธัะตะปั ัะธัะตะป ะทะดะตัั. (ะะพ ัะผะพะปัะฐะฝะธั ััะพ ัะฐะทััะฒ ัััะพะบะธ.)",
+ "title": "ะ ะฐะทะดะตะปะธัะตะปั ัะธัะตะป"
+ },
+ "smart": {
+ "description": "ะะฒัะพะผะฐัะธัะตัะบะพะต ะพะฟัะตะดะตะปะตะฝะธะต ัะธัั ะฒะพ ะฒั
ะพะดะฝัั
ะดะฐะฝะฝัั
.",
+ "title": "ะฃะผะฝะฐั ััะผะผะฐ"
+ }
+ },
+ "inputTitle": "ะั
ะพะด",
+ "numberExtraction": "ะะทะฒะปะตัะตะฝะธะต ัะธัะตะป",
+ "printRunningSum": "ะะตัะฐัั ัะตะบััะตะน ััะผะผั",
+ "printRunningSumDescription": "ะัะพะฑัะฐะทะธัั ััะผะผั ะฟะพ ะผะตัะต ะตะต ัะฐััะตัะฐ ัะฐะณ ะทะฐ ัะฐะณะพะผ.",
+ "resultTitle": "ะะฑัะธะน",
+ "runningSum": "ะขะตะบััะฐั ััะผะผะฐ",
+ "shortDescription": "ะััะธัะปะธัั ััะผะผั ัะธัะตะป",
+ "title": "ะกัะผะผะฐ",
+ "toolInfo": {
+ "description": "ะญัะพ ะพะฝะปะฐะนะฝ-ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฒััะธัะปะตะฝะธั ััะผะผั ะฝะฐะฑะพัะฐ ัะธัะตะป. ะั ะผะพะถะตัะต ะฒะฒะพะดะธัั ัะธัะปะฐ, ัะฐะทะดะตะปัั ะธั
ะทะฐะฟััะพะน, ะฟัะพะฑะตะปะพะผ ะธะปะธ ะปัะฑัะผ ะดััะณะธะผ ัะธะผะฒะพะปะพะผ, ะฒะบะปััะฐั ะฟะตัะตะฝะพั ัััะพะบะธ. ะั ัะฐะบะถะต ะผะพะถะตัะต ะฟัะพััะพ ะฒััะฐะฒะธัั ััะฐะณะผะตะฝั ัะตะบััะพะฒัั
ะดะฐะฝะฝัั
, ัะพะดะตัะถะฐัะธะน ัะธัะปะพะฒัะต ะทะฝะฐัะตะฝะธั, ะบะพัะพััะต ะฝัะถะฝะพ ะฟัะพััะผะผะธัะพะฒะฐัั, ะธ ััะธะปะธัะฐ ะธะทะฒะปะตัะตั ะธั
ะธ ะฒััะธัะปะธั ััะผะผั.",
+ "title": "ะงัะพ ัะฐะบะพะต ะบะฐะปัะบัะปััะพั ััะผะผั ัะธัะตะป?"
+ }
+ },
+ "voltageDropInWire": {
+ "description": "ะ ะฐัััะธััะฒะฐะตั ะฝะฐะฟััะถะตะฝะธะต ะฒ ะพะฑะพะธั
ะฝะฐะฟัะฐะฒะปะตะฝะธัั
ะธ ะฟะพัะตัะธ ะผะพัะฝะพััะธ ะฒ ะดะฒัั
ะฟัะพะฒะพะดะฝะพะผ ะบะฐะฑะตะปะต.",
+ "longDescription": "ะญัะพั ะบะฐะปัะบัะปััะพั ะฟะพะผะพะณะฐะตั ะพะฟัะตะดะตะปะธัั ะฟะฐะดะตะฝะธะต ะฝะฐะฟััะถะตะฝะธั ะธ ะฟะพัะตัะธ ะผะพัะฝะพััะธ ะฒ ะดะฒัั
ะถะธะปัะฝะพะผ ัะปะตะบััะธัะตัะบะพะผ ะบะฐะฑะตะปะต. ะะฝ ััะธััะฒะฐะตั ะดะปะธะฝั ะบะฐะฑะตะปั, ะฟะปะพัะฐะดั ะฟะพะฟะตัะตัะฝะพะณะพ ัะตัะตะฝะธั ะฟัะพะฒะพะดะพะฒ, ัะดะตะปัะฝะพะต ัะพะฟัะพัะธะฒะปะตะฝะธะต ะผะฐัะตัะธะฐะปะฐ ะธ ัะธะปั ัะพะบะฐ. ะะฝััััะผะตะฝั ัะฐัััะธััะฒะฐะตั ะฟะฐะดะตะฝะธะต ะฝะฐะฟััะถะตะฝะธั ะฒ ะพะฑะพะธั
ะฝะฐะฟัะฐะฒะปะตะฝะธัั
, ะฟะพะปะฝะพะต ัะพะฟัะพัะธะฒะปะตะฝะธะต ะบะฐะฑะตะปั ะธ ะผะพัะฝะพััั, ัะฐััะตะธะฒะฐะตะผัั ะฒ ะฒะธะดะต ัะตะฟะปะฐ. ะญัะพ ะพัะพะฑะตะฝะฝะพ ะฟะพะปะตะทะฝะพ ะดะปั ะธะฝะถะตะฝะตัะพะฒ-ัะปะตะบััะธะบะพะฒ, ัะปะตะบััะธะบะพะฒ ะธ ะปัะฑะธัะตะปะตะน ะฟัะธ ะฟัะพะตะบัะธัะพะฒะฐะฝะธะธ ัะปะตะบััะธัะตัะบะธั
ัะธััะตะผ, ััะพะฑั ะณะฐัะฐะฝัะธัะพะฒะฐัั, ััะพ ััะพะฒะตะฝั ะฝะฐะฟััะถะตะฝะธั ะฝะฐ ะฝะฐะณััะทะบะต ะฑัะดะตั ะฒ ะดะพะฟัััะธะผัั
ะฟัะตะดะตะปะฐั
.",
+ "shortDescription": "ะ ะฐัััะธัะฐัั ะฟะฐะดะตะฝะธะต ะฝะฐะฟััะถะตะฝะธั ะธ ะฟะพัะตัั ะผะพัะฝะพััะธ ะฒ ัะปะตะบััะธัะตัะบะธั
ะบะฐะฑะตะปัั
ะฝะฐ ะพัะฝะพะฒะต ะดะปะธะฝั, ะผะฐัะตัะธะฐะปะฐ ะธ ัะพะบะฐ.",
+ "title": "ะะฐะดะตะฝะธะต ะฝะฐะฟััะถะตะฝะธั ะฒ ะบะฐะฑะตะปะต ะฒ ะพะฑะพะธั
ะฝะฐะฟัะฐะฒะปะตะฝะธัั
"
+ }
+}
diff --git a/public/locales/ru/pdf.json b/public/locales/ru/pdf.json
new file mode 100644
index 0000000..08e9a7d
--- /dev/null
+++ b/public/locales/ru/pdf.json
@@ -0,0 +1,113 @@
+{
+ "compressPdf": {
+ "compressedFileSize": "ะ ะฐะทะผะตั ัะถะฐัะพะณะพ ัะฐะนะปะฐ",
+ "compressingPdf": "ะกะถะฐัะธะต PDF-ัะฐะนะปะฐ...",
+ "compressionLevel": "ะฃัะพะฒะตะฝั ัะถะฐัะธั",
+ "compressionSettings": "ะะฐัััะพะนะบะธ ัะถะฐัะธั",
+ "description": "ะฃะผะตะฝััะธัะต ัะฐะทะผะตั PDF-ัะฐะนะปะฐ, ัะพั
ัะฐะฝะธะฒ ะบะฐัะตััะฒะพ, ั ะฟะพะผะพััั Ghostscript",
+ "errorCompressingPdf": "ะะต ัะดะฐะปะพัั ัะถะฐัั PDF: {{error}}",
+ "errorReadingPdf": "ะะต ัะดะฐะปะพัั ะฟัะพัะธัะฐัั PDF-ัะฐะนะป. ะฃะฑะตะดะธัะตัั, ััะพ ััะพ ะบะพััะตะบัะฝัะน PDF-ัะฐะนะป.",
+ "fileSize": "ะัั
ะพะดะฝัะน ัะฐะทะผะตั ัะฐะนะปะฐ",
+ "highCompression": "ะััะพะบะฐั ััะตะฟะตะฝั ัะถะฐัะธั",
+ "highCompressionDescription": "ะะฐะบัะธะผะฐะปัะฝะพะต ัะผะตะฝััะตะฝะธะต ัะฐะทะผะตัะฐ ัะฐะนะปะฐ ั ะฝะตะบะพัะพัะพะน ะฟะพัะตัะตะน ะบะฐัะตััะฒะฐ",
+ "inputTitle": "ะั
ะพะดะฝะพะน PDF-ัะฐะนะป",
+ "lowCompression": "ะะธะทะบะฐั ะบะพะผะฟัะตััะธั",
+ "lowCompressionDescription": "ะะตะผะฝะพะณะพ ัะผะตะฝััะธัั ัะฐะทะผะตั ัะฐะนะปะฐ ั ะผะธะฝะธะผะฐะปัะฝะพะน ะฟะพัะตัะตะน ะบะฐัะตััะฒะฐ",
+ "mediumCompression": "ะกัะตะดะฝัั ะบะพะผะฟัะตััะธั",
+ "mediumCompressionDescription": "ะะฐะปะฐะฝั ะผะตะถะดั ัะฐะทะผะตัะพะผ ัะฐะนะปะฐ ะธ ะบะฐัะตััะฒะพะผ",
+ "pages": "ะะพะปะธัะตััะฒะพ ัััะฐะฝะธั",
+ "resultTitle": "ะกะถะฐััะน PDF-ัะฐะนะป",
+ "shortDescription": "ะะตะทะพะฟะฐัะฝะพะต ัะถะฐัะธะต PDF-ัะฐะนะปะพะฒ ะฒ ะฒะฐัะตะผ ะฑัะฐัะทะตัะต",
+ "title": "ะกะถะฐัั PDF"
+ },
+ "editor": {
+ "description": "ะ ะฐััะธัะตะฝะฝัะน ัะตะดะฐะบัะพั PDF ั ััะฝะบัะธัะผะธ ะฐะฝะฝะพัะธัะพะฒะฐะฝะธั, ะทะฐะฟะพะปะฝะตะฝะธั ัะพัะผ, ะฒัะดะตะปะตะฝะธั ัะตะบััะฐ ะธ ัะบัะฟะพััะฐ. ะ ะตะดะฐะบัะธััะนัะต PDF-ัะฐะนะปั ะฟััะผะพ ะฒ ะฑัะฐัะทะตัะต ั ะฟะพะผะพััั ะฟัะพัะตััะธะพะฝะฐะปัะฝัั
ะธะฝััััะผะตะฝัะพะฒ, ะฒะบะปััะฐั ะฒััะฐะฒะบั ัะตะบััะฐ, ัะธัะพะฒะฐะฝะธะต, ะฒัะดะตะปะตะฝะธะต ัะตะบััะฐ, ะฟะพะดะฟะธัะฐะฝะธะต ะธ ะทะฐะฟะพะปะฝะตะฝะธะต ัะพัะผ.",
+ "shortDescription": "ะ ะตะดะฐะบัะธััะนัะต PDF-ัะฐะนะปั ั ะฟะพะผะพััั ัะฐััะธัะตะฝะฝัั
ะธะฝััััะผะตะฝัะพะฒ ะฐะฝะฝะพัะธัะพะฒะฐะฝะธั, ะฟะพะดะฟะธัะฐะฝะธั ะธ ัะตะดะฐะบัะธัะพะฒะฐะฝะธั.",
+ "title": "PDF-ัะตะดะฐะบัะพั"
+ },
+ "merge": {
+ "inputTitle": "ะั
ะพะดะฝะพะน PDF-ัะฐะนะป",
+ "loadingText": "ะะทะฒะปะตัะตะฝะธะต ัััะฐะฝะธั",
+ "resultTitle": "ะัะฒะตััะธ ะพะฑัะตะดะธะฝะตะฝะฝัะน PDF-ัะฐะนะป",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะพะฑัะตะดะธะฝะธัั ะฝะตัะบะพะปัะบะพ PDF-ัะฐะนะปะพะฒ ะฒ ะพะดะธะฝ ะดะพะบัะผะตะฝั. ะงัะพะฑั ะฒะพัะฟะพะปัะทะพะฒะฐัััั ะธะฝััััะผะตะฝัะพะผ, ะฟัะพััะพ ะทะฐะณััะทะธัะต PDF-ัะฐะนะปั, ะบะพัะพััะต ะฒั ั
ะพัะธัะต ะพะฑัะตะดะธะฝะธัั. ะะฝััััะผะตะฝั ะพะฑัะตะดะธะฝะธั ะฒัะต ัััะฐะฝะธัั ะธัั
ะพะดะฝัั
ัะฐะนะปะพะฒ ะฒ ะพะดะธะฝ PDF-ะดะพะบัะผะตะฝั.",
+ "title": "ะะฐะบ ะธัะฟะพะปัะทะพะฒะฐัั ะธะฝััััะผะตะฝั ะพะฑัะตะดะธะฝะตะฝะธั PDF-ัะฐะนะปะพะฒ?"
+ }
+ },
+ "mergePdf": {
+ "description": "ะะฑัะตะดะธะฝะธัะต ะฝะตัะบะพะปัะบะพ PDF-ัะฐะนะปะพะฒ ะฒ ะพะดะธะฝ ะดะพะบัะผะตะฝั.",
+ "inputTitle": "ะั
ะพะดะฝัะต PDF-ัะฐะนะปั",
+ "mergingPdfs": "ะะฑัะตะดะธะฝะตะฝะธะต PDF-ัะฐะนะปะพะฒ",
+ "pdfOptions": "ะะฐัะฐะผะตััั PDF-ัะฐะนะปะฐ",
+ "resultTitle": "ะะฑัะตะดะธะฝะตะฝะฝัะน PDF-ัะฐะนะป",
+ "shortDescription": "ะะฑัะตะดะธะฝะธัั ะฝะตัะบะพะปัะบะพ PDF-ัะฐะนะปะพะฒ ะฒ ะพะดะธะฝ ะดะพะบัะผะตะฝั",
+ "sortByFileName": "ะกะพััะธัะพะฒะฐัั ะฟะพ ะธะผะตะฝะธ ัะฐะนะปะฐ",
+ "sortByFileNameDescription": "ะกะพััะธัะพะฒะฐัั PDF-ัะฐะนะปั ะฒ ะฐะปัะฐะฒะธัะฝะพะผ ะฟะพััะดะบะต ะฟะพ ะธะผะตะฝะธ ัะฐะนะปะฐ",
+ "sortByUploadOrder": "ะกะพััะธัะพะฒะฐัั ะฟะพ ะฟะพััะดะบั ะทะฐะณััะทะบะธ",
+ "sortByUploadOrderDescription": "ะกะพั
ัะฐะฝัะนัะต PDF-ัะฐะนะปั ะฒ ัะพะผ ะฟะพััะดะบะต, ะฒ ะบะพัะพัะพะผ ะพะฝะธ ะฑัะปะธ ะทะฐะณััะถะตะฝั.",
+ "title": "ะะฑัะตะดะธะฝะธัั PDF",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะพะฑัะตะดะธะฝะธัั ะฝะตัะบะพะปัะบะพ PDF-ัะฐะนะปะพะฒ ะฒ ะพะดะธะฝ ะดะพะบัะผะตะฝั. ะั ะผะพะถะตัะต ะฒัะฑัะฐัั ัะฟะพัะพะฑ ัะพััะธัะพะฒะบะธ PDF-ัะฐะนะปะพะฒ, ะธ ะธะฝััััะผะตะฝั ะพะฑัะตะดะธะฝะธั ะธั
ะฒ ัะบะฐะทะฐะฝะฝะพะผ ะฟะพััะดะบะต.",
+ "title": "ะะฑัะตะดะธะฝะธัั PDF-ัะฐะนะปั"
+ }
+ },
+ "pdfToEpub": {
+ "description": "ะัะตะพะฑัะฐะทัะนัะต PDF-ะดะพะบัะผะตะฝัั ะฒ ัะฐะนะปั EPUB ะดะปั ะปัััะตะน ัะพะฒะผะตััะธะผะพััะธ ั ัะปะตะบััะพะฝะฝัะผะธ ะบะฝะธะณะฐะผะธ.', icon: 'material-symbols:import-contacts', component: lazy(() => import('./index')), keywords: ['pdf', 'epub', 'convert', 'ebook'], path: 'pdf-to-epub', i18n: { name: 'pdf:pdfToEpub.title', description: 'pdf:pdfToEpub.description",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั PDF-ัะฐะนะปั ะฒ ัะพัะผะฐั EPUB",
+ "title": "PDF ะฒ EPUB"
+ },
+ "pdfToPng": {
+ "description": "ะัะตะพะฑัะฐะทัะนัะต PDF-ะดะพะบัะผะตะฝัั ะฒ ะฟะฐะฝะตะปะธ PNG.",
+ "longDescription": "ะะฐะณััะทะธัะต PDF-ัะฐะนะป ะธ ะฟัะตะพะฑัะฐะทัะนัะต ะบะฐะถะดัั ัััะฐะฝะธัั ะฒ ะฒััะพะบะพะบะฐัะตััะฒะตะฝะฝะพะต ะธะทะพะฑัะฐะถะตะฝะธะต PNG ะฟััะผะพ ะฒ ะฑัะฐัะทะตัะต. ะญัะพั ะธะฝััััะผะตะฝั ะธะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะธะทะฒะปะตัะตะฝะธั ะฒะธะทัะฐะปัะฝะพะณะพ ะบะพะฝัะตะฝัะฐ ะธะปะธ ะฟัะฑะปะธะบะฐัะธะธ ะพัะดะตะปัะฝัั
ัััะฐะฝะธั. ะะฐะณััะทะบะฐ ะดะฐะฝะฝัั
ะฝะต ััะตะฑัะตััั โ ะฒัั ัะฐะฑะพัะฐะตั ะปะพะบะฐะปัะฝะพ.",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั PDF ะฒ ะธะทะพะฑัะฐะถะตะฝะธั PNG",
+ "title": "PDF ะฒ PNG"
+ },
+ "protectPdf": {
+ "description": "ะะพะฑะฐะฒััะต ะฝะฐะดะตะถะฝัั ะทะฐัะธัั ะฟะฐัะพะปะตะผ ะดะปั ะฒะฐัะธั
PDF-ัะฐะนะปะพะฒ ะฒ ะฑัะฐัะทะตัะต.",
+ "shortDescription": "ะะฐะดะตะถะฝะฐั ะทะฐัะธัะฐ ะฟะฐัะพะปะตะผ PDF-ัะฐะนะปะพะฒ",
+ "title": "ะะฐัะธัะธัั PDF-ัะฐะนะป"
+ },
+ "rotatePdf": {
+ "allPagesWillBeRotated": "ะัะต {{count}} ัััะฐะฝะธัั ะฑัะดัั ัะพัะธัะพะฒะฐัััั",
+ "angleOptions": {
+ "clockwise90": "90ยฐ ะฟะพ ัะฐัะพะฒะพะน ัััะตะปะบะต",
+ "counterClockwise270": "270ยฐ (90ยฐ ะฟัะพัะธะฒ ัะฐัะพะฒะพะน ัััะตะปะบะธ)",
+ "upsideDown180": "180ยฐ (ะฒะฒะตัั
ะดะฝะพะผ)"
+ },
+ "applyToAllPages": "ะัะธะผะตะฝะธัั ะบะพ ะฒัะตะผ ัััะฐะฝะธัะฐะผ",
+ "description": "ะะพะฒะพัะพั ัััะฐะฝะธั ะฒ PDF-ะดะพะบัะผะตะฝัะต.",
+ "inputTitle": "ะั
ะพะดะฝะพะน PDF-ัะฐะนะป",
+ "longDescription": "ะะทะผะตะฝะธัะต ะพัะธะตะฝัะฐัะธั ัััะฐะฝะธั PDF-ัะฐะนะปะฐ, ะฟะพะฒะตัะฝัะฒ ะธั
ะฝะฐ 90, 180 ะธะปะธ 270 ะณัะฐะดััะพะฒ. ะญัะพ ะฟะพะปะตะทะฝะพ ะดะปั ะธัะฟัะฐะฒะปะตะฝะธั ะฝะตะฟัะฐะฒะธะปัะฝะพ ะพััะบะฐะฝะธัะพะฒะฐะฝะฝัั
ะดะพะบัะผะตะฝัะพะฒ ะธะปะธ ะฟะพะดะณะพัะพะฒะบะธ PDF-ัะฐะนะปะพะฒ ะบ ะฟะตัะฐัะธ.",
+ "pageRangesDescription": "ะะฒะตะดะธัะต ะฝะพะผะตัะฐ ัััะฐะฝะธั ะธะปะธ ะดะธะฐะฟะฐะทะพะฝั, ัะฐะทะดะตะปะตะฝะฝัะต ะทะฐะฟัััะผะธ (ะฝะฐะฟัะธะผะตั, 1,3,5-7)",
+ "pageRangesPlaceholder": "ะฝะฐะฟัะธะผะตั, 1,5-8",
+ "pagesWillBeRotated": "{{count}} ัััะฐะฝะธัะฐ{{count !== 1 ? 's' : ''}} ะฑัะดะตั ะฒัะฐัะฐัััั",
+ "pdfPageCount": "PDF ะธะผะตะตั {{count}} ัััะฐะฝะธัะฐ{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "ะะพะฒะตัะฝัััะน PDF-ัะฐะนะป",
+ "rotatingPages": "ะ ะพัะฐัะธั ัััะฐะฝะธั",
+ "rotationAngle": "ะฃะณะพะป ะฟะพะฒะพัะพัะฐ",
+ "rotationSettings": "ะะฐัััะพะนะบะธ ะฒัะฐัะตะฝะธั",
+ "shortDescription": "ะะพะฒะพัะพั ัััะฐะฝะธั ะฒ PDF-ะดะพะบัะผะตะฝัะต",
+ "title": "ะะพะฒะตัะฝััั PDF",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะฟะพะฒะพัะฐัะธะฒะฐัั ัััะฐะฝะธัั ะฒ PDF-ะดะพะบัะผะตะฝัะต. ะั ะผะพะถะตัะต ะฟะพะฒะตัะฝััั ะฒัะต ัััะฐะฝะธัั ะธะปะธ ัะบะฐะทะฐัั ะพัะดะตะปัะฝัะต. ะัะฑะตัะธัะต ัะณะพะป ะฟะพะฒะพัะพัะฐ: 90ยฐ ะฟะพ ัะฐัะพะฒะพะน ัััะตะปะบะต, 180ยฐ (ะฒะฒะตัั
ะฝะพะณะฐะผะธ) ะธะปะธ 270ยฐ (ะฝะฐ 90ยฐ ะฟัะพัะธะฒ ัะฐัะพะฒะพะน ัััะตะปะบะธ). ะงัะพะฑั ะฟะพะฒะตัะฝััั ะพัะดะตะปัะฝัะต ัััะฐะฝะธัั, ัะฝะธะผะธัะต ัะปะฐะถะพะบ ยซะัะธะผะตะฝะธัั ะบะพ ะฒัะตะผ ัััะฐะฝะธัะฐะผยป ะธ ะฒะฒะตะดะธัะต ะฝะพะผะตัะฐ ัััะฐะฝะธั ะธะปะธ ะดะธะฐะฟะฐะทะพะฝั ัะตัะตะท ะทะฐะฟัััั (ะฝะฐะฟัะธะผะตั, 1, 3, 5โ7).",
+ "title": "ะะฐะบ ะธัะฟะพะปัะทะพะฒะฐัั ะธะฝััััะผะตะฝั ะฟะพะฒะพัะพัะฐ PDF-ัะฐะนะปะฐ"
+ }
+ },
+ "splitPdf": {
+ "description": "ะะทะฒะปะตัะตะฝะธะต ะพะฟัะตะดะตะปะตะฝะฝัั
ัััะฐะฝะธั ะธะท PDF-ะดะพะบัะผะตะฝัะฐ.",
+ "extractingPages": "ะะทะฒะปะตัะตะฝะธะต ัััะฐะฝะธั",
+ "inputTitle": "ะั
ะพะดะฝะพะน PDF-ัะฐะนะป",
+ "pageExtractionPreview": "{{count}} ัััะฐะฝะธัะฐ{{count !== 1 ? 's' : ''}} ะฑัะดัั ะธะทะฒะปะตัะตะฝั",
+ "pageRangesDescription": "ะะฒะตะดะธัะต ะฝะพะผะตัะฐ ัััะฐะฝะธั ะธะปะธ ะดะธะฐะฟะฐะทะพะฝั, ัะฐะทะดะตะปะตะฝะฝัะต ะทะฐะฟัััะผะธ (ะฝะฐะฟัะธะผะตั, 1,3,5-7)",
+ "pageRangesPlaceholder": "ะฝะฐะฟัะธะผะตั, 1,5-8",
+ "pageSelection": "ะัะฑะพั ัััะฐะฝะธัั",
+ "pdfPageCount": "PDF ะธะผะตะตั {{count}} ัััะฐะฝะธัะฐ{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "ะะทะฒะปะตัะตะฝะฝัะน PDF-ัะฐะนะป",
+ "shortDescription": "ะะทะฒะปะตัั ะพะฟัะตะดะตะปะตะฝะฝัะต ัััะฐะฝะธัั ะธะท PDF-ัะฐะนะปะฐ",
+ "title": "ะ ะฐะทะดะตะปะธัั PDF",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะธะทะฒะปะตะบะฐัั ะพะฟัะตะดะตะปัะฝะฝัะต ัััะฐะฝะธัั ะธะท PDF-ะดะพะบัะผะตะฝัะฐ. ะั ะผะพะถะตัะต ัะบะฐะทะฐัั ะพัะดะตะปัะฝัะต ัััะฐะฝะธัั ะธะปะธ ะดะธะฐะฟะฐะทะพะฝั ัััะฐะฝะธั ะดะปั ะธะทะฒะปะตัะตะฝะธั.",
+ "title": "ะ ะฐะทะดะตะปะธัั PDF"
+ }
+ }
+}
diff --git a/public/locales/ru/string.json b/public/locales/ru/string.json
new file mode 100644
index 0000000..045b074
--- /dev/null
+++ b/public/locales/ru/string.json
@@ -0,0 +1,261 @@
+{
+ "base64": {
+ "decode": "ะะตะบะพะดะธัะพะฒะฐะฝะธะต Base64",
+ "description": "ะะพะดะธัะพะฒะฐัั ะธะปะธ ะดะตะบะพะดะธัะพะฒะฐัั ัะตะบัั ั ะธัะฟะพะปัะทะพะฒะฐะฝะธะตะผ ะบะพะดะธัะพะฒะบะธ Base64.",
+ "encode": "ะะพะดะธัะพะฒะฐะฝะธะต Base64",
+ "inputTitle": "ะั
ะพะดะฝัะต ะดะฐะฝะฝัะต",
+ "optionsTitle": "ะะฐัะฐะผะตััั Base64",
+ "resultTitle": "ะ ะตะทัะปััะฐั",
+ "shortDescription": "ะะพะดะธัะพะฒะฐัั ะธะปะธ ะดะตะบะพะดะธัะพะฒะฐัั ะดะฐะฝะฝัะต ั ะฟะพะผะพััั Base64.",
+ "title": "ะะพะดะธัะพะฒัะธะบ/ะดะตะบะพะดะตั Base64",
+ "toolInfo": {
+ "description": "Base64 โ ััะพ ัั
ะตะผะฐ ะบะพะดะธัะพะฒะฐะฝะธั, ะบะพัะพัะฐั ะฟัะตะดััะฐะฒะปัะตั ะดะฐะฝะฝัะต ะฒ ัะพัะผะฐัะต ASCII-ัััะพะบะธ ะฟัััะผ ะฟะตัะตะฒะพะดะฐ ะธั
ะฒ ัะธััะตะผั ััะธัะปะตะฝะธั ั ะพัะฝะพะฒะฐะฝะธะตะผ 64. ะฅะพัั ะตั ะผะพะถะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั ะดะปั ะบะพะดะธัะพะฒะฐะฝะธั ัััะพะบ, ะพะฝะฐ ะพะฑััะฝะพ ะฟัะธะผะตะฝัะตััั ะดะปั ะบะพะดะธัะพะฒะฐะฝะธั ะดะฒะพะธัะฝัั
ะดะฐะฝะฝัั
ะดะปั ะฟะตัะตะดะฐัะธ ะฟะพ ััะตะดะฐะผ, ะฟัะตะดะฝะฐะทะฝะฐัะตะฝะฝัะผ ะดะปั ัะฐะฑะพัั ั ัะตะบััะพะฒัะผะธ ะดะฐะฝะฝัะผะธ.",
+ "title": "ะงัะพ ัะฐะบะพะต Base64?"
+ }
+ },
+ "censor": {
+ "description": "ะฃัะธะปะธัะฐ ะดะปั ัะตะฝะทััะธัะพะฒะฐะฝะธั ัะปะพะฒ ะฒ ัะตะบััะต. ะะฐะณััะทะธัะต ัะตะบัั ะฒ ัะพัะผั ะฒะฒะพะดะฐ ัะปะตะฒะฐ, ัะบะฐะถะธัะต ะฒัะต ะฝะตัะตะฝะทััะฝัะต ัะปะพะฒะฐ ะฒ ะฟะฐัะฐะผะตััะฐั
, ะธ ะฒั ะผะณะฝะพะฒะตะฝะฝะพ ะฟะพะปััะธัะต ะพััะตะฝะทััะธัะพะฒะฐะฝะฝัะน ัะตะบัั ะฒ ะพะฑะปะฐััะธ ะฒัะฒะพะดะฐ.\", longDescription: 'ะก ะฟะพะผะพััั ััะพะณะพ ะพะฝะปะฐะนะฝ-ะธะฝััััะผะตะฝัะฐ ะฒั ะผะพะถะตัะต ะพััะตะฝะทััะธัะพะฒะฐัั ะพะฟัะตะดะตะปัะฝะฝัะต ัะปะพะฒะฐ ะฒ ะปัะฑะพะผ ัะตะบััะต. ะั ะผะพะถะตัะต ัะบะฐะทะฐัั ัะฟะธัะพะบ ะฝะตะถะตะปะฐัะตะปัะฝัั
ัะปะพะฒ (ะฝะฐะฟัะธะผะตั, ััะณะฐัะตะปัััะฒ ะธะปะธ ัะตะบัะตัะฝัั
ัะปะพะฒ), ะธ ะฟัะพะณัะฐะผะผะฐ ะทะฐะผะตะฝะธั ะธั
ะฐะปััะตัะฝะฐัะธะฒะฝัะผะธ ัะปะพะฒะฐะผะธ ะธ ัะพะทะดะฐัั ะฑะตะทะพะฟะฐัะฝัะน ะดะปั ััะตะฝะธั ัะตะบัั. ะกะปะพะฒะฐ ะผะพะถะฝะพ ัะบะฐะทะฐัั ะฒ ะผะฝะพะณะพัััะพัะฝะพะผ ัะตะบััะพะฒะพะผ ะฟะพะปะต ะฒ ะฟะฐัะฐะผะตััะฐั
, ะฒะฒะพะดั ะฟะพ ะพะดะฝะพะผั ัะปะพะฒั ะฝะฐ ัััะพะบั.', keywords: ['text', 'censor', 'words', 'characters'], component: lazy(() => import('./index')), i18n: { name: 'string:censor.title', description: 'string:censor.description",
+ "shortDescription": "ะััััะพ ะผะฐัะบะธััะนัะต ะฟะปะพั
ะธะต ัะปะพะฒะฐ ะธะปะธ ะทะฐะผะตะฝัะนัะต ะธั
ะดััะณะธะผะธ ัะปะพะฒะฐะผะธ.",
+ "title": "ะขะตะบััะพะฒัะน ัะตะฝะทะพั"
+ },
+ "createPalindrome": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ัะพะทะดะฐะฝะธั ะฟะฐะปะธะฝะดัะพะผะพะฒ ะธะท ะปัะฑะพะณะพ ัะตะบััะฐ. ะะฒะตะดะธัะต ัะตะบัั ะธ ะผะณะฝะพะฒะตะฝะฝะพ ะฟัะตะพะฑัะฐะทัะนัะต ะตะณะพ ะฒ ะฟะฐะปะธะฝะดัะพะผ, ะบะพัะพััะน ัะธัะฐะตััั ะพะดะธะฝะฐะบะพะฒะพ ัะปะตะฒะฐ ะฝะฐะฟัะฐะฒะพ ะธ ัะฟัะฐะฒะฐ ะฝะฐะปะตะฒะพ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะปะพะฒะตัะฝัั
ะธะณั, ัะพะทะดะฐะฝะธั ัะธะผะผะตััะธัะฝัั
ัะตะบััะพะฒัั
ัะทะพัะพะฒ ะธะปะธ ะธะทััะตะฝะธั ะปะธะฝะณะฒะธััะธัะตัะบะธั
ะดะธะบะพะฒะธะฝะพะบ.",
+ "shortDescription": "ะกะพะทะดะฐะนัะต ัะตะบัั, ะบะพัะพััะน ะพะดะธะฝะฐะบะพะฒะพ ัะธัะฐะตััั ะบะฐะบ ัะปะตะฒะฐ ะฝะฐะฟัะฐะฒะพ, ัะฐะบ ะธ ัะปะตะฒะฐ ะฝะฐะฟัะฐะฒะพ.",
+ "title": "ะกะพะทะดะฐัั ะฟะฐะปะธะฝะดัะพะผ"
+ },
+ "extractSubstring": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะธะทะฒะปะตัะตะฝะธั ะฟะพะดัััะพะบ ะธะท ัะตะบััะฐ. ะะฒะตะดะธัะต ัะตะบัั ะธ ัะบะฐะถะธัะต ะฝะฐัะฐะปัะฝัั ะธ ะบะพะฝะตัะฝัั ะฟะพะทะธัะธะธ, ััะพะฑั ะธะทะฒะปะตัั ะฝัะถะฝัั ัะฐััั. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะพะฑัะฐะฑะพัะบะธ ะดะฐะฝะฝัั
, ะฐะฝะฐะปะธะทะฐ ัะตะบััะฐ ะธะปะธ ะธะทะฒะปะตัะตะฝะธั ะพะฟัะตะดะตะปัะฝะฝะพะณะพ ะบะพะฝัะตะฝัะฐ ะธะท ะฑะพะปััะธั
ัะตะบััะพะฒัั
ะฑะปะพะบะพะฒ.",
+ "shortDescription": "ะะทะฒะปะตัั ัะฐััั ัะตะบััะฐ ะผะตะถะดั ัะบะฐะทะฐะฝะฝัะผะธ ะฟะพะทะธัะธัะผะธ",
+ "title": "ะะทะฒะปะตัั ะฟะพะดัััะพะบั"
+ },
+ "join": {
+ "blankLinesAndTrailingSpaces": "ะััััะต ัััะพะบะธ ะธ ะบะพะฝะตัะฝัะต ะฟัะพะฑะตะปั",
+ "deleteBlankDescription": "ะฃะดะฐะปะธัะต ัััะพะบะธ, ะฝะต ัะพะดะตัะถะฐัะธะต ัะตะบััะพะฒัั
ัะธะผะฒะพะปะพะฒ.",
+ "deleteBlankTitle": "ะฃะดะฐะปะธัั ะฟััััะต ัััะพะบะธ",
+ "deleteTrailingDescription": "ะฃะดะฐะปะธัะต ะฟัะพะฑะตะปั ะธ ะทะฝะฐะบะธ ัะฐะฑัะปััะธะธ ะฒ ะบะพะฝัะต ัััะพะบ.",
+ "deleteTrailingTitle": "ะฃะดะฐะปะธัั ะบะพะฝะตัะฝัะต ะฟัะพะฑะตะปั",
+ "description": "ะะฑัะตะดะธะฝัะนัะต ััะฐะณะผะตะฝัั ัะตะบััะฐ ั ะฟะพะผะพััั ะฝะฐัััะฐะธะฒะฐะตะผัั
ัะฐะทะดะตะปะธัะตะปะตะน.",
+ "inputTitle": "ะขะตะบััะพะฒัะต ััะฐะณะผะตะฝัั",
+ "joinCharacterDescription": "ะกะธะผะฒะพะป, ัะพะตะดะธะฝัััะธะน ัะฐะทัะพะทะฝะตะฝะฝัะต ััะฐะณะผะตะฝัั ัะตะบััะฐ. (ะัะพะฑะตะป ะฟะพ ัะผะพะปัะฐะฝะธั.)",
+ "joinCharacterPlaceholder": "ะัะธัะพะตะดะธะฝะธัััั ะบ ะฟะตััะพะฝะฐะถั",
+ "resultTitle": "ะะฑัะตะดะธะฝะตะฝะฝัะน ัะตะบัั",
+ "shortDescription": "ะะฑัะตะดะธะฝะธัั ัะตะบััะพะฒัะต ัะปะตะผะตะฝัั ั ัะบะฐะทะฐะฝะฝัะผ ัะฐะทะดะตะปะธัะตะปะตะผ",
+ "textMergedOptions": "ะะฐัะฐะผะตััั ะพะฑัะตะดะธะฝะตะฝะธั ัะตะบััะฐ",
+ "title": "ะัะธัะพะตะดะธะฝะธัััั ะบ ัะตะบััั",
+ "toolInfo": {
+ "description": "ะก ะฟะพะผะพััั ััะพะณะพ ะธะฝััััะผะตะฝัะฐ ะผะพะถะฝะพ ะพะฑัะตะดะธะฝะธัั ัะฐััะธ ัะตะบััะฐ. ะะฝ ะฑะตััั ัะฟะธัะพะบ ัะตะบััะพะฒัั
ะทะฝะฐัะตะฝะธะน, ัะฐะทะดะตะปัะฝะฝัั
ัะธะผะฒะพะปะฐะผะธ ะฟะตัะตะฝะพัะฐ ัััะพะบะธ, ะธ ะพะฑัะตะดะธะฝัะตั ะธั
. ะั ะผะพะถะตัะต ะทะฐะดะฐัั ัะธะผะฒะพะป, ะบะพัะพััะน ะฑัะดะตั ะฒััะฐะฒะปะตะฝ ะผะตะถะดั ัะฐัััะผะธ ะพะฑัะตะดะธะฝัะฝะฝะพะณะพ ัะตะบััะฐ. ะัะพะผะต ัะพะณะพ, ะผะพะถะฝะพ ะธะณะฝะพัะธัะพะฒะฐัั ะฒัะต ะฟััััะต ัััะพะบะธ ะธ ัะดะฐะปััั ะฟัะพะฑะตะปั ะธ ัะฐะฑัะปััะธะธ ะฒ ะบะพะฝัะต ะฒัะตั
ัััะพะบ. ะขะตะบัััะฐะปัะฝะพ!",
+ "title": "ะงัะพ ัะฐะบะพะต ััะตะดััะฒะพ ะพะฑัะตะดะธะฝะตะฝะธั ัะตะบััะพะฒ?"
+ }
+ },
+ "palindrome": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฟัะพะฒะตัะบะธ ัะตะบััะฐ ะฝะฐ ะฟะฐะปะธะฝะดัะพะผ. ะะณะฝะพะฒะตะฝะฝะพ ะฟัะพะฒะตััะตั, ะพะดะธะฝะฐะบะพะฒะพ ะปะธ ัะธัะฐะตััั ัะตะบัั ัะปะตะฒะฐ ะฝะฐะฟัะฐะฒะพ ะธ ัะฟัะฐะฒะฐ ะฝะฐะปะตะฒะพ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะตัะตะฝะธั ัะปะพะฒะตัะฝัั
ะณะพะปะพะฒะพะปะพะผะพะบ, ะปะธะฝะณะฒะธััะธัะตัะบะพะณะพ ะฐะฝะฐะปะธะทะฐ ะธ ะฟัะพะฒะตัะบะธ ัะธะผะผะตััะธัะฝะพััะธ ัะตะบััะพะฒัั
ัะฐะฑะปะพะฝะพะฒ. ะะพะดะดะตัะถะธะฒะฐะตั ัะฐะทะปะธัะฝัะต ัะฐะทะดะตะปะธัะตะปะธ ะธ ะพะฟัะตะดะตะปะตะฝะธะต ะฟะฐะปะธะฝะดัะพะผะพะฒ ะธะท ะฝะตัะบะพะปัะบะธั
ัะปะพะฒ.",
+ "shortDescription": "ะัะพะฒะตัััะต, ัะธัะฐะตััั ะปะธ ัะตะบัั ะพะดะธะฝะฐะบะพะฒะพ ะฒ ะฟััะผะพะผ ะธ ะพะฑัะฐัะฝะพะผ ะฝะฐะฟัะฐะฒะปะตะฝะธะธ.",
+ "title": "ะะฐะปะธะฝะดัะพะผ"
+ },
+ "passwordGenerator": {
+ "avoidAmbiguous": "ะะทะฑะตะณะฐะนัะต ะฝะตะพะดะฝะพะทะฝะฐัะฝัั
ัะธะผะฒะพะปะพะฒ (i, I, l, 0, O)",
+ "description": "ะกะพะทะดะฐะฒะฐะนัะต ะฝะฐะดัะถะฝัะต ัะปััะฐะนะฝัะต ะฟะฐัะพะปะธ ั ะฝะฐัััะฐะธะฒะฐะตะผะพะน ะดะปะธะฝะพะน ะธ ัะธะฟะพะผ ัะธะผะฒะพะปะพะฒ. ะัะฑะธัะฐะนัะต ัััะพัะฝัะต, ะทะฐะณะปะฐะฒะฝัะต, ัะธััั ะธ ัะฟะตัะธะฐะปัะฝัะต ัะธะผะฒะพะปั. ะะพะทะผะพะถะฝะพััั ะธัะบะปััะธัั ะฝะตะพะดะฝะพะทะฝะฐัะฝัะต ัะธะผะฒะพะปั ะดะปั ะปัััะตะน ัะธัะฐะตะผะพััะธ.",
+ "includeLowercase": "ะะบะปััะฐัั ัััะพัะฝัะต ะฑัะบะฒั (aโz)",
+ "includeNumbers": "ะะบะปััะธัั ัะธััั (0-9)",
+ "includeSymbols": "ะะบะปััะธัั ัะฟะตัะธะฐะปัะฝัะต ัะธะผะฒะพะปั",
+ "includeUppercase": "ะะบะปััะฐะนัะต ะทะฐะณะปะฐะฒะฝัะต ะฑัะบะฒั (AโZ)",
+ "lengthDesc": "ะะปะธะฝะฐ ะฟะฐัะพะปั",
+ "lengthPlaceholder": "ะฝะฐะฟัะธะผะตั, 12",
+ "optionsTitle": "ะะฐัะฐะผะตััั ะฟะฐัะพะปั",
+ "resultTitle": "ะกะณะตะฝะตัะธัะพะฒะฐะฝะฝัะน ะฟะฐัะพะปั",
+ "shortDescription": "ะะตะฝะตัะธััะนัะต ะฑะตะทะพะฟะฐัะฝัะต ัะปััะฐะนะฝัะต ะฟะฐัะพะปะธ ั ะฟะพะผะพััั ะฟะพะปัะทะพะฒะฐัะตะปััะบะธั
ะฟะฐัะฐะผะตััะพะฒ",
+ "title": "ะะตะฝะตัะฐัะพั ะฟะฐัะพะปะตะน",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะณะตะฝะตัะธััะตั ะฝะฐะดัะถะฝัะต ัะปััะฐะนะฝัะต ะฟะฐัะพะปะธ ะฝะฐ ะพัะฝะพะฒะต ะฒัะฑัะฐะฝะฝัั
ะฒะฐะผะธ ะบัะธัะตัะธะตะฒ. ะั ะผะพะถะตัะต ะฝะฐัััะพะธัั ะดะปะธะฝั, ะฒะบะปััะฐัั ะธะปะธ ะธัะบะปััะฐัั ัะฐะทะปะธัะฝัะต ัะธะฟั ัะธะผะฒะพะปะพะฒ, ะฐ ัะฐะบะถะต ะธะทะฑะตะณะฐัั ะฝะตะพะดะฝะพะทะฝะฐัะฝัั
ัะธะผะฒะพะปะพะฒ ะดะปั ะปัััะตะน ัะธัะฐะตะผะพััะธ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะพะทะดะฐะฝะธั ะฝะฐะดัะถะฝัั
ะฟะฐัะพะปะตะน ะดะปั ััััะฝัั
ะทะฐะฟะธัะตะน, ะฟัะธะปะพะถะตะฝะธะน ะธ ะปัะฑัั
ะดััะณะธั
ะทะฐะดะฐั ะฑะตะทะพะฟะฐัะฝะพััะธ.",
+ "title": "ะ ะณะตะฝะตัะฐัะพัะต ะฟะฐัะพะปะตะน"
+ }
+ },
+ "quote": {
+ "allowDoubleQuotation": "ะ ะฐะทัะตัะธัั ะดะฒะพะนะฝัะต ะบะฐะฒััะบะธ",
+ "description": "ะะพะฑะฐะฒะปัะนัะต ะบะฐะฒััะบะธ ะฒะพะบััะณ ัะตะบััะฐ ั ะฟะพะผะพััั ะฝะฐัััะฐะธะฒะฐะตะผัั
ะฟะฐัะฐะผะตััะพะฒ.",
+ "inputTitle": "ะะฒะตะดะธัะต ัะตะบัั",
+ "leftQuoteDescription": "ะกะธะผะฒะพะป(ั) ะปะตะฒะพะน ะบะฐะฒััะบะธ",
+ "processAsMultiLine": "ะะฑัะฐะฑะฐััะฒะฐัั ะบะฐะบ ะผะฝะพะณะพัััะพัะฝัะน ัะตะบัั",
+ "quoteEmptyLines": "ะฆะธัะธัะพะฒะฐัั ะฟััััะต ัััะพะบะธ",
+ "quoteOptions": "ะะฐัะธะฐะฝัั ัะฐััะตะฝะพะบ",
+ "resultTitle": "ะฆะธัะธััะตะผัะน ัะตะบัั",
+ "rightQuoteDescription": "ะกะธะผะฒะพะป(ั) ะฟัะฐะฒะพะน ะบะฐะฒััะบะธ",
+ "shortDescription": "ะะพะฑะฐะฒะปัะนัะต ะบะฐะฒััะบะธ ะฒะพะบััะณ ัะตะบััะฐ ั ะธัะฟะพะปัะทะพะฒะฐะฝะธะตะผ ัะฐะทะปะธัะฝัั
ััะธะปะตะน",
+ "title": "ะฆะธัะฐัะฐ ะธะท ัะตะบััะฐ",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะดะพะฑะฐะฒะปััั ะบะฐะฒััะบะธ ะบ ัะตะบััั. ะั ะผะพะถะตัะต ะฒัะฑะธัะฐัั ัะฐะทะปะธัะฝัะต ัะธะผะฒะพะปั ะบะฐะฒััะตะบ, ัะฐะฑะพัะฐัั ั ะผะฝะพะณะพัััะพัะฝัะผ ัะตะบััะพะผ ะธ ัะฟัะฐะฒะปััั ะพะฑัะฐะฑะพัะบะพะน ะฟััััั
ัััะพะบ. ะะฝ ะฟะพะปะตะทะตะฝ ะดะปั ะฟะพะดะณะพัะพะฒะบะธ ัะตะบััะฐ ะบ ะฟัะพะณัะฐะผะผะธัะพะฒะฐะฝะธั, ัะพัะผะฐัะธัะพะฒะฐะฝะธั ะดะฐะฝะฝัั
ะธะปะธ ัะพะทะดะฐะฝะธั ััะธะปะธะทะพะฒะฐะฝะฝะพะณะพ ัะตะบััะฐ.",
+ "title": "ะฆะธัะฐัะฐ ะธะท ัะตะบััะฐ"
+ }
+ },
+ "randomizeCase": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ัะปััะฐะนะฝะพะณะพ ะธะทะผะตะฝะตะฝะธั ัะตะณะธัััะฐ ัะตะบััะฐ. ะะฒะตะดะธัะต ัะตะบัั ะธ ะผะณะฝะพะฒะตะฝะฝะพ ะฟัะตะพะฑัะฐะทัะนัะต ะตะณะพ, ะธัะฟะพะปัะทัั ัะปััะฐะนะฝัะต ะทะฐะณะปะฐะฒะฝัะต ะธ ัััะพัะฝัะต ะฑัะบะฒั. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะพะทะดะฐะฝะธั ัะฝะธะบะฐะปัะฝัั
ัะตะบััะพะฒัั
ัััะตะบัะพะฒ, ะฟัะพะฒะตัะบะธ ััะฒััะฒะธัะตะปัะฝะพััะธ ะบ ัะตะณะธัััั ะธะปะธ ะณะตะฝะตัะฐัะธะธ ัะฐะทะปะธัะฝัั
ัะตะบััะพะฒัั
ัะฐะฑะปะพะฝะพะฒ.",
+ "shortDescription": "ะกะปััะฐะนะฝัะน ัะตะณะธััั ะฑัะบะฒ ะฒ ัะตะบััะต",
+ "title": "ะ ะฐะฝะดะพะผะธะทะธัะพะฒะฐัั ัะปััะฐะน"
+ },
+ "removeDuplicateLines": {
+ "description": "ะะฐะณััะทะธัะต ัะตะบัั ะฒ ัะพัะผั ะฒะฒะพะดะฐ ัะปะตะฒะฐ, ะธ ะฒั ะผะณะฝะพะฒะตะฝะฝะพ ะฟะพะปััะธัะต ัะตะบัั ะฑะตะท ะดัะฑะปะธะบะฐัะพะฒ ัััะพะบ ะฒ ะพะฑะปะฐััะธ ะฒัะฒะพะดะฐ. ะะพัะฝัะน, ะฑะตัะฟะปะฐัะฝัะน ะธ ะฑัััััะน ะธะฝััััะผะตะฝั. ะะฐะณััะทะธัะต ัะตะบััะพะฒัะต ัััะพะบะธ โ ะฟะพะปััะธัะต ัะฝะธะบะฐะปัะฝัะต ัะตะบััะพะฒัะต ัััะพะบะธ.",
+ "shortDescription": "ะััััะพ ัะดะฐะปะธัั ะฒัะต ะฟะพะฒัะพััััะธะตัั ัััะพะบะธ ะธะท ัะตะบััะฐ",
+ "title": "ะฃะดะฐะปะธัั ะดัะฑะปะธะบะฐัั ัััะพะบ"
+ },
+ "repeat": {
+ "delimiterDescription": "ะ ะฐะทะดะตะปะธัะตะปั ะดะปั ะฒัั
ะพะดะฝัั
ะบะพะฟะธะน.",
+ "delimiterPlaceholder": "ะ ะฐะทะดะตะปะธัะตะปั",
+ "description": "ะะพะฒัะพััะนัะต ัะตะบัั ะฝะตัะบะพะปัะบะพ ัะฐะท ั ะฝะฐัััะฐะธะฒะฐะตะผัะผะธ ัะฐะทะดะตะปะธัะตะปัะผะธ.",
+ "inputTitle": "ะะฒะตะดะธัะต ัะตะบัั",
+ "numberPlaceholder": "ะงะธัะปะพ",
+ "repeatAmountDescription": "ะะพะปะธัะตััะฒะพ ะฟะพะฒัะพัะตะฝะธะน.",
+ "repetitionsDelimiter": "ะ ะฐะทะดะตะปะธัะตะปั ะฟะพะฒัะพัะตะฝะธะน",
+ "resultTitle": "ะะพะฒัะพััััะธะนัั ัะตะบัั",
+ "shortDescription": "ะะพะฒัะพัะธัั ัะตะบัั ะฝะตัะบะพะปัะบะพ ัะฐะท",
+ "textRepetitions": "ะะพะฒัะพัั ัะตะบััะฐ",
+ "title": "ะะพะฒัะพัะธัั ัะตะบัั",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะฟะพะฒัะพัััั ะทะฐะดะฐะฝะฝัะน ัะตะบัั ะฝะตัะบะพะปัะบะพ ัะฐะท ั ะดะพะฟะพะปะฝะธัะตะปัะฝัะผ ัะฐะทะดะตะปะธัะตะปะตะผ.",
+ "title": "ะะพะฒัะพัะธัั ัะตะบัั"
+ }
+ },
+ "reverse": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฟะตัะตะฒะพัะพัะฐ ัะตะบััะฐ. ะะฒะตะดะธัะต ะปัะฑะพะน ัะตะบัั, ะธ ะพะฝ ะผะณะฝะพะฒะตะฝะฝะพ ะฟะตัะตะฒะตัะฝัััั, ัะธะผะฒะพะป ะทะฐ ัะธะผะฒะพะปะพะผ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะพะทะดะฐะฝะธั ะทะตัะบะฐะปัะฝะพะณะพ ัะตะบััะฐ, ะฐะฝะฐะปะธะทะฐ ะฟะฐะปะธะฝะดัะพะผะพะฒ ะธ ัะบัะฟะตัะธะผะตะฝัะพะฒ ั ัะตะบััะพะฒัะผะธ ัะฐะฑะปะพะฝะฐะผะธ. ะกะพั
ัะฐะฝัะตั ะฟัะพะฑะตะปั ะธ ัะฟะตัะธะฐะปัะฝัะต ัะธะผะฒะพะปั ะฟัะธ ะฟะตัะตะฒะพัะพัะต.",
+ "inputTitle": "ะขะตะบัั ะดะปั ะฟะตัะตะฒะพัะพัะฐ",
+ "processMultiLine": "ะะฑัะฐะฑะพัะบะฐ ะผะฝะพะณะพัััะพัะฝะพะณะพ ัะตะบััะฐ",
+ "processMultiLineDescription": "ะะฐะถะดะฐั ัััะพะบะฐ ะฑัะดะตั ะฟะตัะตะฒะตัะฝััะฐ ะฝะตะทะฐะฒะธัะธะผะพ",
+ "resultTitle": "ะะตัะตะฒะตัะฝัััะน ัะตะบัั",
+ "reversalOptions": "ะะฐัะธะฐะฝัั ะพัะผะตะฝั",
+ "shortDescription": "ะะตัะตะฒะตัะฝััั ะปัะฑะพะน ัะตะบัั ะฟะพัะธะผะฒะพะปัะฝะพ",
+ "skipEmptyLines": "ะัะพะฟััะบะฐัั ะฟััััะต ัััะพะบะธ",
+ "skipEmptyLinesDescription": "ะััััะต ัััะพะบะธ ะฑัะดัั ัะดะฐะปะตะฝั ะธะท ะฒัะฒะพะดะฐ.",
+ "title": "ะะฑะตัะฟะตัะธัั ัะตะณัะตัั",
+ "trimWhitespace": "ะะฑัะตะทะฐัั ะฟัะพะฑะตะปั",
+ "trimWhitespaceDescription": "ะฃะดะฐะปะธัั ะฝะฐัะฐะปัะฝัะต ะธ ะบะพะฝะตัะฝัะต ะฟัะพะฑะตะปั ะธะท ะบะฐะถะดะพะน ัััะพะบะธ."
+ },
+ "rot13": {
+ "description": "ะะพะดะธัะพะฒะฐัั ะธะปะธ ะดะตะบะพะดะธัะพะฒะฐัั ัะตะบัั ั ะฟะพะผะพััั ัะธััะฐ ROT13.",
+ "inputTitle": "ะะฒะตะดะธัะต ัะตะบัั",
+ "resultTitle": "ะ ะตะทัะปััะฐั ROT13",
+ "shortDescription": "ะะพะดะธัะพะฒะฐัั ะธะปะธ ะดะตะบะพะดะธัะพะฒะฐัั ัะตะบัั ั ะฟะพะผะพััั ัะธััะฐ ROT13.",
+ "title": "ะะพะดะตั/ะดะตะบะพะดะตั ROT13",
+ "toolInfo": {
+ "description": "ROT13 (ะฟะพะฒะพัะพั ะฝะฐ 13 ะฟะพะทะธัะธะน) โ ััะพ ะฟัะพััะพะน ัะธัั ะทะฐะผะตะฝั ะฑัะบะฒ, ะบะพัะพััะน ะทะฐะผะตะฝัะตั ะฑัะบะฒั ะฝะฐ 13-ั ะฑัะบะฒั ะฟะพัะปะต ะฝะตั ะฒ ะฐะปัะฐะฒะธัะต. ROT13 โ ััะพ ะพัะพะฑัะน ัะปััะฐะน ัะธััะฐ ะฆะตะทะฐัั, ัะฐะทัะฐะฑะพัะฐะฝะฝะพะณะพ ะฒ ะัะตะฒะฝะตะผ ะ ะธะผะต. ะะพัะบะพะปัะบั ะฒ ะฐะฝะณะปะธะนัะบะพะผ ะฐะปัะฐะฒะธัะต 26 ะฑัะบะฒ, ROT13 ัะฒะปัะตััั ัะฒะพะธะผ ัะพะฑััะฒะตะฝะฝัะผ ะธะฝะฒะตััะธะตะน; ัะพ ะตััั ะดะปั ะพัะผะตะฝั ROT13 ะฟัะธะผะตะฝัะตััั ัะพั ะถะต ะฐะปะณะพัะธัะผ, ะฟะพััะพะผั ะพะดะฝะพ ะธ ัะพ ะถะต ะดะตะนััะฒะธะต ะผะพะถะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั ะดะปั ะบะพะดะธัะพะฒะฐะฝะธั ะธ ะดะตะบะพะดะธัะพะฒะฐะฝะธั.",
+ "title": "ะงัะพ ัะฐะบะพะต ROT13?"
+ }
+ },
+ "rotate": {
+ "description": "ะะพะฒะตัะฝััั ัะธะผะฒะพะปั ะฒ ัะตะบััะต ะฝะฐ ัะบะฐะทะฐะฝะฝัะต ะฟะพะทะธัะธะธ.",
+ "inputTitle": "ะะฒะตะดะธัะต ัะตะบัั",
+ "processAsMultiLine": "ะะฑัะฐะฑะฐััะฒะฐัั ะบะฐะบ ะผะฝะพะณะพัััะพัะฝัะน ัะตะบัั (ะฟะพะฒะพัะฐัะธะฒะฐัั ะบะฐะถะดัั ัััะพะบั ะพัะดะตะปัะฝะพ)",
+ "resultTitle": "ะะพะฒะตัะฝัััะน ัะตะบัั",
+ "rotateLeft": "ะะพะฒะตัะฝััั ะฒะปะตะฒะพ",
+ "rotateRight": "ะะพะฒะตัะฝััั ะฒะฟัะฐะฒะพ",
+ "rotationOptions": "ะะฐัะฐะผะตััั ะฒัะฐัะตะฝะธั",
+ "shortDescription": "ะกะดะฒะธะณ ัะธะผะฒะพะปะพะฒ ะฒ ัะตะบััะต ะฟะพ ะฟะพะทะธัะธะธ.",
+ "stepDescription": "ะะพะปะธัะตััะฒะพ ะฟะพะทะธัะธะน ะดะปั ะฟะพะฒะพัะพัะฐ",
+ "title": "ะะพะฒะตัะฝััั ัะตะบัั",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะฟะพะฒะพัะฐัะธะฒะฐัั ัะธะผะฒะพะปั ะฒ ัััะพะบะต ะฝะฐ ะทะฐะดะฐะฝะฝะพะต ะบะพะปะธัะตััะฒะพ ะฟะพะทะธัะธะน. ะั ะผะพะถะตัะต ะฟะพะฒะพัะฐัะธะฒะฐัั ัะธะผะฒะพะปั ะฒะปะตะฒะพ ะธะปะธ ะฒะฟัะฐะฒะพ, ะฐ ัะฐะบะถะต ะพะฑัะฐะฑะฐััะฒะฐัั ะผะฝะพะณะพัััะพัะฝัะน ัะตะบัั, ะฟะพะฒะพัะฐัะธะฒะฐั ะบะฐะถะดัั ัััะพะบั ะพัะดะตะปัะฝะพ. ะะพะฒะพัะพั ัััะพะบ ะฟะพะปะตะทะตะฝ ะดะปั ะฟัะพัััั
ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธะน ัะตะบััะฐ, ัะพะทะดะฐะฝะธั ัะฐะฑะปะพะฝะพะฒ ะธะปะธ ัะตะฐะปะธะทะฐัะธะธ ะฑะฐะทะพะฒัั
ะผะตัะพะดะพะฒ ัะธััะพะฒะฐะฝะธั.",
+ "title": "ะัะฐัะตะฝะธะต ััััะฝั"
+ }
+ },
+ "split": {
+ "charAfterChunkDescription": "ะกะธะผะฒะพะป ะฟะพัะปะต ะบะฐะถะดะพะณะพ ััะฐะณะผะตะฝัะฐ",
+ "charBeforeChunkDescription": "ะกะธะผะฒะพะป ะฟะตัะตะด ะบะฐะถะดัะผ ััะฐะณะผะตะฝัะพะผ",
+ "chunksDescription": "ะะพะปะธัะตััะฒะพ ััะฐะณะผะตะฝัะพะฒ ะพะดะธะฝะฐะบะพะฒะพะน ะดะปะธะฝั ะฝะฐ ะฒัั
ะพะดะต.",
+ "chunksTitle": "ะัะฟะพะปัะทัะนัะต ะฝะตัะบะพะปัะบะพ ััะฐะณะผะตะฝัะพะฒ",
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ัะฐะทะดะตะปะตะฝะธั ัะตะบััะฐ. ะะฒะตะดะธัะต ัะตะบัั ะธ ัะบะฐะถะธัะต ัะฐะทะดะตะปะธัะตะปั, ััะพะฑั ัะฐะทะดะตะปะธัั ะตะณะพ ะฝะฐ ะฝะตัะบะพะปัะบะพ ัะฐััะตะน. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะพะฑัะฐะฑะพัะบะธ ะดะฐะฝะฝัั
, ัะฐะฑะพัั ั ัะตะบััะพะผ ะธะปะธ ะธะทะฒะปะตัะตะฝะธั ะพะฟัะตะดะตะปัะฝะฝะพะณะพ ะบะพะฝัะตะฝัะฐ ะธะท ะฑะพะปััะธั
ัะตะบััะพะฒัั
ะฑะปะพะบะพะฒ.",
+ "lengthDescription": "ะะพะปะธัะตััะฒะพ ัะธะผะฒะพะปะพะฒ, ะบะพัะพััะต ะฑัะดัั ะฟะพะผะตัะตะฝั ะฒ ะบะฐะถะดัะน ะฒัั
ะพะดะฝะพะน ััะฐะณะผะตะฝั.",
+ "lengthTitle": "ะัะฟะพะปัะทะพะฒะฐัั ะดะปะธะฝั ะดะปั ัะฐะทะดะตะปะตะฝะธั",
+ "outputSeparatorDescription": "ะกะธะผะฒะพะป, ะบะพัะพััะน ะฑัะดะตั ะฒััะฐะฒะปะตะฝ ะผะตะถะดั ัะฐะทะดะตะปัะฝะฝัะผะธ ััะฐะณะผะตะฝัะฐะผะธ.\n(ะะพ ัะผะพะปัะฐะฝะธั ััะพ ัะธะผะฒะพะป ะฝะพะฒะพะน ัััะพะบะธ \"\\n\".)",
+ "outputSeparatorOptions": "ะะฐัะฐะผะตััั ัะฐะทะดะตะปะธัะตะปั ะฒัะฒะพะดะฐ",
+ "regexDescription": "ะ ะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต, ะบะพัะพัะพะต ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัััั ะดะปั ัะฐะทะฑะธะตะฝะธั ัะตะบััะฐ ะฝะฐ ัะฐััะธ.\n(ะะพ ัะผะพะปัะฐะฝะธั ะฝะตัะบะพะปัะบะพ ะฟัะพะฑะตะปะพะฒ.)",
+ "regexTitle": "ะัะฟะพะปัะทัะนัะต ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต ะดะปั ัะฐะทะดะตะปะตะฝะธั",
+ "resultTitle": "ะขะตะบััะพะฒัะต ััะฐะณะผะตะฝัั",
+ "shortDescription": "ะ ะฐะทะดะตะปะธัั ัะตะบัั ะฝะฐ ะฝะตัะบะพะปัะบะพ ัะฐััะตะน ั ะฟะพะผะพััั ัะฐะทะดะตะปะธัะตะปั",
+ "splitSeparatorOptions": "ะะฐัะฐะผะตััั ัะฐะทะดะตะปะธัะตะปั ัะฐะทะดะตะปะธัะตะปะตะน",
+ "symbolDescription": "ะกะธะผะฒะพะป, ะบะพัะพััะน ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัััั ะดะปั ัะฐะทะฑะธะตะฝะธั ัะตะบััะฐ ะฝะฐ ัะฐััะธ.\n(ะัะพะฑะตะป ะฟะพ ัะผะพะปัะฐะฝะธั.)",
+ "symbolTitle": "ะัะฟะพะปัะทัะนัะต ัะธะผะฒะพะป ะดะปั ัะฐะทะดะตะปะตะฝะธั",
+ "title": "ะ ะฐัะบะพะปะพัั"
+ },
+ "statistic": {
+ "characterFrequencyAnalysis": "ะะฝะฐะปะธะท ัะฐััะพัั ัะธะผะฒะพะปะพะฒ",
+ "characterFrequencyAnalysisDescription": "ะะพะดััะธัะฐะนัะต, ะบะฐะบ ัะฐััะพ ะบะฐะถะดัะน ัะธะผะฒะพะป ะฒัััะตัะฐะตััั ะฒ ัะตะบััะต.",
+ "delimitersOptions": "ะะฐัะฐะผะตััั ัะฐะทะดะตะปะธัะตะปะตะน",
+ "description": "ะะฝะฐะปะธะทะธััะนัะต ัะตะบัั ะธ ัะพะทะดะฐะฒะฐะนัะต ะบะพะผะฟะปะตะบัะฝัั ััะฐัะธััะธะบั.",
+ "includeEmptyLines": "ะะบะปััะธัั ะฟััััะต ัััะพะบะธ",
+ "includeEmptyLinesDescription": "ะัะธ ะฟะพะดััะตัะต ัััะพะบ ััะธััะฒะฐะนัะต ะฟััััะต ัััะพะบะธ.",
+ "inputTitle": "ะะฒะตะดะธัะต ัะตะบัั",
+ "resultTitle": "ะกัะฐัะธััะธะบะฐ ัะตะบััะฐ",
+ "sentenceDelimitersDescription": "ะะฒะตะดะธัะต ะฟะพะปัะทะพะฒะฐัะตะปััะบะธะต ัะธะผะฒะพะปั, ะธัะฟะพะปัะทัะตะผัะต ะดะปั ัะฐะทะดะตะปะตะฝะธั ะฟัะตะดะปะพะถะตะฝะธะน ะฝะฐ ะฒะฐัะตะผ ัะทัะบะต (ัะตัะตะท ะทะฐะฟัััั), ะธะปะธ ะพััะฐะฒััะต ะฟะพะปะต ะฟััััะผ, ััะพะฑั ะธัะฟะพะปัะทะพะฒะฐัั ะทะฝะฐัะตะฝะธะต ะฟะพ ัะผะพะปัะฐะฝะธั.",
+ "sentenceDelimitersPlaceholder": "ะฝะฐะฟัะธะผะตั, ., !, ?, ...",
+ "shortDescription": "ะะพะปััะธัะต ััะฐัะธััะธะบั ะพ ะฒะฐัะตะผ ัะตะบััะต",
+ "statisticsOptions": "ะะฐัะฐะผะตััั ััะฐัะธััะธะบะธ",
+ "title": "ะกัะฐัะธััะธะบะฐ ัะตะบััะฐ",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะฐะฝะฐะปะธะทะธัะพะฒะฐัั ัะตะบัั ะธ ะณะตะฝะตัะธัะพะฒะฐัั ะบะพะผะฟะปะตะบัะฝัั ััะฐัะธััะธะบั, ะฒะบะปััะฐั ะบะพะปะธัะตััะฒะพ ัะธะผะฒะพะปะพะฒ, ะบะพะปะธัะตััะฒะพ ัะปะพะฒ, ะบะพะปะธัะตััะฒะพ ัััะพะบ, ะฐ ัะฐะบะถะต ะฐะฝะฐะปะธะท ัะฐััะพัั ัะธะผะฒะพะปะพะฒ ะธ ัะปะพะฒ.",
+ "title": "ะงัะพ ัะฐะบะพะต {{title}}?"
+ },
+ "wordDelimitersDescription": "ะะฒะตะดะธัะต ะฟะพะปัะทะพะฒะฐัะตะปััะบะพะต ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต ะดะปั ะฟะพะดััะตัะฐ ัะปะพะฒ ะธะปะธ ะพััะฐะฒััะต ะฟะพะปะต ะฟััััะผ ะดะปั ะธัะฟะพะปัะทะพะฒะฐะฝะธั ะฟะพ ัะผะพะปัะฐะฝะธั.",
+ "wordDelimitersPlaceholder": "ะฝะฐะฟั. \\s.,;:!?\"ยซยป()โฆ",
+ "wordFrequencyAnalysis": "ะะฝะฐะปะธะท ัะฐััะพัั ัะปะพะฒ",
+ "wordFrequencyAnalysisDescription": "ะะพะดััะธัะฐะนัะต, ะบะฐะบ ัะฐััะพ ะบะฐะถะดะพะต ัะปะพะฒะพ ะฒัััะตัะฐะตััั ะฒ ัะตะบััะต."
+ },
+ "textReplacer": {
+ "description": "ะะฐะผะตะฝะธัะต ัะตะบััะพะฒัะต ัะฐะฑะปะพะฝั ะฝะพะฒัะผ ัะพะดะตัะถะฐะฝะธะตะผ.",
+ "findPatternInText": "ะะฐะนัะธ ััะพั ัะฐะฑะปะพะฝ ะฒ ัะตะบััะต",
+ "findPatternUsingRegexp": "ะะฐะนะดะธัะต ัะฐะฑะปะพะฝ ั ะฟะพะผะพััั ัะตะณัะปััะฝะพะณะพ ะฒััะฐะถะตะฝะธั",
+ "inputTitle": "ะขะตะบัั ะดะปั ะทะฐะผะตะฝั",
+ "newTextPlaceholder": "ะะพะฒัะน ัะตะบัั",
+ "regexpDescription": "ะะฒะตะดะธัะต ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต, ะบะพัะพัะพะต ะฒั ั
ะพัะธัะต ะทะฐะผะตะฝะธัั.",
+ "replacePatternDescription": "ะะฒะตะดะธัะต ัะฐะฑะปะพะฝ, ะบะพัะพััะน ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัััั ะดะปั ะทะฐะผะตะฝั.",
+ "replaceText": "ะะฐะผะตะฝะธัั ัะตะบัั",
+ "resultTitle": "ะขะตะบัั ั ะทะฐะผะตะฝะฐะผะธ",
+ "searchPatternDescription": "ะะฒะตะดะธัะต ัะตะบััะพะฒัะน ัะฐะฑะปะพะฝ, ะบะพัะพััะน ะฒั ั
ะพัะธัะต ะทะฐะผะตะฝะธัั.",
+ "searchText": "ะะพะธัะบ ัะตะบััะฐ",
+ "shortDescription": "ะััััะพ ะทะฐะผะตะฝัะนัะต ัะตะบัั ะฒ ะฒะฐัะตะผ ะบะพะฝัะตะฝัะต",
+ "title": "ะะฐะผะตะฝะธัะตะปั ัะตะบััะฐ",
+ "toolInfo": {
+ "description": "ะะตะณะบะพ ะทะฐะผะตะฝัะนัะต ัะตะบัั ะฒ ะฒะฐัะตะผ ะบะพะฝัะตะฝัะต ั ะฟะพะผะพััั ััะพะณะพ ะฟัะพััะพะณะพ ะฑัะฐัะทะตัะฝะพะณะพ ะธะฝััััะผะตะฝัะฐ. ะัะพััะพ ะฒะฒะตะดะธัะต ัะตะบัั, ัะบะฐะถะธัะต ัะตะบัั, ะบะพัะพััะน ั
ะพัะธัะต ะทะฐะผะตะฝะธัั, ะธ ะทะฝะฐัะตะฝะธะต ะดะปั ะทะฐะผะตะฝั, ะธ ะผะณะฝะพะฒะตะฝะฝะพ ะฟะพะปััะธัะต ะพะฑะฝะพะฒะปัะฝะฝัั ะฒะตััะธั.",
+ "title": "ะะฐะผะตะฝะธัะตะปั ัะตะบััะฐ"
+ }
+ },
+ "toMorse": {
+ "dashSymbolDescription": "ะกะธะผะฒะพะป, ะบะพัะพััะน ะฑัะดะตั ัะพะพัะฒะตัััะฒะพะฒะฐัั ัะธัะต ะฒ ะฐะทะฑัะบะต ะะพัะทะต.",
+ "description": "ะัะตะพะฑัะฐะทะพะฒะฐัั ัะตะบัั ะฒ ะฐะทะฑัะบั ะะพัะทะต.",
+ "dotSymbolDescription": "ะกะธะผะฒะพะป, ะบะพัะพััะน ะฑัะดะตั ัะพะพัะฒะตัััะฒะพะฒะฐัั ัะพัะบะต ะฒ ะฐะทะฑัะบะต ะะพัะทะต.",
+ "longSignal": "ะะปะธะฝะฝัะน ัะธะณะฝะฐะป",
+ "resultTitle": "ะฐะทะฑัะบะฐ ะะพัะทะต",
+ "shortDescription": "ะััััะพะต ะบะพะดะธัะพะฒะฐะฝะธะต ัะตะบััะฐ ะฒ ะฐะทะฑัะบั ะะพัะทะต",
+ "shortSignal": "ะะพัะพัะบะธะน ัะธะณะฝะฐะป",
+ "title": "ะกััะพะบะฐ ะฒ ะฐะทะฑัะบะต ะะพัะทะต"
+ },
+ "truncate": {
+ "addTruncationIndicator": "ะะพะฑะฐะฒะธัั ะธะฝะดะธะบะฐัะพั ััะตัะตะฝะธั",
+ "charactersPlaceholder": "ะะตััะพะฝะฐะถะธ",
+ "description": "ะกะพะบัะฐัะธัั ัะตะบัั ะดะพ ัะบะฐะทะฐะฝะฝะพะน ะดะปะธะฝั.",
+ "indicatorDescription": "ะกะธะผะฒะพะปั, ะดะพะฑะฐะฒะปัะตะผัะต ะฒ ะบะพะฝะตั (ะธะปะธ ะฝะฐัะฐะปะพ) ัะตะบััะฐ. ะัะธะผะตัะฐะฝะธะต: ะพะฝะธ ััะธััะฒะฐัััั ะฟัะธ ะฟะพะดััััะต ะดะปะธะฝั.",
+ "inputTitle": "ะะฒะตะดะธัะต ัะตะบัั",
+ "leftSideDescription": "ะฃะดะฐะปะธัั ัะธะผะฒะพะปั ะธะท ะฝะฐัะฐะปะฐ ัะตะบััะฐ.",
+ "leftSideTruncation": "ะฃัะตัะตะฝะธะต ัะปะตะฒะฐ",
+ "lengthAndLines": "ะะปะธะฝะฐ ะธ ะปะธะฝะธะธ",
+ "lineByLineDescription": "ะะฑัะตะทะฐะนัะต ะบะฐะถะดัั ัััะพะบั ะพัะดะตะปัะฝะพ.",
+ "lineByLineTruncating": "ะะพัััะพัะฝะพะต ััะตัะตะฝะธะต",
+ "maxLengthDescription": "ะะพะปะธัะตััะฒะพ ัะธะผะฒะพะปะพะฒ, ะบะพัะพัะพะต ะฝัะถะฝะพ ะพััะฐะฒะธัั ะฒ ัะตะบััะต.",
+ "numberPlaceholder": "ะงะธัะปะพ",
+ "resultTitle": "ะฃัะตัะตะฝะฝัะน ัะตะบัั",
+ "rightSideDescription": "ะฃะดะฐะปะธัั ัะธะผะฒะพะปั ะธะท ะบะพะฝัะฐ ัะตะบััะฐ.",
+ "rightSideTruncation": "ะัะฐะฒะพััะพัะพะฝะฝะตะต ััะตัะตะฝะธะต",
+ "shortDescription": "ะะฑัะตะทะฐัั ัะตะบัั ะดะพ ัะบะฐะทะฐะฝะฝะพะน ะดะปะธะฝั",
+ "suffixAndAffix": "ะกัััะธะบั ะธ ะฐััะธะบั",
+ "title": "ะะฑัะตะทะฐัั ัะตะบัั",
+ "toolInfo": {
+ "description": "ะะฐะณััะทะธัะต ัะตะบัั ะฒ ัะพัะผั ะฒะฒะพะดะฐ ัะปะตะฒะฐ, ะธ ัะฟัะฐะฒะฐ ะฒั ะฐะฒัะพะผะฐัะธัะตัะบะธ ะฟะพะปััะธัะต ะพะฑัะตะทะฐะฝะฝัะน ัะตะบัั.",
+ "title": "ะะฑัะตะทะฐัั ัะตะบัั"
+ },
+ "truncationSide": "ะกัะพัะพะฝะฐ ััะตัะตะฝะธั"
+ },
+ "uppercase": {
+ "description": "ะัะตะพะฑัะฐะทะพะฒะฐัั ัะตะบัั ะฒ ะทะฐะณะปะฐะฒะฝัะต ะฑัะบะฒั.",
+ "inputTitle": "ะะฒะตะดะธัะต ัะตะบัั",
+ "resultTitle": "ะขะตะบัั ะทะฐะณะปะฐะฒะฝัะผะธ ะฑัะบะฒะฐะผะธ",
+ "shortDescription": "ะัะตะพะฑัะฐะทะพะฒะฐัั ัะตะบัั ะฒ ะฒะตัั
ะฝะธะน ัะตะณะธััั",
+ "title": "ะัะตะพะฑัะฐะทะพะฒะฐัั ะฒ ะฒะตัั
ะฝะธะน ัะตะณะธััั"
+ }
+}
diff --git a/public/locales/ru/time.json b/public/locales/ru/time.json
new file mode 100644
index 0000000..835422c
--- /dev/null
+++ b/public/locales/ru/time.json
@@ -0,0 +1,100 @@
+{
+ "checkLeapYears": {
+ "description": "ะัะพะฒะตัััะต, ัะฒะปัะตััั ะปะธ ะณะพะด ะฒะธัะพะบะพัะฝัะผ, ะธ ะฟะพะปััะธัะต ะธะฝัะพัะผะฐัะธั ะพ ะฒะธัะพะบะพัะฝะพะผ ะณะพะดะต.",
+ "inputTitle": "ะะฒะตะดะธัะต ะณะพะด",
+ "resultTitle": "ะ ะตะทัะปััะฐั ะฒะธัะพะบะพัะฝะพะณะพ ะณะพะดะฐ",
+ "shortDescription": "ะัะพะฒะตัััะต, ัะฒะปัะตััั ะปะธ ะณะพะด ะฒะธัะพะบะพัะฝัะผ",
+ "title": "ะัะพะฒะตัััะต ะฒะธัะพะบะพัะฝัะต ะณะพะดั",
+ "toolInfo": {
+ "description": "ะะธัะพะบะพัะฝัะน ะณะพะด โ ััะพ ะณะพะด, ัะพะดะตัะถะฐัะธะน ะพะดะธะฝ ะดะพะฟะพะปะฝะธัะตะปัะฝัะน ะดะตะฝั (29 ัะตะฒัะฐะปั) ะดะปั ัะธะฝั
ัะพะฝะธะทะฐัะธะธ ะบะฐะปะตะฝะดะฐัะฝะพะณะพ ะณะพะดะฐ ั ะฐัััะพะฝะพะผะธัะตัะบะธะผ ะณะพะดะพะผ. ะะธัะพะบะพัะฝัะต ะณะพะดั ะฟัะพะธัั
ะพะดัั ะบะฐะถะดัะต 4 ะณะพะดะฐ, ะทะฐ ะธัะบะปััะตะฝะธะตะผ ัะตั
, ะบะพัะพััะต ะดะตะปัััั ะฝะฐ 100, ะฝะพ ะฝะต ะดะตะปัััั ะฝะฐ 400.",
+ "title": "ะงัะพ ัะฐะบะพะต ะฒะธัะพะบะพัะฝัะน ะณะพะด?"
+ }
+ },
+ "convertDaysToHours": {
+ "addHoursName": "ะะพะฑะฐะฒะธัั ัะฐัั ะะผั",
+ "addHoursNameDescription": "ะะพะฑะฐะฒะธัั ัััะพะบั ัะฐัะพะฒ ะบ ะฒัั
ะพะดะฝัะผ ะทะฝะฐัะตะฝะธัะผ",
+ "description": "ะะพะฝะฒะตััะธััะนัะต ะดะฝะธ ะฒ ัะฐัั ั ะฟะพะผะพััั ะฝะฐัััะฐะธะฒะฐะตะผัั
ะฟะฐัะฐะผะตััะพะฒ.",
+ "hoursName": "ะงะฐัั ะะผั",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั ะดะฝะธ ะฒ ัะฐัั",
+ "title": "ะะพะฝะฒะตััะธัะพะฒะฐัั ะดะฝะธ ะฒ ัะฐัั",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะฟัะตะพะฑัะฐะทะพะฒัะฒะฐัั ะดะฝะธ ะฒ ัะฐัั. ะั ะผะพะถะตัะต ะฒะฒะตััะธ ะดะฝะธ ะฒ ะฒะธะดะต ัะธัะตะป ะธะปะธ ะตะดะธะฝะธั ะธะทะผะตัะตะฝะธั, ะธ ะธะฝััััะผะตะฝั ะฟัะตะพะฑัะฐะทัะตั ะธั
ะฒ ัะฐัั. ะั ัะฐะบะถะต ะผะพะถะตัะต ะดะพะฑะฐะฒะธัั ััััะธะบั ยซัะฐััยป ะบ ะฒัั
ะพะดะฝัะผ ะทะฝะฐัะตะฝะธัะผ.",
+ "title": "ะะพะฝะฒะตััะธัะพะฒะฐัั ะดะฝะธ ะฒ ัะฐัั"
+ }
+ },
+ "convertHoursToDays": {
+ "addDaysName": "ะะพะฑะฐะฒะธัั ะฝะฐะทะฒะฐะฝะธะต ะดะฝั",
+ "addDaysNameDescription": "ะะพะฑะฐะฒะธัั ัััะพะบั days ะบ ะฒัั
ะพะดะฝัะผ ะทะฝะฐัะตะฝะธัะผ",
+ "daysName": "ะะผั ะดะฝั",
+ "description": "ะะพะฝะฒะตััะธััะนัะต ัะฐัั ะฒ ะดะฝะธ ั ะฟะพะผะพััั ะฝะฐัััะฐะธะฒะฐะตะผัั
ะฟะฐัะฐะผะตััะพะฒ.",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั ัะฐัั ะฒ ะดะฝะธ",
+ "title": "ะะพะฝะฒะตััะธัะพะฒะฐัั ัะฐัั ะฒ ะดะฝะธ",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะบะพะฝะฒะตััะธัะพะฒะฐัั ัะฐัั ะฒ ะดะฝะธ. ะั ะผะพะถะตัะต ะฒะฒะตััะธ ัะฐัั ะฒ ะฒะธะดะต ัะธัะตะป ะธะปะธ ะตะดะธะฝะธั ะธะทะผะตัะตะฝะธั, ะธ ะธะฝััััะผะตะฝั ะบะพะฝะฒะตััะธััะตั ะธั
ะฒ ะดะฝะธ. ะั ัะฐะบะถะต ะผะพะถะตัะต ะดะพะฑะฐะฒะธัั ััััะธะบั ยซะดะฝะธยป ะบ ะฒัั
ะพะดะฝัะผ ะทะฝะฐัะตะฝะธัะผ.",
+ "title": "ะะพะฝะฒะตััะธัะพะฒะฐัั ัะฐัั ะฒ ะดะฝะธ"
+ }
+ },
+ "convertSecondsToTime": {
+ "addPadding": "ะะพะฑะฐะฒะธัั ะพััััะฟ",
+ "addPaddingDescription": "ะะพะฑะฐะฒััะต ะฝัะปะธ ะบ ัะฐัะฐะผ, ะผะธะฝััะฐะผ ะธ ัะตะบัะฝะดะฐะผ.",
+ "description": "ะะตัะตะฒะพะด ัะตะบัะฝะด ะฒ ัะดะพะฑะฝัะน ะดะปั ััะตะฝะธั ัะพัะผะฐั ะฒัะตะผะตะฝะธ (ัะฐัั:ะผะธะฝััั:ัะตะบัะฝะดั). ะะฒะตะดะธัะต ะบะพะปะธัะตััะฒะพ ัะตะบัะฝะด, ััะพะฑั ะฟะพะปััะธัั ะพััะพัะผะฐัะธัะพะฒะฐะฝะฝะพะต ะฒัะตะผั.",
+ "shortDescription": "ะัะตะพะฑัะฐะทะพะฒะฐัั ัะตะบัะฝะดั ะฒ ัะพัะผะฐั ะฒัะตะผะตะฝะธ",
+ "timePadding": "ะะฐะฟะพะปะฝะตะฝะธะต ะฒัะตะผะตะฝะธ",
+ "title": "ะะตัะตะฒะตััะธ ัะตะบัะฝะดั ะฒะพ ะฒัะตะผั",
+ "toolInfo": {
+ "title": "ะงัะพ ัะฐะบะพะต {{title}}?"
+ }
+ },
+ "convertTimeToSeconds": {
+ "description": "ะัะตะพะฑัะฐะทะพะฒะฐัั ัะพัะผะฐัะธัะพะฒะฐะฝะฝะพะต ะฒัะตะผั (ะงะง:ะะ:ะกะก) ะฒ ัะตะบัะฝะดั.",
+ "inputTitle": "ะัะตะผั ะฒะฒะพะดะฐ",
+ "resultTitle": "ะกะตะบัะฝะดั",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั ัะพัะผะฐั ะฒัะตะผะตะฝะธ ะฒ ัะตะบัะฝะดั",
+ "title": "ะะตัะตะฒะตััะธ ะฒัะตะผั ะฒ ัะตะบัะฝะดั",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะฟัะตะพะฑัะฐะทะพะฒัะฒะฐัั ัะพัะผะฐัะธัะพะฒะฐะฝะฝัะต ัััะพะบะธ ะฒัะตะผะตะฝะธ (ะงะง:ะะ:ะกะก) ะฒ ัะตะบัะฝะดั. ะะฝ ะฟะพะปะตะทะตะฝ ะดะปั ัะฐััััะฐ ะดะปะธัะตะปัะฝะพััะตะน ะธ ะฒัะตะผะตะฝะฝัั
ะธะฝัะตัะฒะฐะปะพะฒ.",
+ "title": "ะะตัะตะฒะตััะธ ะฒัะตะผั ะฒ ัะตะบัะฝะดั"
+ }
+ },
+ "crontabGuru": {
+ "description": "ะะตะฝะตัะธััะนัะต ะธ ะฐะฝะฐะปะธะทะธััะนัะต ะฒััะฐะถะตะฝะธั cron. ะกะพะทะดะฐะฒะฐะนัะต ัะฐัะฟะธัะฐะฝะธั cron ะดะปั ะฐะฒัะพะผะฐัะธะทะธัะพะฒะฐะฝะฝัั
ะทะฐะดะฐั ะธ ัะธััะตะผะฝัั
ะทะฐะดะฐะฝะธะน.",
+ "shortDescription": "ะะตะฝะตัะฐัะธั ะธ ะฟะพะฝะธะผะฐะฝะธะต ะฒััะฐะถะตะฝะธะน cron",
+ "title": "Crontab ะััั"
+ },
+ "timeBetweenDates": {
+ "description": "ะ ะฐัััะธัะฐะนัะต ัะฐะทะฝะธัั ะฒะพ ะฒัะตะผะตะฝะธ ะผะตะถะดั ะดะฒัะผั ะดะฐัะฐะผะธ. ะะพะปััะธัะต ัะพัะฝัั ะฟัะพะดะพะปะถะธัะตะปัะฝะพััั ะฒ ะดะฝัั
, ัะฐัะฐั
, ะผะธะฝััะฐั
ะธ ัะตะบัะฝะดะฐั
.",
+ "endDate": "ะะฐัะฐ ะพะบะพะฝัะฐะฝะธั",
+ "endDateTime": "ะะฐัะฐ ะธ ะฒัะตะผั ะพะบะพะฝัะฐะฝะธั",
+ "endTime": "ะะพะฝะตั ะัะตะผะตะฝะธ",
+ "endTimezone": "ะะพะฝะตัะฝัะน ัะฐัะพะฒะพะน ะฟะพัั",
+ "shortDescription": "ะ ะฐัััะธัะฐัั ะฒัะตะผั ะผะตะถะดั ะดะฒัะผั ะดะฐัะฐะผะธ",
+ "startDate": "ะะฐัะฐ ะฝะฐัะฐะปะฐ",
+ "startDateTime": "ะะฐัะฐ ะธ ะฒัะตะผั ะฝะฐัะฐะปะฐ",
+ "startTime": "ะัะตะผั ะฝะฐัะฐะปะฐ",
+ "startTimezone": "ะะฐัะฐะปัะฝัะน ัะฐัะพะฒะพะน ะฟะพัั",
+ "title": "ะัะตะผั ะผะตะถะดั ะดะฐัะฐะผะธ",
+ "toolInfo": {
+ "description": "ะ ะฐัััะธัะฐะนัะต ัะพัะฝัั ัะฐะทะฝะธัั ะฒะพ ะฒัะตะผะตะฝะธ ะผะตะถะดั ะดะฒัะผั ะดะฐัะฐะผะธ ะธ ะฒัะตะผะตะฝะตะผ ั ะฟะพะดะดะตัะถะบะพะน ัะฐะทะฝัั
ัะฐัะพะฒัั
ะฟะพััะพะฒ. ะญัะพั ะธะฝััััะผะตะฝั ะฟัะตะดะพััะฐะฒะปัะตั ะฟะพะดัะพะฑะฝัั ะธะฝัะพัะผะฐัะธั ะพ ัะฐะทะฝะธัะต ะฒะพ ะฒัะตะผะตะฝะธ ะฒ ัะฐะทะปะธัะฝัั
ะตะดะธะฝะธัะฐั
(ะณะพะดั, ะผะตัััั, ะดะฝะธ, ัะฐัั, ะผะธะฝััั ะธ ัะตะบัะฝะดั).",
+ "title": "ะะฐะปัะบัะปััะพั ะฒัะตะผะตะฝะธ ะผะตะถะดั ะดะฐัะฐะผะธ"
+ }
+ },
+ "truncateClockTime": {
+ "description": "ะะบััะณะปะธัะต ะฒัะตะผั ะดะพ ะฑะปะธะถะฐะนัะตะณะพ ัะฐัะฐ, ะผะธะฝััั ะธะปะธ ะทะฐะดะฐะฝะฝะพะณะพ ะฒะฐะผะธ ะธะฝัะตัะฒะฐะปะฐ.",
+ "printDroppedComponents": "ะะตัะฐัั ัะดะฐะปะตะฝะฝัั
ะบะพะผะฟะพะฝะตะฝัะพะฒ",
+ "shortDescription": "ะฃัะตัะตะฝะธะต ะฒัะตะผะตะฝะธ ะดะพ ะทะฐะดะฐะฝะฝะพะน ัะพัะฝะพััะธ",
+ "timePadding": "ะะฐะฟะพะปะฝะตะฝะธะต ะฒัะตะผะตะฝะธ",
+ "title": "ะฃัะตัะตะฝะธะต ะฒัะตะผะตะฝะธ ะฝะฐ ัะฐัะฐั
",
+ "toolInfo": {
+ "title": "ะงัะพ ัะฐะบะพะต {{title}}?"
+ },
+ "truncateMinutesAndSeconds": "ะฃัะตัะตะฝะธะต ะผะธะฝัั ะธ ัะตะบัะฝะด",
+ "truncateMinutesAndSecondsDescription": "ะัะฑัะพัััะต ะพะฑะต ัะพััะฐะฒะปัััะธะต โ ะผะธะฝััั ะธ ัะตะบัะฝะดั โ ะธะท ะบะฐะถะดะพะณะพ ะฒัะตะผะตะฝะธ.",
+ "truncateOnlySeconds": "ะกะพะบัะฐัะธัั ัะพะปัะบะพ ัะตะบัะฝะดั",
+ "truncateOnlySecondsDescription": "ะัะฑัะพัััะต ัะตะบัะฝะดะฝัั ัะพััะฐะฒะปััััั ะธะท ะบะฐะถะดะพะณะพ ะฟะพะบะฐะทะฐะฝะธั ัะฐัะพะฒ.",
+ "truncationSide": "ะกัะพัะพะฝะฐ ััะตัะตะฝะธั",
+ "useZeroPadding": "ะัะฟะพะปัะทะพะฒะฐัั ะฝัะปะตะฒะพะต ะทะฐะฟะพะปะฝะตะฝะธะต",
+ "zeroPaddingDescription": "ะกะดะตะปะฐะนัะต ัะฐะบ, ััะพะฑั ะฒัะต ะบะพะผะฟะพะฝะตะฝัั ะฒัะตะผะตะฝะธ ะฒัะตะณะดะฐ ะฑัะปะธ ะดะฒัะทะฝะฐัะฝัะผะธ.",
+ "zeroPrintDescription": "ะัะพะฑัะฐะทะธัั ะพัะฑัะพัะตะฝะฝัะต ัะฐััะธ ะบะฐะบ ะฝัะปะตะฒัะต ะทะฝะฐัะตะฝะธั ยซ00ยป.",
+ "zeroPrintTruncatedParts": "ะฃัะตัะตะฝะฝัะต ะดะตัะฐะปะธ ั ะฝัะปะตะฒะพะน ะฟะตัะฐััั"
+ }
+}
diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json
new file mode 100644
index 0000000..d537f8f
--- /dev/null
+++ b/public/locales/ru/translation.json
@@ -0,0 +1,250 @@
+{
+ "audio": {
+ "changeSpeed": {
+ "description": "ะะทะผะตะฝะธัะต ัะบะพัะพััั ะฒะพัะฟัะพะธะทะฒะตะดะตะฝะธั ะฐัะดะธะพัะฐะนะปะพะฒ. ะฃัะบะพัััะต ะธะปะธ ะทะฐะผะตะดะปะธัะต ะทะฒัะบ, ัะพั
ัะฐะฝัั ะฒััะพัั ะทะฒัะบะฐ.",
+ "name": "ะะทะผะตะฝะธัั ัะบะพัะพััั ะทะฒัะบะฐ",
+ "shortDescription": "ะะทะผะตะฝะธัั ัะบะพัะพััั ะฐัะดะธะพัะฐะนะปะพะฒ"
+ },
+ "extractAudio": {
+ "description": "ะะทะฒะปะตะบะธัะต ะทะฒัะบะพะฒัั ะดะพัะพะถะบั ะธะท ะฒะธะดะตะพัะฐะนะปะฐ ะธ ัะพั
ัะฐะฝะธัะต ะตะต ะบะฐะบ ะพัะดะตะปัะฝัะน ะฐัะดะธะพัะฐะนะป ะฒ ะฒัะฑัะฐะฝะฝะพะผ ะฒะฐะผะธ ัะพัะผะฐัะต (AAC, MP3, WAV).",
+ "name": "ะะทะฒะปะตัั ะฐัะดะธะพ",
+ "shortDescription": "ะะทะฒะปะตะบะฐะนัะต ะฐัะดะธะพ ะธะท ะฒะธะดะตะพัะฐะนะปะพะฒ (MP4, MOV ะธ ั. ะด.) ะฒ ัะพัะผะฐัั AAC, MP3 ะธะปะธ WAV."
+ }
+ },
+ "baseFileInput": {
+ "copyFailed": "ะะต ัะดะฐะปะพัั ัะบะพะฟะธัะพะฒะฐัั: {{error}}",
+ "dropFileHere": "ะััะฐะฒััะต ัะฒะพะน {{type}} ะทะดะตัั",
+ "fileCopied": "ะคะฐะนะป ัะบะพะฟะธัะพะฒะฐะฝ",
+ "selectFileDescription": "ะะฐะถะผะธัะต ะทะดะตัั, ััะพะฑั ะฒัะฑัะฐัั {{type}} ั ะฒะฐัะตะณะพ ััััะพะนััะฒะฐ ะฝะฐะถะผะธัะต Ctrl+V, ััะพะฑั ะธัะฟะพะปัะทะพะฒะฐัั {{type}} ะธะท ะฑััะตัะฐ ะพะฑะผะตะฝะฐ ะธะปะธ ะฟะตัะตัะฐัะธัะต ัะฐะนะป ั ัะฐะฑะพัะตะณะพ ััะพะปะฐ"
+ },
+ "categories": {
+ "audio": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ัะพ ะทะฒัะบะพะผ โ ะธะทะฒะปะตัะตะฝะธะต ะทะฒัะบะฐ ะธะท ะฒะธะดะตะพ, ัะตะณัะปะธัะพะฒะบะฐ ัะบะพัะพััะธ ะทะฒัะบะฐ, ะพะฑัะตะดะธะฝะตะฝะธะต ะฝะตัะบะพะปัะบะธั
ะฐัะดะธะพัะฐะนะปะพะฒ ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "ะัะดะธะพ ะธะฝััััะผะตะฝัั"
+ },
+ "csv": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ั CSV-ัะฐะนะปะฐะผะธ โ ะบะพะฝะฒะตััะธััะนัะต CSV ะฒ ัะฐะทะปะธัะฝัะต ัะพัะผะฐัั, ะพะฑัะฐะฑะฐััะฒะฐะนัะต CSV-ะดะฐะฝะฝัะต, ะฟัะพะฒะตััะนัะต ััััะบัััั CSV ะธ ัััะตะบัะธะฒะฝะพ ะพะฑัะฐะฑะฐััะฒะฐะนัะต CSV-ัะฐะนะปั.",
+ "title": "CSV-ะธะฝััััะผะตะฝัั"
+ },
+ "gif": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ั GIF-ะฐะฝะธะผะฐัะธะตะน โ ัะพะทะดะฐะฝะธะต ะฟัะพะทัะฐัะฝัั
GIF-ัะฐะนะปะพะฒ, ะธะทะฒะปะตัะตะฝะธะต GIF-ะบะฐะดัะพะฒ, ะดะพะฑะฐะฒะปะตะฝะธะต ัะตะบััะฐ ะฒ GIF-ัะฐะนะปั, ะพะฑัะตะทะบะฐ, ะฟะพะฒะพัะพั, ะพะฑัะฐัะฝะพะต ะพัะพะฑัะฐะถะตะฝะธะต GIF-ัะฐะนะปะพะฒ ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "GIF-ะธะฝััััะผะตะฝัั"
+ },
+ "image-generic": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ั ะธะทะพะฑัะฐะถะตะฝะธัะผะธ โ ัะถะฐัะธะต, ะธะทะผะตะฝะตะฝะธะต ัะฐะทะผะตัะฐ, ะพะฑัะตะทะบะฐ, ะบะพะฝะฒะตััะฐัะธั ะฒ JPG, ะฟะพะฒะพัะพั, ัะดะฐะปะตะฝะธะต ัะพะฝะฐ ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ั ะธะทะพะฑัะฐะถะตะฝะธัะผะธ"
+ },
+ "json": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ัะพ ััััะบัััะฐะผะธ ะดะฐะฝะฝัั
JSON โ ัะฟัะพัะฐะนัะต ะธ ะผะธะฝะธะผะธะทะธััะนัะต ะพะฑัะตะบัั JSON, ะฒััะฐะฒะฝะธะฒะฐะนัะต ะผะฐััะธะฒั JSON, ะฟัะตะพะฑัะฐะทัะนัะต ะทะฝะฐัะตะฝะธั JSON ะฒ ัััะพะบะธ, ะฐะฝะฐะปะธะทะธััะนัะต ะดะฐะฝะฝัะต ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "ะะฝััััะผะตะฝัั JSON"
+ },
+ "list": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ัะพ ัะฟะธัะบะฐะผะธ โ ัะพััะธัะพะฒะบะฐ, ะพะฑัะฐัะฝัะน ะฟะพััะดะพะบ, ัะฐะฝะดะพะผะธะทะฐัะธั ัะฟะธัะบะพะฒ, ะฟะพะธัะบ ัะฝะธะบะฐะปัะฝัั
ะธ ะฟะพะฒัะพััััะธั
ัั ัะปะตะผะตะฝัะพะฒ ัะฟะธัะบะฐ, ะธะทะผะตะฝะตะฝะธะต ัะฐะทะดะตะปะธัะตะปะตะน ัะปะตะผะตะฝัะพะฒ ัะฟะธัะบะฐ ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "ะกะฟะธัะพะบ ะธะฝััััะผะตะฝัะพะฒ"
+ },
+ "number": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ั ัะธัะปะฐะผะธ โ ะณะตะฝะตัะฐัะธั ัะธัะปะพะฒัั
ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััะตะน, ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธะต ัะธัะตะป ะฒ ัะปะพะฒะฐ ะธ ัะปะพะฒ ะฒ ัะธัะปะฐ, ัะพััะธัะพะฒะบะฐ, ะพะบััะณะปะตะฝะธะต, ัะฐะทะปะพะถะตะฝะธะต ัะธัะตะป ะฝะฐ ะผะฝะพะถะธัะตะปะธ ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "ะงะธัะปะพะฒัะต ะธะฝััััะผะตะฝัั"
+ },
+ "pdf": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ั PDF-ัะฐะนะปะฐะผะธ โ ะธะทะฒะปะตัะตะฝะธะต ัะตะบััะฐ ะธะท PDF-ัะฐะนะปะพะฒ, ะบะพะฝะฒะตััะฐัะธั PDF-ัะฐะนะปะพะฒ ะฒ ะดััะณะธะต ัะพัะผะฐัั, ะผะฐะฝะธะฟัะปะธัะพะฒะฐะฝะธะต PDF-ัะฐะนะปะฐะผะธ ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "PDF-ะธะฝััััะผะตะฝัั"
+ },
+ "png": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ั ะธะทะพะฑัะฐะถะตะฝะธัะผะธ PNG โ ะบะพะฝะฒะตััะธััะนัะต PNG ะฒ JPG, ัะพะทะดะฐะฒะฐะนัะต ะฟัะพะทัะฐัะฝัะต PNG, ะธะทะผะตะฝัะนัะต ัะฒะตัะฐ PNG, ะพะฑัะตะทะฐะนัะต, ะฟะพะฒะพัะฐัะธะฒะฐะนัะต, ะธะทะผะตะฝัะนัะต ัะฐะทะผะตั PNG ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "ะะฝััััะผะตะฝัั PNG"
+ },
+ "seeAll": "ะกะผะพััะตัั ะฒัะต {{title}}",
+ "string": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ั ัะตะบััะพะผ โ ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธะต ัะตะบััะฐ ะฒ ะธะทะพะฑัะฐะถะตะฝะธั, ะฟะพะธัะบ ะธ ะทะฐะผะตะฝะฐ ัะตะบััะฐ, ัะฐะทะดะตะปะตะฝะธะต ัะตะบััะฐ ะฝะฐ ััะฐะณะผะตะฝัั, ะพะฑัะตะดะธะฝะตะฝะธะต ัะตะบััะพะฒัั
ัััะพะบ, ะฟะพะฒัะพั ัะตะบััะฐ ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "ะขะตะบััะพะฒัะต ะธะฝััััะผะตะฝัั"
+ },
+ "time": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ัะพ ะฒัะตะผะตะฝะตะผ ะธ ะดะฐัะพะน โ ัะฐััะตั ัะฐะทะฝะธัั ะฒะพ ะฒัะตะผะตะฝะธ, ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธะต ัะฐัะพะฒัั
ะฟะพััะพะฒ, ัะพัะผะฐัะธัะพะฒะฐะฝะธะต ะดะฐั, ัะพะทะดะฐะฝะธะต ะฟะพัะปะตะดะพะฒะฐัะตะปัะฝะพััะตะน ะดะฐั ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "ะะฝััััะผะตะฝัั ะฒัะตะผะตะฝะธ"
+ },
+ "try": "ะััะฐัััั {{title}}",
+ "video": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ั ะฒะธะดะตะพ โ ะธะทะฒะปะตัะตะฝะธะต ะบะฐะดัะพะฒ ะธะท ะฒะธะดะตะพ, ัะพะทะดะฐะฝะธะต GIF-ัะฐะนะปะพะฒ ะธะท ะฒะธะดะตะพ, ะบะพะฝะฒะตััะฐัะธั ะฒะธะดะตะพ ะฒ ัะฐะทะปะธัะฝัะต ัะพัะผะฐัั ะธ ะผะฝะพะณะพะต ะดััะณะพะต.",
+ "title": "ะะธะดะตะพ ะธะฝััััะผะตะฝัั"
+ },
+ "xml": {
+ "description": "ะะฝััััะผะตะฝัั ะดะปั ัะฐะฑะพัั ั XML-ััััะบัััะฐะผะธ ะดะฐะฝะฝัั
โ ะฟัะพัะผะพัััะธะบ, ัะปัััะธัะตะปั, ะฒะฐะปะธะดะฐัะพั ะธ ะผะฝะพะณะพะต ะดััะณะพะต",
+ "title": "XML-ะธะฝััััะผะตะฝัั"
+ }
+ },
+ "csv": {
+ "findIncompleteCsvRecords": {
+ "description": "ะัะพััะพ ะทะฐะณััะทะธัะต CSV-ัะฐะนะป ะฒ ัะพัะผั ะฝะธะถะต, ะธ ััะพั ะธะฝััััะผะตะฝั ะฐะฒัะพะผะฐัะธัะตัะบะธ ะฟัะพะฒะตัะธั ะฝะฐะปะธัะธะต ะฒัะตั
ะฟัะพะฟััะตะฝะฝัั
ะทะฝะฐัะตะฝะธะน ะฒ ัััะพะบะฐั
ะธ ััะพะปะฑัะฐั
. ะ ะฝะฐัััะพะนะบะฐั
ะธะฝััััะผะตะฝัะฐ ะผะพะถะฝะพ ะฝะฐัััะพะธัั ัะพัะผะฐั ะฒั
ะพะดะฝะพะณะพ ัะฐะนะปะฐ (ัะบะฐะทะฐัั ัะฐะทะดะตะปะธัะตะปั, ัะธะผะฒะพะป ะบะฐะฒััะบะธ ะธ ัะธะผะฒะพะป ะบะพะผะผะตะฝัะฐัะธั). ะัะพะผะต ัะพะณะพ, ะผะพะถะฝะพ ะฒะบะปััะธัั ะฟัะพะฒะตัะบั ะฝะฐ ะฝะฐะปะธัะธะต ะฟััััั
ะทะฝะฐัะตะฝะธะน, ะฟัะพะฟััะบะฐัั ะฟััััะต ัััะพะบะธ ะธ ัััะฐะฝะพะฒะธัั ะพะณัะฐะฝะธัะตะฝะธะต ะฝะฐ ะบะพะปะธัะตััะฒะพ ัะพะพะฑัะตะฝะธะน ะพะฑ ะพัะธะฑะบะฐั
ะฒ ะฒัั
ะพะดะฝัั
ะดะฐะฝะฝัั
.",
+ "name": "ะะฐะนัะธ ะฝะตะฟะพะปะฝัะต ะทะฐะฟะธัะธ CSV",
+ "shortDescription": "ะััััะพ ะฝะฐั
ะพะดะธัะต ัััะพะบะธ ะธ ััะพะปะฑัั ะฒ CSV-ัะฐะนะปะต, ะฒ ะบะพัะพััั
ะพััััััะฒััั ะทะฝะฐัะตะฝะธั."
+ }
+ },
+ "hero": {
+ "brand": "ะะผะฝะธะะฝััััะผะตะฝัั",
+ "description": "ะะพะฒััััะต ัะฒะพั ะฟัะพะธะทะฒะพะดะธัะตะปัะฝะพััั ั OmniTools โ ะปัััะธะผ ะฝะฐะฑะพัะพะผ ะธะฝััััะผะตะฝัะพะฒ ะดะปั ะฑััััะพะณะพ ัะตัะตะฝะธั ะทะฐะดะฐั! ะะพะปััะธัะต ะดะพัััะฟ ะบ ัััััะฐะผ ัะดะพะฑะฝัั
ััะธะปะธั ะดะปั ัะตะดะฐะบัะธัะพะฒะฐะฝะธั ะธะทะพะฑัะฐะถะตะฝะธะน, ัะตะบััะฐ, ัะฟะธัะบะพะฒ ะธ ะดะฐะฝะฝัั
โ ะธ ะฒัั ััะพ ะฟััะผะพ ะฒ ะฑัะฐัะทะตัะต.",
+ "examples": {
+ "calculateNumberSum": "ะััะธัะปะธัั ััะผะผั ัะธัะตะป",
+ "changeGifSpeed": "ะะทะผะตะฝะธัั ัะบะพัะพััั GIF-ะฐะฝะธะผะฐัะธะธ",
+ "compressPng": "ะกะถะฐัั PNG",
+ "createTransparentImage": "ะกะพะทะดะฐัั ะฟัะพะทัะฐัะฝะพะต ะธะทะพะฑัะฐะถะตะฝะธะต",
+ "prettifyJson": "ะฃะฟัะพัะตะฝะธะต JSON",
+ "sortList": "ะกะพััะธัะพะฒะฐัั ัะฟะธัะพะบ",
+ "splitPdf": "ะ ะฐะทะดะตะปะธัั PDF",
+ "splitText": "ะ ะฐะทะดะตะปะธัั ัะตะบัั",
+ "trimVideo": "ะะฑัะตะทะฐัั ะฒะธะดะตะพ"
+ },
+ "searchPlaceholder": "ะัะบะฐัั ะฒัะต ะธะฝััััะผะตะฝัั",
+ "title": "ะัะฟะพะปะฝัะนัะต ะทะฐะดะฐัะธ ะฑััััะพ ั ะฟะพะผะพััั"
+ },
+ "inputFooter": {
+ "clear": "ะัะพะทัะฐัะฝัะน",
+ "copyToClipboard": "ะะพะฟะธัะพะฒะฐัั ะฒ ะฑััะตั ะพะฑะผะตะฝะฐ",
+ "importFromFile": "ะะผะฟะพัั ะธะท ัะฐะนะปะฐ"
+ },
+ "list": {
+ "group": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะณััะฟะฟะธัะพะฒะบะธ ัะปะตะผะตะฝัะพะฒ ัะฟะธัะบะฐ. ะะฒะตะดะธัะต ัะฟะธัะพะบ ะธ ัะบะฐะถะธัะต ะบัะธัะตัะธะธ ะณััะฟะฟะธัะพะฒะบะธ, ััะพะฑั ะพัะณะฐะฝะธะทะพะฒะฐัั ัะปะตะผะตะฝัั ะฒ ะปะพะณะธัะตัะบะธะต ะณััะฟะฟั. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ะบะฐัะตะณะพัะธะทะฐัะธะธ ะดะฐะฝะฝัั
, ะพัะณะฐะฝะธะทะฐัะธะธ ะธะฝัะพัะผะฐัะธะธ ะธ ัะพะทะดะฐะฝะธั ััััะบัััะธัะพะฒะฐะฝะฝัั
ัะฟะธัะบะพะฒ. ะะพะดะดะตัะถะธะฒะฐะตั ะฝะฐัััะฐะธะฒะฐะตะผัะต ัะฐะทะดะตะปะธัะตะปะธ ะธ ัะฐะทะปะธัะฝัะต ะฒะฐัะธะฐะฝัั ะณััะฟะฟะธัะพะฒะบะธ.",
+ "name": "ะััะฟะฟะฐ",
+ "shortDescription": "ะััะฟะฟะธัะพะฒะฐัั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะฟะพ ะพะฑัะธะผ ัะฒะพะนััะฒะฐะผ"
+ },
+ "reverse": {
+ "description": "ะญัะพ ะพัะตะฝั ะฟัะพััะพะต ะฑัะฐัะทะตัะฝะพะต ะฟัะธะปะพะถะตะฝะธะต, ะบะพัะพัะพะต ะฒัะฒะพะดะธั ะฒัะต ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะฒ ะพะฑัะฐัะฝะพะผ ะฟะพััะดะบะต. ะญะปะตะผะตะฝัั ะฒะฒะพะดะฐ ะผะพะถะฝะพ ัะฐะทะดะตะปััั ะปัะฑัะผ ัะธะผะฒะพะปะพะผ, ะธ ะฒั ัะฐะบะถะต ะผะพะถะตัะต ะธะทะผะตะฝะธัั ัะฐะทะดะตะปะธัะตะปั ะดะปั ัะปะตะผะตะฝัะพะฒ ะฟะตัะตะฒััะฝััะพะณะพ ัะฟะธัะบะฐ.",
+ "name": "ะะฑะตัะฟะตัะธัั ัะตะณัะตัั",
+ "shortDescription": "ะััััะพ ะฟะตัะตะฒะตัะฝััั ัะฟะธัะพะบ"
+ },
+ "sort": {
+ "description": "ะญัะพ ะพัะตะฝั ะฟัะพััะพะต ะฑัะฐัะทะตัะฝะพะต ะฟัะธะปะพะถะตะฝะธะต, ะบะพัะพัะพะต ัะพััะธััะตั ัะปะตะผะตะฝัั ัะฟะธัะบะฐ ะฒ ะฟะพััะดะบะต ะฒะพะทัะฐััะฐะฝะธั ะธะปะธ ัะฑัะฒะฐะฝะธั. ะั ะผะพะถะตัะต ัะพััะธัะพะฒะฐัั ัะปะตะผะตะฝัั ะฟะพ ะฐะปัะฐะฒะธัั, ะฟะพ ะฝะพะผะตัะฐะผ ะธะปะธ ะฟะพ ะดะปะธะฝะต. ะั ัะฐะบะถะต ะผะพะถะตัะต ัะดะฐะปััั ะฟะพะฒัะพััััะธะตัั ะธ ะฟััััะต ัะปะตะผะตะฝัั, ะฐ ัะฐะบะถะต ะพะฑัะตะทะฐัั ะพัะดะตะปัะฝัะต ัะปะตะผะตะฝัั ั ะฟัะพะฑะตะปะฐะผะธ ะฒะพะบััะณ ะฝะธั
. ะะปั ัะฐะทะดะตะปะตะฝะธั ัะปะตะผะตะฝัะพะฒ ะฒั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ ะผะพะถะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั ะปัะฑะพะน ัะธะผะฒะพะป-ัะฐะทะดะตะปะธัะตะปั ะธะปะธ ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต. ะัะพะผะต ัะพะณะพ, ะฒั ะผะพะถะตัะต ัะพะทะดะฐัั ะฝะพะฒัะน ัะฐะทะดะตะปะธัะตะปั ะดะปั ะพััะพััะธัะพะฒะฐะฝะฝะพะณะพ ะฒัั
ะพะดะฝะพะณะพ ัะฟะธัะบะฐ.",
+ "name": "ะกะพััะธัะพะฒะฐัั",
+ "shortDescription": "ะััััะฐั ัะพััะธัะพะฒะบะฐ ัะฟะธัะบะฐ"
+ }
+ },
+ "navbar": {
+ "buyMeACoffee": "ะัะฟะธ ะผะฝะต ะบะพัะต",
+ "home": "ะะพะผ",
+ "tools": "ะะฝััััะผะตะฝัั"
+ },
+ "number": {
+ "generate": {
+ "description": "ะััััะพ ะฒััะธัะปัะนัะต ัะฟะธัะพะบ ัะตะปัั
ัะธัะตะป ะฒ ะฑัะฐัะทะตัะต. ะงัะพะฑั ะฟะพะปััะธัั ัะฟะธัะพะบ, ะฟัะพััะพ ัะบะฐะถะธัะต ะฟะตัะฒะพะต ัะตะปะพะต ัะธัะปะพ, ะธะทะผะตะฝะธัะต ะทะฝะฐัะตะฝะธะต ะธ ะพะฑัะตะต ะบะพะปะธัะตััะฒะพ ะฒ ะฟะฐัะฐะผะตััะฐั
ะฝะธะถะต, ะธ ััะฐ ััะธะปะธัะฐ ัะณะตะฝะตัะธััะตั ะฝัะถะฝะพะต ะบะพะปะธัะตััะฒะพ ัะตะปัั
ัะธัะตะป.",
+ "name": "ะะตะฝะตัะธัะพะฒะฐัั ัะธัะปะฐ",
+ "shortDescription": "ะััััะพ ะฒััะธัะปะธัะต ัะฟะธัะพะบ ัะตะปัั
ัะธัะตะป ะฒ ะฒะฐัะตะผ ะฑัะฐัะทะตัะต"
+ },
+ "sum": {
+ "description": "ะญัะพ ะพัะตะฝั ะฟัะพััะพะต ะฑัะฐัะทะตัะฝะพะต ะฟัะธะปะพะถะตะฝะธะต ะดะปั ัะปะพะถะตะฝะธั ัะธัะตะป. ะะฒะพะดะธะผัะต ัะธัะปะฐ ะผะพะถะฝะพ ัะฐะทะดะตะปััั ะปัะฑัะผ ัะธะผะฒะพะปะพะผ, ะฐ ัะฐะบะถะต ะผะพะถะฝะพ ะธะทะผะตะฝะธัั ัะฐะทะดะตะปะธัะตะปั ััะผะผะธััะตะผัั
ัะธัะตะป.",
+ "name": "ะกัะผะผะฐ ัะธัะตะป",
+ "shortDescription": "ะััััะพ ััะผะผะธัะพะฒะฐัั ัะฟะธัะพะบ ัะธัะตะป"
+ }
+ },
+ "numericInputWithUnit": {
+ "unit": "ะะดะธะฝะธัะฐ"
+ },
+ "pdf": {
+ "compressPdf": {
+ "description": "ะฃะผะตะฝััะธัะต ัะฐะทะผะตั PDF-ัะฐะนะปะฐ, ัะพั
ัะฐะฝะธะฒ ะบะฐัะตััะฒะพ, ั ะฟะพะผะพััั Ghostscript",
+ "name": "ะกะถะฐัั PDF",
+ "shortDescription": "ะะตะทะพะฟะฐัะฝะพะต ัะถะฐัะธะต PDF-ัะฐะนะปะพะฒ ะฒ ะฒะฐัะตะผ ะฑัะฐัะทะตัะต"
+ },
+ "mergePdf": {
+ "description": "ะะฑัะตะดะธะฝะธัะต ะฝะตัะบะพะปัะบะพ PDF-ัะฐะนะปะพะฒ ะฒ ะพะดะธะฝ ะดะพะบัะผะตะฝั.",
+ "name": "ะะฑัะตะดะธะฝะธัั PDF",
+ "shortDescription": "ะะฑัะตะดะธะฝะธัั ะฝะตัะบะพะปัะบะพ PDF-ัะฐะนะปะพะฒ ะฒ ะพะดะธะฝ ะดะพะบัะผะตะฝั"
+ },
+ "pdfToEpub": {
+ "description": "ะัะตะพะฑัะฐะทัะนัะต PDF-ะดะพะบัะผะตะฝัั ะฒ ัะฐะนะปั EPUB ะดะปั ะปัััะตะน ัะพะฒะผะตััะธะผะพััะธ ั ัะปะตะบััะพะฝะฝัะผะธ ะบะฝะธะณะฐะผะธ.",
+ "name": "PDF ะฒ EPUB",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั PDF-ัะฐะนะปั ะฒ ัะพัะผะฐั EPUB"
+ },
+ "protectPdf": {
+ "description": "ะะพะฑะฐะฒััะต ะฝะฐะดะตะถะฝัั ะทะฐัะธัั ะฟะฐัะพะปะตะผ ะดะปั ะฒะฐัะธั
PDF-ัะฐะนะปะพะฒ ะฒ ะฑัะฐัะทะตัะต.",
+ "name": "ะะฐัะธัะธัั PDF-ัะฐะนะป",
+ "shortDescription": "ะะฐะดะตะถะฝะฐั ะทะฐัะธัะฐ ะฟะฐัะพะปะตะผ PDF-ัะฐะนะปะพะฒ"
+ },
+ "splitPdf": {
+ "description": "ะะทะฒะปะตัะตะฝะธะต ะพะฟัะตะดะตะปะตะฝะฝัั
ัััะฐะฝะธั ะธะท PDF-ัะฐะนะปะฐ ั ะธัะฟะพะปัะทะพะฒะฐะฝะธะตะผ ะฝะพะผะตัะพะฒ ะธะปะธ ะดะธะฐะฟะฐะทะพะฝะพะฒ ัััะฐะฝะธั (ะฝะฐะฟัะธะผะตั, 1,5-8)",
+ "name": "ะ ะฐะทะดะตะปะธัั PDF",
+ "shortDescription": "ะะทะฒะปะตัั ะพะฟัะตะดะตะปะตะฝะฝัะต ัััะฐะฝะธัั ะธะท PDF-ัะฐะนะปะฐ"
+ }
+ },
+ "resultFooter": {
+ "copy": "ะะพะฟะธัะพะฒะฐัั ะฒ ะฑััะตั ะพะฑะผะตะฝะฐ",
+ "download": "ะกะบะฐัะฐัั"
+ },
+ "string": {
+ "createPalindrome": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ัะพะทะดะฐะฝะธั ะฟะฐะปะธะฝะดัะพะผะพะฒ ะธะท ะปัะฑะพะณะพ ัะตะบััะฐ. ะะฒะตะดะธัะต ัะตะบัั ะธ ะผะณะฝะพะฒะตะฝะฝะพ ะฟัะตะพะฑัะฐะทัะนัะต ะตะณะพ ะฒ ะฟะฐะปะธะฝะดัะพะผ, ะบะพัะพััะน ัะธัะฐะตััั ะพะดะธะฝะฐะบะพะฒะพ ัะปะตะฒะฐ ะฝะฐะฟัะฐะฒะพ ะธ ัะฟัะฐะฒะฐ ะฝะฐะปะตะฒะพ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะปะพะฒะตัะฝัั
ะธะณั, ัะพะทะดะฐะฝะธั ัะธะผะผะตััะธัะฝัั
ัะตะบััะพะฒัั
ัะทะพัะพะฒ ะธะปะธ ะธะทััะตะฝะธั ะปะธะฝะณะฒะธััะธัะตัะบะธั
ะดะธะบะพะฒะธะฝะพะบ.",
+ "name": "ะกะพะทะดะฐัั ะฟะฐะปะธะฝะดัะพะผ",
+ "shortDescription": "ะกะพะทะดะฐะนัะต ัะตะบัั, ะบะพัะพััะน ะพะดะธะฝะฐะบะพะฒะพ ัะธัะฐะตััั ะบะฐะบ ัะปะตะฒะฐ ะฝะฐะฟัะฐะฒะพ, ัะฐะบ ะธ ัะปะตะฒะฐ ะฝะฐะฟัะฐะฒะพ."
+ },
+ "palindrome": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฟัะพะฒะตัะบะธ ัะตะบััะฐ ะฝะฐ ะฟะฐะปะธะฝะดัะพะผ. ะะณะฝะพะฒะตะฝะฝะพ ะฟัะพะฒะตััะตั, ะพะดะธะฝะฐะบะพะฒะพ ะปะธ ัะธัะฐะตััั ัะตะบัั ัะปะตะฒะฐ ะฝะฐะฟัะฐะฒะพ ะธ ัะฟัะฐะฒะฐ ะฝะฐะปะตะฒะพ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะตัะตะฝะธั ัะปะพะฒะตัะฝัั
ะณะพะปะพะฒะพะปะพะผะพะบ, ะปะธะฝะณะฒะธััะธัะตัะบะพะณะพ ะฐะฝะฐะปะธะทะฐ ะธ ะฟัะพะฒะตัะบะธ ัะธะผะผะตััะธัะฝะพััะธ ัะตะบััะพะฒัั
ัะฐะฑะปะพะฝะพะฒ. ะะพะดะดะตัะถะธะฒะฐะตั ัะฐะทะปะธัะฝัะต ัะฐะทะดะตะปะธัะตะปะธ ะธ ะพะฟัะตะดะตะปะตะฝะธะต ะฟะฐะปะธะฝะดัะพะผะพะฒ ะธะท ะฝะตัะบะพะปัะบะธั
ัะปะพะฒ.",
+ "name": "ะะฐะปะธะฝะดัะพะผ",
+ "shortDescription": "ะัะพะฒะตัััะต, ัะธัะฐะตััั ะปะธ ัะตะบัั ะพะดะธะฝะฐะบะพะฒะพ ะฒ ะฟััะผะพะผ ะธ ะพะฑัะฐัะฝะพะผ ะฝะฐะฟัะฐะฒะปะตะฝะธะธ."
+ },
+ "repeat": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะฟะพะฒัะพัััั ะทะฐะดะฐะฝะฝัะน ัะตะบัั ะฝะตัะบะพะปัะบะพ ัะฐะท ั ะดะพะฟะพะปะฝะธัะตะปัะฝัะผ ัะฐะทะดะตะปะธัะตะปะตะผ.",
+ "name": "ะะพะฒัะพัะธัั ัะตะบัั",
+ "shortDescription": "ะะพะฒัะพัะธัั ัะตะบัั ะฝะตัะบะพะปัะบะพ ัะฐะท"
+ },
+ "reverse": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฟะตัะตะฒะพัะพัะฐ ัะตะบััะฐ. ะะฒะตะดะธัะต ะปัะฑะพะน ัะตะบัั, ะธ ะพะฝ ะผะณะฝะพะฒะตะฝะฝะพ ะฟะตัะตะฒะตัะฝัััั, ัะธะผะฒะพะป ะทะฐ ัะธะผะฒะพะปะพะผ. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะพะทะดะฐะฝะธั ะทะตัะบะฐะปัะฝะพะณะพ ัะตะบััะฐ, ะฐะฝะฐะปะธะทะฐ ะฟะฐะปะธะฝะดัะพะผะพะฒ ะธ ัะบัะฟะตัะธะผะตะฝัะพะฒ ั ัะตะบััะพะฒัะผะธ ัะฐะฑะปะพะฝะฐะผะธ. ะกะพั
ัะฐะฝัะตั ะฟัะพะฑะตะปั ะธ ัะฟะตัะธะฐะปัะฝัะต ัะธะผะฒะพะปั ะฟัะธ ะฟะตัะตะฒะพัะพัะต.",
+ "name": "ะะฑะตัะฟะตัะธัั ัะตะณัะตัั",
+ "shortDescription": "ะะตัะตะฒะตัะฝััั ะปัะฑะพะน ัะตะบัั ะฟะพัะธะผะฒะพะปัะฝะพ"
+ },
+ "toMorse": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธั ัะตะบััะฐ ะฒ ะบะพะด ะะพัะทะต. ะะฐะณััะทะธัะต ัะตะบัั ะฒ ัะพัะผั ะฒะฒะพะดะฐ ัะปะตะฒะฐ, ะธ ะฒั ะผะณะฝะพะฒะตะฝะฝะพ ะฟะพะปััะธัะต ะบะพะด ะะพัะทะต ะฒ ะพะฑะปะฐััะธ ะฒัะฒะพะดะฐ. ะะพัะฝะฐั, ะฑะตัะฟะปะฐัะฝะฐั ะธ ะฑััััะฐั. ะะฐะณััะทะธัะต ัะตะบัั โ ะฟะพะปััะธัะต ะบะพะด ะะพัะทะต.",
+ "name": "ะกััะพะบะฐ ะฒ ะฐะทะฑัะบะต ะะพัะทะต",
+ "shortDescription": "ะััััะพะต ะบะพะดะธัะพะฒะฐะฝะธะต ัะตะบััะฐ ะฒ ะฐะทะฑัะบั ะะพัะทะต"
+ },
+ "uppercase": {
+ "description": "ะกะฐะผะฐั ะฟัะพััะฐั ะฒ ะผะธัะต ะฑัะฐัะทะตัะฝะฐั ััะธะปะธัะฐ ะดะปั ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธั ัะตะบััะฐ ะฒ ะฒะตัั
ะฝะธะน ัะตะณะธััั. ะัะพััะพ ะฒะฒะตะดะธัะต ัะตะบัั, ะธ ะพะฝ ะฑัะดะตั ะฐะฒัะพะผะฐัะธัะตัะบะธ ะฟัะตะพะฑัะฐะทะพะฒะฐะฝ ะฒ ะทะฐะณะปะฐะฒะฝัะต ะฑัะบะฒั. ะะดะตะฐะปัะฝะพ ะฟะพะดั
ะพะดะธั ะดะปั ัะพะทะดะฐะฝะธั ะทะฐะณะพะปะพะฒะบะพะฒ, ะฒัะดะตะปะตะฝะธั ัะตะบััะฐ ะธะปะธ ััะฐะฝะดะฐััะธะทะฐัะธะธ ัะพัะผะฐัะธัะพะฒะฐะฝะธั ัะตะบััะฐ. ะะพะดะดะตัะถะธะฒะฐะตั ัะฐะทะปะธัะฝัะต ัะตะบััะพะฒัะต ัะพัะผะฐัั ะธ ัะพั
ัะฐะฝัะตั ัะฟะตัะธะฐะปัะฝัะต ัะธะผะฒะพะปั.",
+ "name": "ะะฐะณะปะฐะฒะฝัะต ะฑัะบะฒั",
+ "shortDescription": "ะัะตะพะฑัะฐะทะพะฒะฐัั ัะตะบัั ะฒ ะทะฐะณะปะฐะฒะฝัะต ะฑัะบะฒั"
+ }
+ },
+ "toolExamples": {
+ "subtitle": "ะะฐะถะผะธัะต, ััะพะฑั ะฟะพะฟัะพะฑะพะฒะฐัั!",
+ "title": "{{title}} ะัะธะผะตัั"
+ },
+ "toolFileResult": {
+ "copied": "ะคะฐะนะป ัะบะพะฟะธัะพะฒะฐะฝ",
+ "copyFailed": "ะะต ัะดะฐะปะพัั ัะบะพะฟะธัะพะฒะฐัั: {{error}}",
+ "loading": "ะะฐะณััะทะบะฐ... ะญัะพ ะผะพะถะตั ะทะฐะฝััั ะฝะตะบะพัะพัะพะต ะฒัะตะผั.",
+ "result": "ะ ะตะทัะปััะฐั"
+ },
+ "toolHeader": {
+ "seeExamples": "ะกะผ. ะฟัะธะผะตัั"
+ },
+ "toolLayout": {
+ "allToolsTitle": "ะัะต {{type}}"
+ },
+ "toolMultiFileResult": {
+ "copied": "ะคะฐะนะป ัะบะพะฟะธัะพะฒะฐะฝ",
+ "copyFailed": "ะะต ัะดะฐะปะพัั ัะบะพะฟะธัะพะฒะฐัั: {{error}}",
+ "loading": "ะะฐะณััะทะบะฐ... ะญัะพ ะผะพะถะตั ะทะฐะฝััั ะฝะตะบะพัะพัะพะต ะฒัะตะผั.",
+ "result": "ะ ะตะทัะปััะฐั"
+ },
+ "toolMultipleAudioInput": {
+ "inputTitle": "ะั
ะพะด {{type}}",
+ "noFilesSelected": "ะคะฐะนะปั ะฝะต ะฒัะฑัะฐะฝั."
+ },
+ "toolMultiplePdfInput": {
+ "inputTitle": "ะั
ะพะด {{type}}",
+ "noFilesSelected": "ะคะฐะนะปั ะฝะต ะฒัะฑัะฐะฝั."
+ },
+ "toolOptions": {
+ "title": "ะะฐัะฐะผะตััั ะธะฝััััะผะตะฝัะฐ"
+ },
+ "toolTextInput": {
+ "copied": "ะขะตะบัั ัะบะพะฟะธัะพะฒะฐะฝ",
+ "copyFailed": "ะะต ัะดะฐะปะพัั ัะบะพะฟะธัะพะฒะฐัั: {{error}}",
+ "input": "ะะฒะตะดะธัะต ัะตะบัั",
+ "placeholder": "ะะฒะตะดะธัะต ัะตะบัั ะทะดะตัั..."
+ },
+ "toolTextResult": {
+ "copied": "ะขะตะบัั ัะบะพะฟะธัะพะฒะฐะฝ",
+ "copyFailed": "ะะต ัะดะฐะปะพัั ัะบะพะฟะธัะพะฒะฐัั: {{error}}",
+ "loading": "ะะฐะณััะทะบะฐ... ะญัะพ ะผะพะถะตั ะทะฐะฝััั ะฝะตะบะพัะพัะพะต ะฒัะตะผั.",
+ "result": "ะ ะตะทัะปััะฐั"
+ }
+}
diff --git a/public/locales/ru/video.json b/public/locales/ru/video.json
new file mode 100644
index 0000000..3f0b505
--- /dev/null
+++ b/public/locales/ru/video.json
@@ -0,0 +1,113 @@
+{
+ "changeSpeed": {
+ "defaultMultiplier": "ะะฝะพะถะธัะตะปั ะฟะพ ัะผะพะปัะฐะฝะธั: 2 ะพะทะฝะฐัะฐะตั ะฒ 2 ัะฐะทะฐ ะฑััััะตะต",
+ "description": "ะะทะผะตะฝัะนัะต ัะบะพัะพััั ะฒะพัะฟัะพะธะทะฒะตะดะตะฝะธั ะฒะธะดะตะพัะฐะนะปะพะฒ. ะฃัะบะพััะนัะต ะธะปะธ ะทะฐะผะตะดะปัะนัะต ะฒะธะดะตะพ, ัะพั
ัะฐะฝัั ัะธะฝั
ัะพะฝะธะทะฐัะธั ัะพ ะทะฒัะบะพะผ. ะะพะดะดะตัะถะธะฒะฐะตั ัะฐะทะปะธัะฝัะต ะบะพัััะธัะธะตะฝัั ััะบะพัะตะฝะธั ะธ ัะฐัะฟัะพัััะฐะฝัะฝะฝัะต ะฒะธะดะตะพัะพัะผะฐัั.",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะฒะธะดะตะพ",
+ "newVideoSpeed": "ะะพะฒะฐั ัะบะพัะพััั ะฒะธะดะตะพ",
+ "resultTitle": "ะััะตะดะฐะบัะธัะพะฒะฐะฝะฝะพะต ะฒะธะดะตะพ",
+ "settingSpeed": "ะกะบะพัะพััั ัััะฐะฝะพะฒะบะธ",
+ "shortDescription": "ะะทะผะตะฝะธัั ัะบะพัะพััั ะฒะพัะฟัะพะธะทะฒะตะดะตะฝะธั ะฒะธะดะตะพ",
+ "title": "ะะทะผะตะฝะธัั ัะบะพัะพััั ะฒะธะดะตะพ",
+ "toolInfo": {
+ "title": "ะงัะพ ัะฐะบะพะต {{title}}?"
+ }
+ },
+ "compress": {
+ "default": "ะะพ ัะผะพะปัะฐะฝะธั",
+ "description": "ะกะถะธะผะฐะนัะต ะฒะธะดะตะพ, ะผะฐัััะฐะฑะธััั ะธั
ะดะพ ัะฐะทะปะธัะฝัั
ัะฐะทัะตัะตะฝะธะน, ัะฐะบะธั
ะบะฐะบ 240p, 480p, 720p ะธ ั. ะด. ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะผะพะณะฐะตั ัะผะตะฝััะธัั ัะฐะทะผะตั ัะฐะนะปะฐ, ัะพั
ัะฐะฝัั ะฟัะธะตะผะปะตะผะพะต ะบะฐัะตััะฒะพ. ะะพะดะดะตัะถะธะฒะฐะตั ัะฐัะฟัะพัััะฐะฝัะฝะฝัะต ะฒะธะดะตะพัะพัะผะฐัั, ัะฐะบะธะต ะบะฐะบ MP4, WebM ะธ OGG.",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะฒะธะดะตะพ",
+ "loadingText": "ะกะถะฐัะธะต ะฒะธะดะตะพ...",
+ "lossless": "ะะตะท ะฟะพัะตัั",
+ "quality": "ะะฐัะตััะฒะพ (CRF)",
+ "resolution": "ะ ะฐะทัะตัะตะฝะธะต",
+ "resultTitle": "ะกะถะฐัะพะต ะฒะธะดะตะพ",
+ "shortDescription": "ะกะถะธะผะฐะนัะต ะฒะธะดะตะพ ะฟััะตะผ ะผะฐัััะฐะฑะธัะพะฒะฐะฝะธั ะดะพ ัะฐะทะฝัั
ัะฐะทัะตัะตะฝะธะน",
+ "title": "ะกะถะฐัั ะฒะธะดะตะพ",
+ "worst": "ะฅัะดัะธะน"
+ },
+ "cropVideo": {
+ "cropCoordinates": "ะะพะพัะดะธะฝะฐัั ะพะฑัะตะทะบะธ",
+ "croppingVideo": "ะะฑัะตะทะบะฐ ะฒะธะดะตะพ",
+ "description": "ะะฑัะตะถััะต ะฒะธะดะตะพ, ััะพะฑั ัะดะฐะปะธัั ะฝะตะถะตะปะฐัะตะปัะฝัะต ะพะฑะปะฐััะธ.",
+ "errorBeyondHeight": "ะะฑะปะฐััั ะบะฐะดัะธัะพะฒะฐะฝะธั ะฒัั
ะพะดะธั ะทะฐ ะฟัะตะดะตะปั ะฒััะพัั ะฒะธะดะตะพ ({{height}}ะฟะธะบั)",
+ "errorBeyondWidth": "ะะฑะปะฐััั ะบะฐะดัะธัะพะฒะฐะฝะธั ะฒัั
ะพะดะธั ะทะฐ ะฟัะตะดะตะปั ัะธัะธะฝั ะฒะธะดะตะพ ({{width}}ะฟะธะบั)",
+ "errorCroppingVideo": "ะัะธะฑะบะฐ ะพะฑัะตะทะบะธ ะฒะธะดะตะพ. ะัะพะฒะตัััะต ะฟะฐัะฐะผะตััั ะธ ะฒะธะดะตะพัะฐะนะป.",
+ "errorLoadingDimensions": "ะะต ัะดะฐะปะพัั ะทะฐะณััะทะธัั ัะฐะทะผะตัั ะฒะธะดะตะพ.",
+ "errorNonNegativeCoordinates": "ะะพะพัะดะธะฝะฐัั X ะธ Y ะดะพะปะถะฝั ะฑััั ะฝะตะพััะธัะฐัะตะปัะฝัะผะธ",
+ "errorPositiveDimensions": "ะจะธัะธะฝะฐ ะธ ะฒััะพัะฐ ะดะพะปะถะฝั ะฑััั ะฟะพะปะพะถะธัะตะปัะฝัะผะธ.",
+ "height": "ะััะพัะฐ",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะฒะธะดะตะพ",
+ "loadVideoForDimensions": "ะะฐะณััะทะธัะต ะฒะธะดะตะพ, ััะพะฑั ัะฒะธะดะตัั ัะฐะทะผะตัั",
+ "resultTitle": "ะะฑัะตะทะฐะฝะฝะพะต ะฒะธะดะตะพ",
+ "shortDescription": "ะะฑัะตะถััะต ะฒะธะดะตะพ, ััะพะฑั ัะดะฐะปะธัั ะฝะตะถะตะปะฐัะตะปัะฝัะต ะพะฑะปะฐััะธ",
+ "title": "ะะฑัะตะทะฐัั ะฒะธะดะตะพ",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะพะฑัะตะทะฐัั ะฒะธะดะตะพัะฐะนะปั, ัะดะฐะปัั ะฝะตะถะตะปะฐัะตะปัะฝัะต ะพะฑะปะฐััะธ. ะั ะผะพะถะตัะต ัะบะฐะทะฐัั ะพะฑะปะฐััั ะพะฑัะตะทะบะธ, ะทะฐะดะฐะฒ ะบะพะพัะดะธะฝะฐัั X, Y, ะฐ ัะฐะบะถะต ัะธัะธะฝั ะธ ะฒััะพัั.",
+ "title": "ะะฑัะตะทะฐัั ะฒะธะดะตะพ"
+ },
+ "videoDimensions": "ะ ะฐะทะผะตัั ะฒะธะดะตะพ: {{width}} ร {{height}} ะฟะธะบัะตะปะธ",
+ "videoInformation": "ะะธะดะตะพ ะธะฝัะพัะผะฐัะธั",
+ "width": "ะจะธัะธะฝะฐ",
+ "xCoordinate": "X (ัะปะตะฒะฐ)",
+ "yCoordinate": "Y (ะฒะฒะตัั
ั)"
+ },
+ "flip": {
+ "description": "ะะตัะตะฒะพัะฐัะธะฒะฐะนัะต ะฒะธะดะตะพัะฐะนะปั ะฟะพ ะณะพัะธะทะพะฝัะฐะปะธ ะธะปะธ ะฒะตััะธะบะฐะปะธ. ะะตัะบะฐะปัะฝะพ ะพัะพะฑัะฐะถะฐะนัะต ะฒะธะดะตะพ ะดะปั ัะพะทะดะฐะฝะธั ัะฟะตััััะตะบัะพะฒ ะธะปะธ ะธัะฟัะฐะฒะปะตะฝะธั ะฟัะพะฑะปะตะผ ั ะพัะธะตะฝัะฐัะธะตะน.",
+ "flippingVideo": "ะะตัะตะปะธัััะฒะฐะฝะธะต ะฒะธะดะตะพ",
+ "horizontalLabel": "ะะพัะธะทะพะฝัะฐะปัะฝัะน (ะะตัะบะฐะปัะฝัะน)",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะฒะธะดะตะพ",
+ "orientation": "ะัะธะตะฝัะฐัะธั",
+ "resultTitle": "ะะตัะตะฒะตัะฝััะพะต ะฒะธะดะตะพ",
+ "shortDescription": "ะะตัะตะฒะตัะฝััั ะฒะธะดะตะพ ะฟะพ ะณะพัะธะทะพะฝัะฐะปะธ ะธะปะธ ะฒะตััะธะบะฐะปะธ",
+ "title": "ะะตัะตะฒะตัะฝััั ะฒะธะดะตะพ",
+ "verticalLabel": "ะะตััะธะบะฐะปัะฝะพ (ะฒะฒะตัั
ะดะฝะพะผ)"
+ },
+ "gif": {
+ "changeSpeed": {
+ "description": "ะะทะผะตะฝะธัะต ัะบะพัะพััั ะฒะพัะฟัะพะธะทะฒะตะดะตะฝะธั GIF-ะฐะฝะธะผะฐัะธะธ. ะฃัะบะพััะนัะต ะธะปะธ ะทะฐะผะตะดะปัะนัะต GIF-ะฐะฝะธะผะฐัะธั, ัะพั
ัะฐะฝัั ะฟะปะฐะฒะฝะพััั ะฐะฝะธะผะฐัะธะธ.",
+ "shortDescription": "ะะทะผะตะฝะธัั ัะบะพัะพััั GIF-ะฐะฝะธะผะฐัะธะธ",
+ "title": "ะะทะผะตะฝะธัั ัะบะพัะพััั GIF-ะฐะฝะธะผะฐัะธะธ"
+ }
+ },
+ "loop": {
+ "description": "ะกะพะทะดะฐะนัะต ะทะฐัะธะบะปะตะฝะฝะพะต ะฒะธะดะตะพ, ะฟะพะฒัะพัะธะฒ ะธัั
ะพะดะฝะพะต ะฒะธะดะตะพ ะฝะตัะบะพะปัะบะพ ัะฐะท.",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะฒะธะดะตะพ",
+ "loopingVideo": "ะะฐัะธะบะปะธะฒะฐะฝะธะต ะฒะธะดะตะพ",
+ "loops": "ะะตัะปะธ",
+ "numberOfLoops": "ะะพะปะธัะตััะฒะพ ะฟะตัะตะปั",
+ "resultTitle": "ะะฐัะธะบะปะตะฝะฝะพะต ะฒะธะดะตะพ",
+ "shortDescription": "ะกะพะทะดะฐะฝะธะต ะทะฐัะธะบะปะตะฝะฝัั
ะฒะธะดะตะพัะฐะนะปะพะฒ",
+ "title": "ะฆะธะบะป ะฒะธะดะตะพ",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ัะพะทะดะฐัั ัะธะบะปะธัะฝะพะต ะฒะธะดะตะพ, ะฟะพะฒัะพััั ะธัั
ะพะดะฝะพะต ะฒะธะดะตะพ ะฝะตัะบะพะปัะบะพ ัะฐะท. ะั ะผะพะถะตัะต ัะบะฐะทะฐัั, ัะบะพะปัะบะพ ัะฐะท ะฒะธะดะตะพ ะดะพะปะถะฝะพ ะฟะพะฒัะพัััััั.",
+ "title": "ะงัะพ ัะฐะบะพะต {{title}}?"
+ }
+ },
+ "rotate": {
+ "180Degrees": "180ยฐ (ะฒะฒะตัั
ะดะฝะพะผ)",
+ "270Degrees": "270ยฐ (90ยฐ ะฟัะพัะธะฒ ัะฐัะพะฒะพะน ัััะตะปะบะธ)",
+ "90Degrees": "90ยฐ ะฟะพ ัะฐัะพะฒะพะน ัััะตะปะบะต",
+ "description": "ะะพะฒะพัะฐัะธะฒะฐะนัะต ะฒะธะดะตะพัะฐะนะปั ะฝะฐ 90, 180 ะธะปะธ 270 ะณัะฐะดััะพะฒ. ะะพััะตะบัะธััะนัะต ะพัะธะตะฝัะฐัะธั ะฒะธะดะตะพ ะธะปะธ ัะพะทะดะฐะฒะฐะนัะต ัะฟะตััััะตะบัั ั ะฟะพะผะพััั ัะพัะฝะพะณะพ ัะฟัะฐะฒะปะตะฝะธั ะฟะพะฒะพัะพัะพะผ.",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะฒะธะดะตะพ",
+ "resultTitle": "ะะพะฒะตัะฝััะพะต ะฒะธะดะตะพ",
+ "rotatingVideo": "ะัะฐัะตะฝะธะต ะฒะธะดะตะพ",
+ "rotation": "ะัะฐัะตะฝะธะต",
+ "shortDescription": "ะะพะฒะตัะฝััั ะฒะธะดะตะพ ะฝะฐ ัะบะฐะทะฐะฝะฝัะน ัะณะพะป",
+ "title": "ะะพะฒะตัะฝััั ะฒะธะดะตะพ"
+ },
+ "trim": {
+ "description": "ะะฑัะตะทะฐะนัะต ะฒะธะดะตะพัะฐะนะปั, ัะบะฐะทะฐะฒ ะฒัะตะผั ะฝะฐัะฐะปะฐ ะธ ะพะบะพะฝัะฐะฝะธั. ะฃะดะฐะปัะนัะต ะฝะตะฝัะถะฝัะต ััะฐะณะผะตะฝัั ะฒ ะฝะฐัะฐะปะต ะธะปะธ ะบะพะฝัะต ะฒะธะดะตะพ.",
+ "endTime": "ะะพะฝะตั ะัะตะผะตะฝะธ",
+ "inputTitle": "ะั
ะพะดะฝะพะต ะฒะธะดะตะพ",
+ "resultTitle": "ะะฑัะตะทะฐะฝะฝะพะต ะฒะธะดะตะพ",
+ "shortDescription": "ะะฑัะตะถััะต ะฒะธะดะตะพ, ัะดะฐะปะธะฒ ะฝะตะฝัะถะฝัะต ััะฐะณะผะตะฝัั",
+ "startTime": "ะัะตะผั ะฝะฐัะฐะปะฐ",
+ "timestamps": "ะัะตะผะตะฝะฝัะต ะผะตัะบะธ",
+ "title": "ะะฑัะตะทะฐัั ะฒะธะดะตะพ"
+ },
+ "videoToGif": {
+ "description": "ะะพะฝะฒะตััะธััะนัะต ะฒะธะดะตะพัะฐะนะปั ะฒ ะฐะฝะธะผะธัะพะฒะฐะฝะฝัะน GIF-ัะพัะผะฐั. ะะทะฒะปะตะบะฐะนัะต ะพะฟัะตะดะตะปัะฝะฝัะต ะฒัะตะผะตะฝะฝัะต ะดะธะฐะฟะฐะทะพะฝั ะธ ัะพะทะดะฐะฒะฐะนัะต ะฐะฝะธะผะธัะพะฒะฐะฝะฝัะต ะธะทะพะฑัะฐะถะตะฝะธั ะดะปั ะฟัะฑะปะธะบะฐัะธะธ.",
+ "shortDescription": "ะะพะฝะฒะตััะธัะพะฒะฐัั ะฒะธะดะตะพ ะฒ ะฐะฝะธะผะธัะพะฒะฐะฝะฝัะน GIF",
+ "title": "ะะธะดะตะพ ะฒ GIF"
+ }
+}
diff --git a/public/locales/ru/xml.json b/public/locales/ru/xml.json
new file mode 100644
index 0000000..97a2f85
--- /dev/null
+++ b/public/locales/ru/xml.json
@@ -0,0 +1,38 @@
+{
+ "xmlBeautifier": {
+ "description": "ะััะพัะผะฐัะธััะนัะต XML ั ะฟัะฐะฒะธะปัะฝัะผะธ ะพััััะฟะฐะผะธ ะธ ะธะฝัะตัะฒะฐะปะฐะผะธ.",
+ "indentation": "ะััััะฟ",
+ "inputTitle": "ะั
ะพะดะฝะพะน XML",
+ "resultTitle": "ะฃะบัะฐัะตะฝะฝัะน XML",
+ "shortDescription": "ะคะพัะผะฐัะธััะนัะต ะธ ัะบัะฐัะฐะนัะต XML-ะบะพะด",
+ "title": "XML Beautifier",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ัะพัะผะฐัะธัะพะฒะฐัั XML-ะดะฐะฝะฝัะต ั ะฟัะฐะฒะธะปัะฝัะผะธ ะพััััะฟะฐะผะธ ะธ ะธะฝัะตัะฒะฐะปะฐะผะธ, ะดะตะปะฐั ะธั
ะฑะพะปะตะต ัะธัะฐะฑะตะปัะฝัะผะธ ะธ ัะดะพะฑะฝัะผะธ ะดะปั ัะฐะฑะพัั.",
+ "title": "XML Beautifier"
+ },
+ "useSpaces": "ะัะฟะพะปัะทัะนัะต ะฟัะพะฑะตะปั",
+ "useSpacesDescription": "ะััััะฟ ะฒัะฒะพะดะฐ ั ะฟัะพะฑะตะปะฐะผะธ",
+ "useTabs": "ะัะฟะพะปัะทะพะฒะฐัั ะฒะบะปะฐะดะบะธ",
+ "useTabsDescription": "ะััััะฟ ะฒัะฒะพะดะฐ ั ะฟะพะผะพััั ัะฐะฑัะปััะธะธ."
+ },
+ "xmlValidator": {
+ "description": "ะัะพะฒะตัััะต ัะธะฝัะฐะบัะธั ะธ ััััะบัััั XML.",
+ "placeholder": "ะััะฐะฒััะต ะธะปะธ ะธะผะฟะพััะธััะนัะต XML ััะดะฐ...",
+ "shortDescription": "ะัะพะฒะตัะธัั XML-ะบะพะด ะฝะฐ ะฝะฐะปะธัะธะต ะพัะธะฑะพะบ",
+ "title": "XML-ะฒะฐะปะธะดะฐัะพั",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะฟัะพะฒะตัะธัั ัะธะฝัะฐะบัะธั ะธ ััััะบัััั XML. ะะฝ ะฟัะพะฒะตััะตั ะฟัะฐะฒะธะปัะฝะพััั ัะพัะผะฐัะฐ XML ะธ ะฒัะฒะพะดะธั ะฟะพะดัะพะฑะฝัะต ัะพะพะฑัะตะฝะธั ะพะฑ ะพัะธะฑะบะฐั
ะฟัะธ ะพะฑะฝะฐััะถะตะฝะธะธ ะปัะฑัั
ะฟัะพะฑะปะตะผ.",
+ "title": "XML-ะฒะฐะปะธะดะฐัะพั"
+ }
+ },
+ "xmlViewer": {
+ "description": "ะัะพัะผะพัั ะธ ะธััะปะตะดะพะฒะฐะฝะธะต ััััะบัััั XML ะฒ ะดัะตะฒะพะฒะธะดะฝะพะน ัะพัะผะต.",
+ "inputTitle": "ะั
ะพะดะฝะพะน XML",
+ "resultTitle": "XML-ะดะตัะตะฒะพ",
+ "title": "XML-ะฟัะพัะผะพัััะธะบ",
+ "toolInfo": {
+ "description": "ะญัะพั ะธะฝััััะผะตะฝั ะฟะพะทะฒะพะปัะตั ะฟัะพัะผะฐััะธะฒะฐัั XML-ะดะฐะฝะฝัะต ะฒ ัะพัะผะฐัะต ะธะตัะฐัั
ะธัะตัะบะพะณะพ ะดะตัะตะฒะฐ, ััะพ ัะฟัะพัะฐะตั ะธะทััะตะฝะธะต ะธ ะฟะพะฝะธะผะฐะฝะธะต ััััะบัััั XML-ะดะพะบัะผะตะฝัะพะฒ.",
+ "title": "XML-ะฟัะพัะผะพัััะธะบ"
+ }
+ }
+}
diff --git a/public/locales/zh/audio.json b/public/locales/zh/audio.json
new file mode 100644
index 0000000..241f235
--- /dev/null
+++ b/public/locales/zh/audio.json
@@ -0,0 +1,42 @@
+{
+ "changeSpeed": {
+ "description": "ๆดๆน้ณ้ขๆไปถ็ๆญๆพ้ๅบฆใๅจไฟๆ้ณ่ฐไธๅ็ๆ
ๅตไธๅ ๅฟซๆๅๆ
ข้ณ้ข้ๅบฆใ",
+ "inputTitle": "่พๅ
ฅ้ณ้ข",
+ "newAudioSpeed": "ๆฐ้ณ้ข้ๅบฆ",
+ "outputFormat": "่พๅบๆ ผๅผ",
+ "resultTitle": "็ผ่พ้ณ้ข",
+ "settingSpeed": "่ฎพๅฎ้ๅบฆ",
+ "shortDescription": "ๆดๆน้ณ้ขๆไปถ็้ๅบฆ",
+ "speedDescription": "้ป่ฎคไนๆฐ๏ผ2 ่กจ็คบ้ๅบฆๅฟซ 2 ๅ",
+ "title": "ๆดๆน้ณ้ข้ๅบฆ",
+ "toolInfo": {
+ "title": "ไปไนๆฏ {{title}}๏ผ"
+ }
+ },
+ "extractAudio": {
+ "description": "ไป่ง้ขๆไปถไธญๆๅ้ณ่ฝจใ",
+ "extractingAudio": "ๆๅ้ณ้ข",
+ "inputTitle": "่พๅ
ฅ่ง้ข",
+ "outputFormat": "่พๅบๆ ผๅผ",
+ "outputFormatDescription": "้ๆฉ่ฆๆๅ็้ณ้ข็ๆ ผๅผใ",
+ "resultTitle": "ๆๅ้ณ้ข",
+ "shortDescription": "ๅฐ่ง้ขๆไปถ๏ผMP4ใMOV ็ญ๏ผไธญ็้ณ้ขๆๅไธบ AACใMP3 ๆ WAVใ",
+ "title": "ไป่ง้ขไธญๆๅ้ณ้ข",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅฏ่ฎฉๆจไป่ง้ขๆไปถไธญๆๅ้ณ่ฝจใๆจๅฏไปฅ้ๆฉไธๅ็้ณ้ขๆ ผๅผ๏ผๅ
ๆฌ AACใMP3 ๅ WAVใ",
+ "title": "ไปไนๆฏ {{title}}๏ผ"
+ }
+ },
+ "mergeAudio": {
+ "description": "ๆ้กบๅบ่ฟๆฅๅคไธช้ณ้ขๆไปถ๏ผๅฐๅ
ถๅๅนถไธบไธไธช้ณ้ขๆไปถใ",
+ "longDescription": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจๅฐๅคไธช้ณ้ขๆไปถๆ็
งไธไผ ้กบๅบไธฒ่ๆไธไธชๆไปถใ้ๅธธ้ๅๅๅนถๆญๅฎข็ๆฎตใ้ณไนๆฒ็ฎๆไปปไฝ้่ฆๅๅนถ็้ณ้ขๆไปถใๆฏๆๅค็ง้ณ้ขๆ ผๅผ๏ผๅ
ๆฌ MP3ใAAC ๅ WAVใ",
+ "shortDescription": "ๅฐๅคไธช้ณ้ขๆไปถๅๅนถไธบไธไธช๏ผMP3ใAACใWAV๏ผใ",
+ "title": "ๅๅนถ้ณ้ข"
+ },
+ "trim": {
+ "description": "้่ฟๆๅฎๅผๅงๅ็ปๆๆถ้ดๆฅๅชๅๅไฟฎๅช้ณ้ขๆไปถไปฅๆๅ็นๅฎ็ๆฎตใ",
+ "longDescription": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจ้่ฟๆๅฎๅผๅงๅ็ปๆๆถ้ดๆฅไฟฎๅช้ณ้ขๆไปถใๆจๅฏไปฅไป่พ้ฟ็้ณ้ขๆไปถไธญๆๅ็นๅฎ็ๆฎต๏ผๅ ้คไธ้่ฆ็้จๅ๏ผๆๅๅปบ่พ็ญ็็ๆฎตใๆฏๆๅค็ง้ณ้ขๆ ผๅผ๏ผๅ
ๆฌ MP3ใAAC ๅ WAVใ้ๅธธ้ๅๆญๅฎข็ผ่พใ้ณไนๅถไฝๆไปปไฝ้ณ้ข็ผ่พ้ๆฑใ",
+ "shortDescription": "ไฟฎๅช้ณ้ขๆไปถไปฅๆๅ็นๅฎๆถ้ดๆฎต๏ผMP3ใAACใWAV๏ผใ",
+ "title": "ไฟฎๅช้ณ้ข"
+ }
+}
diff --git a/public/locales/zh/csv.json b/public/locales/zh/csv.json
new file mode 100644
index 0000000..2383050
--- /dev/null
+++ b/public/locales/zh/csv.json
@@ -0,0 +1,114 @@
+{
+ "changeCsvSeparator": {
+ "description": "ๆดๆน CSV ๆไปถไธญ็ๅ้็ฌฆใๅจไธๅ็ CSV ๆ ผๅผ๏ผไพๅฆ้ๅทใๅๅทใๅถ่กจ็ฌฆๆ่ชๅฎไนๅ้็ฌฆ๏ผไน้ด่ฟ่ก่ฝฌๆขใ",
+ "shortDescription": "ๆดๆน CSV ๆไปถๅ้็ฌฆ",
+ "title": "ๆดๆน CSV ๅ้็ฌฆ"
+ },
+ "csvRowsToColumns": {
+ "description": "ๆญคๅทฅๅ
ทๅฏๅฐ CSV๏ผ้ๅทๅ้ๅผ๏ผๆไปถ็่ก่ฝฌๆขไธบๅใๅฎไผไป่พๅ
ฅ็ CSV ๆไปถไธญ้่กๆๅๆฐดๅนณ็บฟ๏ผๅฐๅ
ถๆ่ฝฌ 90 ๅบฆ๏ผ็ถๅๅฐๅ
ถ่พๅบไธบๅ็ดๅ๏ผๅนถไปฅ้ๅทๅ้ใ', longDescription: 'ๆญคๅทฅๅ
ทๅฏๅฐ CSV๏ผ้ๅทๅ้ๅผ๏ผๆไปถ็่ก่ฝฌๆขไธบๅใไพๅฆ๏ผๅฆๆ่พๅ
ฅ็ CSV ๆฐๆฎๆ 6 ่ก๏ผๅ่พๅบๅฐๆ 6 ๅ๏ผๅนถไธ่กไธญ็ๅ
็ด ๅฐๆไปไธๅฐไธ็้กบๅบๆๅใๅจๆ ผๅผๆญฃ็กฎ็ CSV ๆไปถไธญ๏ผๆฏ่ก็ๅผๆฐ้็ธๅใไฝๆฏ๏ผๅฆๆ่กไธญ็ผบๅฐๅญๆฎต๏ผ็จๅบๅฏไปฅไฟฎๅคๅฎไปฌ๏ผๆจๅฏไปฅไปๅฏ็จ้้กนไธญ่ฟ่ก้ๆฉ๏ผ็จ็ฉบๅ
็ด ๅกซๅ
็ผบๅคฑๆฐๆฎ๏ผๆ็จ่ชๅฎไนๅ
็ด ๏ผไพๅฆโmissingโใโ?โๆโxโ๏ผๆฟๆข็ผบๅคฑๆฐๆฎใๅจ่ฝฌๆข่ฟ็จไธญ๏ผ่ฏฅๅทฅๅ
ท่ฟไผๆธ
้ค CSV ๆไปถไธญ็ไธๅฟ
่ฆไฟกๆฏ๏ผไพๅฆ็ฉบ่ก๏ผ่ฟไบ่กๆฒกๆๅฏ่ง็ไฟกๆฏ๏ผๅๆณจ้ใไธบไบๅธฎๅฉๅทฅๅ
ทๆญฃ็กฎ่ฏๅซๆณจ้๏ผๆจๅฏไปฅๅจ้้กนไธญๆๅฎ่ก้ฆ็ๆณจ้็ฌฆๅทใๆญค็ฌฆๅท้ๅธธๆฏไบๅทโ#โๆๅๆๆ โ//โใCSV ็ๆฃ๏ผ",
+ "longDescription": "ๆญคๅทฅๅ
ทๅฏๅฐ CSV๏ผ้ๅทๅ้ๅผ๏ผๆไปถ็่ก่ฝฌๆขไธบๅใไพๅฆ๏ผๅฆๆ่พๅ
ฅ็ CSV ๆฐๆฎๆ 6 ่ก๏ผๅ่พๅบๅฐๆ 6 ๅ๏ผๅนถไธ่กไธญ็ๅ
็ด ๅฐๆไปไธๅฐไธ็้กบๅบๆๅใๅจๆ ผๅผๆญฃ็กฎ็ CSV ๆไปถไธญ๏ผๆฏ่ก็ๅผๆฐ้็ธๅใไฝๆฏ๏ผๅฆๆ่กไธญ็ผบๅฐๅญๆฎต๏ผ็จๅบๅฏไปฅไฟฎๅคๅฎไปฌ๏ผๆจๅฏไปฅไปไปฅไธ้้กนไธญ่ฟ่ก้ๆฉ๏ผ็จ็ฉบๅ
็ด ๅกซๅ
็ผบๅคฑๆฐๆฎ๏ผๆ็จ่ชๅฎไนๅ
็ด ๆฟๆข็ผบๅคฑๆฐๆฎ๏ผไพๅฆ",
+ "shortDescription": "ๅฐ CSV ่ก่ฝฌๆขไธบๅใ",
+ "title": "ๅฐ CSV ่ก่ฝฌๆขไธบๅ"
+ },
+ "csvToJson": {
+ "columnSeparator": "ๅๅ้็ฌฆ๏ผไพๅฆ๏ผ๏ผ๏ผ\\t๏ผ",
+ "commentSymbol": "ๆณจ้็ฌฆๅท๏ผไพๅฆ #๏ผ",
+ "conversionOptions": "่ฝฌๆข้้กน",
+ "description": "ๅฐ CSV ๆไปถ่ฝฌๆขไธบ JSON ๆ ผๅผ๏ผๅนถๅฏ่ชๅฎไนๅ้็ฌฆใๅผๅทๅ่พๅบๆ ผๅผใๆฏๆๆ ้ขใๆณจ้ๅๅจๆ็ฑปๅ่ฝฌๆขใ",
+ "dynamicTypes": "ๅจๆ็ฑปๅ",
+ "dynamicTypesDescription": "่ชๅจ่ฝฌๆขๆฐๅญๅๅธๅฐๅผ",
+ "errorParsing": "่งฃๆ CSV ๆถๅบ้๏ผ {{error}}",
+ "fieldQuote": "ๅญๆฎตๅผๅท๏ผไพๅฆโ๏ผ",
+ "inputCsvFormat": "่พๅ
ฅ CSV ๆ ผๅผ",
+ "inputTitle": "่พๅ
ฅ CSV",
+ "resultTitle": "่พๅบ JSON",
+ "shortDescription": "ๅฐ CSV ๆฐๆฎ่ฝฌๆขไธบ JSON ๆ ผๅผใ",
+ "skipEmptyLines": "่ทณ่ฟ็ฉบ่ก",
+ "skipEmptyLinesDescription": "ๅฟฝ็ฅ่พๅ
ฅ CSV ไธญ็็ฉบ่ก",
+ "title": "ๅฐ CSV ่ฝฌๆขไธบ JSON",
+ "useHeaders": "ไฝฟ็จๆ ้ข",
+ "useHeadersDescription": "ๅฐ็ฌฌไธ่ก่งไธบๅๆ ้ข"
+ },
+ "csvToTsv": {
+ "description": "ไฝฟ็จไธๆน่กจๅไธไผ ๆจ็ CSV ๆไปถ๏ผๅฎๅฐ่ชๅจ่ฝฌๆขไธบ TSV ๆไปถใๅจๅทฅๅ
ท้้กนไธญ๏ผๆจๅฏไปฅ่ชๅฎไน่พๅ
ฅ็ CSV ๆ ผๅผโโๆๅฎๅญๆฎตๅ้็ฌฆใๅผๅทๅๆณจ้็ฌฆๅท๏ผไปฅๅ่ทณ่ฟ็ฉบ็ CSV ่ก๏ผๅนถ้ๆฉๆฏๅฆไฟ็ CSV ๅๆ ้ขใ",
+ "longDescription": "ๆญคๅทฅๅ
ทๅฐ้ๅทๅ้ๅผ (CSV) ๆฐๆฎ่ฝฌๆขไธบๅถ่กจ็ฌฆๅ้ๅผ (TSV)ใCSV ๅ TSV ้ฝๆฏ็จไบๅญๅจ่กจๆ ผๆฐๆฎ็ๅธธ็จๆไปถๆ ผๅผ๏ผไฝๅฎไปฌไฝฟ็จไธๅ็ๅ้็ฌฆๆฅๅ้ๅผโโCSV ไฝฟ็จ้ๅท (",
+ "shortDescription": "ๅฐ CSV ๆฐๆฎ่ฝฌๆขไธบ TSV ๆ ผๅผใ",
+ "title": "ๅฐ CSV ่ฝฌๆขไธบ TSV"
+ },
+ "csvToXml": {
+ "description": "ไฝฟ็จๅฏ่ชๅฎไน็้้กนๅฐ CSV ๆไปถ่ฝฌๆขไธบ XML ๆ ผๅผใ",
+ "shortDescription": "ๅฐ CSV ๆฐๆฎ่ฝฌๆขไธบ XML ๆ ผๅผใ",
+ "title": "ๅฐ CSV ่ฝฌๆขไธบ XML"
+ },
+ "csvToYaml": {
+ "description": "ๅช้ๅจไธๆน่กจๅไธญไธไผ ๆจ็ CSV ๆไปถ๏ผๅฎๅฐฑไผ่ชๅจ่ฝฌๆขไธบ YAML ๆไปถใๅจๅทฅๅ
ท้้กนไธญ๏ผๆจๅฏไปฅๆๅฎๅญๆฎตๅ้็ฌฆใๅญๆฎตๅผๅทๅๆณจ้็ฌฆ๏ผไปฅไฝฟๅทฅๅ
ท้ๅบ่ชๅฎไน CSV ๆ ผๅผใๆญคๅค๏ผๆจ่ฟๅฏไปฅ้ๆฉ่พๅบ YAML ๆ ผๅผ๏ผไฟ็ CSV ๆ ๅคดๆไธๅ
ๅซ CSV ๆ ๅคดใ",
+ "longDescription": "ๆญคๅทฅๅ
ทๅฏๅฐ CSV๏ผ้ๅทๅ้ๅผ๏ผๆฐๆฎ่ฝฌๆขไธบ YAML๏ผๅฆไธ็งๆ ่ฎฐ่ฏญ่จ๏ผๆฐๆฎใCSV ๆฏไธ็ง็ฎๅ็่กจๆ ผๆ ผๅผ๏ผ็จไบ่กจ็คบ็ฑ่กๅๅ็ปๆ็็ฉ้ตๅผๆฐๆฎ็ฑปๅใ่ YAML ๆฏไธ็งๆด้ซ็บง็ๆ ผๅผ๏ผๅฎ้
ไธๆฏ JSON ็่ถ
้๏ผ๏ผๅฎ่ฝๅคๅๅปบๆดๆไบๅบๅๅ็ๆฐๆฎ๏ผๅนถไธๆฏๆๅ่กจใๅญๅ
ธๅๅตๅฅๅฏน่ฑกใๆญค็จๅบๆฏๆๅค็ง CSV ่พๅ
ฅๆ ผๅผโโ่พๅ
ฅๆฐๆฎๅฏไปฅไฝฟ็จ้ๅทๅ้๏ผ้ป่ฎค๏ผใๅๅทๅ้ใ็ซ็บฟๅ้ๆไฝฟ็จๅ
ถไปๅฎๅ
จไธๅ็ๅ้็ฌฆใๆจๅฏไปฅๅจ้้กนไธญๆๅฎๆฐๆฎไฝฟ็จ็็กฎๅๅ้็ฌฆใๅๆ ท๏ผๆจๅฏไปฅๅจ้้กนไธญๆๅฎ็จไบๅ
่ฃ
CSV ๅญๆฎต็ๅผๅทๅญ็ฌฆ๏ผ้ป่ฎคไธบๅๅผๅท๏ผใๆจ่ฟๅฏไปฅ้่ฟๅจ้้กนไธญๆๅฎๆณจ้็ฌฆๅทๆฅ่ทณ่ฟไปฅๆณจ้ๅผๅคด็่กใ่ฟๆ ทๅฏไปฅ้่ฟ่ทณ่ฟไธๅฟ
่ฆ็่กๆฅไฟๆๆฐๆฎๆดๆดใๆไธค็งๆนๆณๅฏไปฅๅฐ CSV ่ฝฌๆขไธบ YAMLใ็ฌฌไธ็งๆนๆณๅฐๆฏไธช CSV ่ก่ฝฌๆขไธบ YAML ๅ่กจใ็ฌฌไบ็งๆนๆณไป็ฌฌไธไธช CSV ่กไธญๆๅๆ ้ข๏ผๅนถๆ นๆฎ่ฟไบๆ ้ขๅๅปบๅธฆๆ้ฎ็ YAML ๅฏน่ฑกใๆจ่ฟๅฏไปฅ้่ฟๆๅฎ YAML ็ปๆ็ผฉ่ฟ็็ฉบๆ ผๆฐๆฅ่ชๅฎไน่พๅบ YAML ๆ ผๅผใๅฆๆๆจ้่ฆๆง่กๅๅ่ฝฌๆข๏ผๅณๅฐ YAML ่ฝฌๆขไธบ CSV๏ผๅฏไปฅไฝฟ็จๆไปฌ็โๅฐ YAML ่ฝฌๆขไธบ CSVโๅทฅๅ
ทใCSV ็ๆฃ๏ผ",
+ "shortDescription": "ๅฟซ้ๅฐ CSV ๆไปถ่ฝฌๆขไธบ YAML ๆไปถใ",
+ "title": "ๅฐ CSV ่ฝฌๆขไธบ YAML"
+ },
+ "findIncompleteCsvRecords": {
+ "checkingOptions": "ๆฃๆฅ้้กน",
+ "commentCharacterDescription": "่พๅ
ฅ่กจ็คบๆณจ้่กๅผๅง็ๅญ็ฌฆใไปฅๆญค็ฌฆๅทๅผๅคด็่กๅฐ่ขซ่ทณ่ฟใ",
+ "csvInputOptions": "CSV ่พๅ
ฅ้้กน",
+ "csvSeparatorDescription": "่พๅ
ฅ็จไบๅ้ CSV ่พๅ
ฅๆไปถไธญๅ็ๅญ็ฌฆใ",
+ "deleteLinesWithNoData": "ๅ ้คๆฒกๆๆฐๆฎ็่ก",
+ "deleteLinesWithNoDataDescription": "ไป CSV ่พๅ
ฅๆไปถไธญๅ ้ค็ฉบ่กใ",
+ "description": "ๅช้ๅฐๆจ็ CSV ๆไปถไธไผ ๅฐไธๆน่กจๅ๏ผๆญคๅทฅๅ
ทๅฐฑไผ่ชๅจๆฃๆฅๆๆ่กๆๅๆฏๅฆๅ็ผบๅคฑๅผใๅจๅทฅๅ
ท้้กนไธญ๏ผๆจๅฏไปฅ่ฐๆด่พๅ
ฅๆไปถๆ ผๅผ๏ผๆๅฎๅ้็ฌฆใๅผๅทๅๆณจ้็ฌฆ๏ผใๆญคๅค๏ผๆจ่ฟๅฏไปฅๅฏ็จ็ฉบๅผๆฃๆฅใ่ทณ่ฟ็ฉบ่ก๏ผไปฅๅ่ฎพ็ฝฎ่พๅบไธญ้่ฏฏๆถๆฏ็ๆฐ้้ๅถใ",
+ "findEmptyValues": "ๆฅๆพ็ฉบๅผ",
+ "findEmptyValuesDescription": "ๆพ็คบๆๅ
ณ CSV ๅญๆฎตไธบ็ฉบ็ๆถๆฏ๏ผ่ฟไบไธๆฏ็ผบๅคฑ็ๅญๆฎต๏ผ่ๆฏไธๅ
ๅซไปปไฝๅ
ๅฎน็ๅญๆฎต๏ผใ",
+ "inputTitle": "่พๅ
ฅ CSV",
+ "limitNumberOfMessages": "้ๅถๆถๆฏๆฐ้",
+ "messageLimitDescription": "่ฎพ็ฝฎ่พๅบไธญๆถๆฏๆฐ้็้ๅถใ",
+ "quoteCharacterDescription": "่พๅ
ฅ็จไบๅผ็จ CSV ่พๅ
ฅๅญๆฎต็ๅผๅทๅญ็ฌฆใ",
+ "resultTitle": "CSV ็ถๆ",
+ "shortDescription": "ๅฟซ้ๆฅๆพ CSV ไธญ็ผบๅฐๅผ็่กๅๅใ",
+ "title": "ๆฅๆพไธๅฎๆด็ CSV ่ฎฐๅฝ",
+ "toolInfo": {
+ "title": "ไปไนๆฏ {{title}}๏ผ"
+ }
+ },
+ "insertCsvColumns": {
+ "appendColumns": "้ๅ ๅ",
+ "commentCharacterDescription": "่พๅ
ฅ่กจ็คบๆณจ้่กๅผๅง็ๅญ็ฌฆใไปฅๆญค็ฌฆๅทๅผๅคด็่กๅฐ่ขซ่ทณ่ฟใ",
+ "csvOptions": "CSV ้้กน",
+ "csvSeparator": "CSV ๅ้็ฌฆ",
+ "csvToInsert": "่ฆๆๅ
ฅ็ CSV",
+ "csvToInsertDescription": "่พๅ
ฅ่ฆๆๅ
ฅๅฐ CSV ไธญ็ไธไธชๆๅคไธชๅใ็จไบๅ้ๅ็ๅญ็ฌฆๅฟ
้กปไธ CSV ่พๅ
ฅๆไปถไธญ็ๅญ็ฌฆ็ธๅใๆณจ๏ผ็ฉบ่กๅฐ่ขซๅฟฝ็ฅ",
+ "customFillDescription": "ๅฆๆ่พๅ
ฅ็ CSV ๆไปถไธๅฎๆด๏ผ็ผบๅฐๅผ๏ผ๏ผๅๅ่ฎฐๅฝไธญๆทปๅ ็ฉบๅญๆฎตๆ่ชๅฎไน็ฌฆๅทไปฅๅถไฝๆ ผๅผ่ฏๅฅฝ็ CSV๏ผ",
+ "customFillValueDescription": "ไฝฟ็จๆญค่ชๅฎไนๅผๅกซๅ็ผบๅคฑ็ๅญๆฎตใ๏ผไป
้็จไบไธ่ฟฐโ่ชๅฎไนๅผโๆจกๅผใ๏ผ",
+ "customPosition": "่ชๅฎไนไฝ็ฝฎ",
+ "customPositionOptionsDescription": "้ๆฉๅจ CSV ๆไปถไธญๆๅ
ฅๅ็ๆนๆณใ",
+ "description": "ๅจๆๅฎไฝ็ฝฎๅ CSV ๆฐๆฎๆทปๅ ๆฐๅใ",
+ "fillWithCustomValues": "ๅกซๅๆตทๅ
ณไปทๅผ",
+ "fillWithEmptyValues": "ๅกซๅ
็ฉบๅผ",
+ "headerName": "ๆ ๅคดๅ็งฐ",
+ "headerNameDescription": "ๆจๆณ่ฆๅจๅ
ถๅๆๅ
ฅๅ็ๅๆ ้ขใ",
+ "inputTitle": "่พๅ
ฅ CSV",
+ "insertingPositionDescription": "ๆๅฎๅจ CSV ๆไปถไธญๆๅ
ฅๅ็ไฝ็ฝฎใ",
+ "position": "ไฝ็ฝฎ",
+ "positionOptions": "ไฝ็ฝฎ้้กน",
+ "prependColumns": "ๆทปๅ ๅ",
+ "quoteCharDescription": "่พๅ
ฅ็จไบๅผ็จ CSV ่พๅ
ฅๅญๆฎต็ๅผๅทๅญ็ฌฆใ",
+ "resultTitle": "่พๅบ CSV",
+ "rowNumberDescription": "ๆจๆณ่ฆๅจๅ
ถๅๆๅ
ฅๅ็ๅๅทใ",
+ "separatorDescription": "่พๅ
ฅ็จไบๅ้ CSV ่พๅ
ฅๆไปถไธญๅ็ๅญ็ฌฆใ",
+ "shortDescription": "ๅจ CSV ๆไปถไธญ็ไปปไฝไฝ็ฝฎๅฟซ้ๆๅ
ฅไธไธชๆๅคไธชๆฐๅใ",
+ "title": "ๆๅ
ฅ CSV ๅ",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจๅจ CSV ๆฐๆฎ็ๆๅฎไฝ็ฝฎๆๅ
ฅๆฐๅใๆจๅฏไปฅๆ นๆฎๆ ้ขๅ็งฐๆๅๅทๅจ่ชๅฎไนไฝ็ฝฎๆทปๅ ใ่ฟฝๅ ๆๆๅ
ฅๅใ",
+ "title": "ๆๅ
ฅ CSV ๅ"
+ }
+ },
+ "swapCsvColumns": {
+ "description": "ๅช้ๅจไธๆน่กจๅไธญไธไผ ๆจ็ CSV ๆไปถ๏ผๆๅฎ่ฆไบคๆข็ๅ๏ผ่ฏฅๅทฅๅ
ทๅฐฑไผ่ชๅจๆดๆน่พๅบๆไปถไธญๆๅฎๅ็ไฝ็ฝฎใๅจๅทฅๅ
ท้้กนไธญ๏ผๆจๅฏไปฅๆๅฎ่ฆไบคๆข็ๅไฝ็ฝฎๆๅ็งฐ๏ผ่ฟๅฏไปฅไฟฎๅคไธๅฎๆด็ๆฐๆฎ๏ผๅนถ้ๆฉๆงๅฐๅ ้ค็ฉบ่ฎฐๅฝๅๅทฒๆณจ้ๆ็่ฎฐๅฝใ",
+ "longDescription": "ๆญคๅทฅๅ
ท้่ฟไบคๆขๅ็ไฝ็ฝฎๆฅ้ๆฐ็ป็ป CSV ๆฐๆฎใไบคๆขๅๅฏไปฅๅฐๅธธ็จๆฐๆฎๆพๅจไธ่ตทๆๆพๅจๆๅ้ข๏ผไปฅไพฟไบๆฐๆฎๆฏ่พๅ็ผ่พ๏ผไป่ๆ้ซ CSV ๆไปถ็ๅฏ่ฏปๆงใไพๅฆ๏ผๆจๅฏไปฅๅฐ็ฌฌไธๅไธๆๅไธๅไบคๆข๏ผๆ่
ๅฐ็ฌฌไบๅไธ็ฌฌไธๅไบคๆขใ่ฆๆ นๆฎๅ็ไฝ็ฝฎไบคๆขๅ๏ผ่ฏท้ๆฉ",
+ "shortDescription": "้ๆฐๆๅบ CSV ๅใ",
+ "title": "ไบคๆข CSV ๅ"
+ },
+ "transposeCsv": {
+ "description": "ๅช้ไฝฟ็จไธๆน่กจๆ ผไธไผ ๆจ็ CSV ๆไปถ๏ผๆญคๅทฅๅ
ทๅฐฑไผ่ชๅจ่ฝฌ็ฝฎๆจ็ CSV ๆไปถใๅจๅทฅๅ
ท้้กนไธญ๏ผๆจๅฏไปฅๆๅฎ CSV ๆไปถไธญๆณจ้่ก็่ตทๅงๅญ็ฌฆ๏ผไปฅๅฐๅ
ถ็งป้คใๆญคๅค๏ผๅฆๆ CSV ๆไปถไธๅฎๆด๏ผ็ผบๅฐๅผ๏ผ๏ผๆจๅฏไปฅไฝฟ็จ็ฉบๅญ็ฌฆๆ่ชๅฎไนๅญ็ฌฆๆฟๆข็ผบๅคฑๅผใ",
+ "longDescription": "ๆญคๅทฅๅ
ท็จไบ่ฝฌ็ฝฎ้ๅทๅ้ๅผ (CSV)ใๅฎๅฐ CSV ่งไธบๆฐๆฎ็ฉ้ต๏ผๅนถๅฐๆๆๅ
็ด ๆฒฟไธปๅฏน่ง็บฟ็ฟป่ฝฌใ่พๅบๅ
ๅซไธ่พๅ
ฅ็ธๅ็ CSV ๆฐๆฎ๏ผไฝ็ฐๅจๆๆ่ก้ฝๅๆไบๅ๏ผๆๆๅ้ฝๅๆไบ่กใ่ฝฌ็ฝฎๅ๏ผCSV ๆไปถ็ๅฐบๅฏธๅฐ็ธๅใไพๅฆ๏ผๅฆๆ่พๅ
ฅๆไปถๆ 4 ๅ 3 ่ก๏ผๅ่พๅบๆไปถๅฐๆ 3 ๅ 4 ่กใๅจ่ฝฌๆข่ฟ็จไธญ๏ผ็จๅบ่ฟไผๆธ
้คๆฐๆฎไธญไธๅฟ
่ฆ็่ก๏ผๅนถๆดๆญฃไธๅฎๆด็ๆฐๆฎใๅ
ทไฝๆฅ่ฏด๏ผ่ฏฅๅทฅๅ
ทไผ่ชๅจๅ ้คๆๆไปฅ็นๅฎๅญ็ฌฆๅผๅคด็็ฉบ่ฎฐๅฝๅๆณจ้๏ผๆจๅฏไปฅๅจ้้กนไธญ่ฎพ็ฝฎ่ฟไบๅญ็ฌฆใๆญคๅค๏ผๅฆๆ CSV ๆฐๆฎๆๅๆไธขๅคฑ๏ผ่ฏฅๅฎ็จ็จๅบไผไฝฟ็จ็ฉบๅญๆฎตๆ่ชๅฎไนๅญๆฎต๏ผๅฏๅจ้้กนไธญๆๅฎ๏ผๆฅๅกซๅ
ๆไปถใCSV ็ๆฏๅคชๆฃไบ๏ผ",
+ "shortDescription": "ๅฟซ้่ฝฌ็ฝฎ CSV ๆไปถใ",
+ "title": "่ฝฌ็ฝฎ CSV"
+ }
+}
diff --git a/public/locales/zh/image.json b/public/locales/zh/image.json
new file mode 100644
index 0000000..870131b
--- /dev/null
+++ b/public/locales/zh/image.json
@@ -0,0 +1,98 @@
+{
+ "changeColors": {
+ "description": "ไธ็",
+ "shortDescription": "ๅฟซ้ไบคๆขๅพๅไธญ็้ข่ฒ",
+ "title": "ๆนๅๅพๅ็้ข่ฒ"
+ },
+ "changeOpacity": {
+ "description": "่ฝปๆพ่ฐๆดๅพ็้ๆๅบฆใๅช้ไธไผ ๅพ็๏ผไฝฟ็จๆปๅๅจ 0๏ผๅฎๅ
จ้ๆ๏ผๅ 1๏ผๅฎๅ
จไธ้ๆ๏ผไน้ด่ฎพ็ฝฎๆ้็ไธ้ๆๅบฆ๏ผ็ถๅไธ่ฝฝไฟฎๆนๅ็ๅพ็ๅณๅฏใ",
+ "shortDescription": "่ฐๆดๅพๅ็้ๆๅบฆ",
+ "title": "ๆดๆนๅพๅไธ้ๆๅบฆ"
+ },
+ "compress": {
+ "description": "ๅจไฟๆ่ดจ้็ๅๆถๅๅฐๅพๅๆไปถๅคงๅฐใ",
+ "inputTitle": "่พๅ
ฅๅพๅ",
+ "resultTitle": "ๅ็ผฉๅพๅ",
+ "shortDescription": "ๅ็ผฉๅพๅไปฅๅๅฐๆไปถๅคงๅฐ๏ผๅๆถไฟๆๅ็็่ดจ้ใ",
+ "title": "ๅ็ผฉๅพๅ"
+ },
+ "compressPng": {
+ "description": "่ฟๆฏไธไธชๅ็ผฉ PNG ๅพ็็็จๅบใๅช่ฆๆจๅฐ PNG ๅพ็็ฒ่ดดๅฐ่พๅ
ฅๅบๅ๏ผ็จๅบๅฐฑไผๅฏนๅ
ถ่ฟ่กๅ็ผฉ๏ผๅนถๅจ่พๅบๅบๅๆพ็คบ็ปๆใๅจ้้กนไธญ๏ผๆจๅฏไปฅ่ฐๆดๅ็ผฉ็บงๅซ๏ผไปฅๅๆฅ็ๆฐๆงๅพ็ๆไปถ็ๅคงๅฐใ",
+ "shortDescription": "ๅฟซ้ๅ็ผฉ PNG",
+ "title": "ๅ็ผฉ png"
+ },
+ "convertJgpToPng": {
+ "description": "ๅฟซ้ๅฐๆจ็ JPG ๅพๅ่ฝฌๆขไธบ PNGใๅช้ๅจๅทฆไพง็็ผ่พๅจไธญๅฏผๅ
ฅๆจ็ PNG ๅพๅๅณๅฏ",
+ "shortDescription": "ๅฟซ้ๅฐๆจ็ JPG ๅพๅ่ฝฌๆขไธบ PNG",
+ "title": "JPG ่ฝฌๆขไธบ PNG"
+ },
+ "convertToJpg": {
+ "description": "ๅฐๅ็งๅพๅๆ ผๅผ๏ผPNGใGIFใTIFใPSDใSVGใWEBPใHEICใRAW๏ผ่ฝฌๆขไธบ JPG๏ผๅนถๅฏ่ชๅฎไน่ดจ้ๅ่ๆฏ้ข่ฒ่ฎพ็ฝฎใ",
+ "shortDescription": "ๅฐๅพๅ่ฝฌๆขไธบ JPG ๆ ผๅผๅนถ่ฟ่ก่ดจ้ๆงๅถ",
+ "title": "ๅฐๅพๅ่ฝฌๆขไธบ JPG"
+ },
+ "createTransparent": {
+ "description": "ไธ็",
+ "shortDescription": "ๅฟซ้ไฝฟๅพๅ้ๆ",
+ "title": "ๅๅปบ้ๆ PNG"
+ },
+ "crop": {
+ "description": "่ฃๅชๅพๅไปฅๅ ้คไธ้่ฆ็ๅบๅใ",
+ "inputTitle": "่พๅ
ฅๅพๅ",
+ "resultTitle": "่ฃๅชๅพๅ",
+ "shortDescription": "ๅฟซ้่ฃๅชๅพๅใ",
+ "title": "่ฃๅชๅพ็"
+ },
+ "editor": {
+ "description": "้ซ็บงๅพๅ็ผ่พๅจ๏ผๅ
ๅซ่ฃๅชใๆ่ฝฌใๆณจ้ใ่ฐๆด้ข่ฒๅๆทปๅ ๆฐดๅฐ็ญๅทฅๅ
ทใ็ดๆฅๅจๆต่งๅจไธญไฝฟ็จไธไธ็บงๅทฅๅ
ท็ผ่พๅพๅใ",
+ "shortDescription": "ไฝฟ็จ้ซ็บงๅทฅๅ
ทๅๅ่ฝ็ผ่พๅพๅ",
+ "title": "ๅพๅ็ผ่พๅจ"
+ },
+ "imageToText": {
+ "description": "ไฝฟ็จๅ
ๅญฆๅญ็ฌฆ่ฏๅซ (OCR) ไปๅพๅ (JPGใPNG) ไธญๆๅๆๆฌใ",
+ "shortDescription": "ไฝฟ็จ OCR ไปๅพๅไธญๆๅๆๆฌใ",
+ "title": "ๅพๅ่ฝฌๆๆฌ (OCR)"
+ },
+ "qrCode": {
+ "description": "ไธบไธๅๆฐๆฎ็ฑปๅ็ๆไบ็ปด็ ๏ผURLใๆๆฌใ็ตๅญ้ฎไปถใ็ต่ฏใ็ญไฟกใWiFiใvCard ็ญใ",
+ "shortDescription": "ไธบๅ็งๆฐๆฎๆ ผๅผๅๅปบๅฎๅถ็ไบ็ปด็ ใ",
+ "title": "ไบ็ปด็ ็ๆๅจ"
+ },
+ "removeBackground": {
+ "description": "ไธ็",
+ "shortDescription": "่ชๅจๅ ้คๅพๅ็่ๆฏ",
+ "title": "ไปๅพๅไธญๅ ้ค่ๆฏ"
+ },
+ "resize": {
+ "description": "ๅฐๅพๅ่ฐๆดไธบไธๅ็ๅฐบๅฏธใ",
+ "dimensionType": "ๅฐบๅฏธ็ฑปๅ",
+ "heightDescription": "้ซๅบฆ๏ผๅ็ด ๏ผ",
+ "inputTitle": "่พๅ
ฅๅพๅ",
+ "maintainAspectRatio": "ไฟๆ็บตๆจชๆฏ",
+ "maintainAspectRatioDescription": "ไฟๆๅพๅ็ๅๅง็บตๆจชๆฏใ",
+ "percentage": "็พๅๆฏ",
+ "percentageDescription": "ๅๅงๅคงๅฐ็็พๅๆฏ๏ผไพๅฆ๏ผ50 ่กจ็คบไธๅๅคงๅฐ๏ผ200 ่กจ็คบไธคๅๅคงๅฐ๏ผ",
+ "resizeByPercentage": "ๆ็พๅๆฏ่ฐๆดๅคงๅฐ",
+ "resizeByPercentageDescription": "้่ฟๆๅฎๅๅงๅคงๅฐ็็พๅๆฏๆฅ่ฐๆดๅคงๅฐใ",
+ "resizeByPixels": "ๆๅ็ด ่ฐๆดๅคงๅฐ",
+ "resizeByPixelsDescription": "้่ฟๆๅฎๅ็ด ๅฐบๅฏธๆฅ่ฐๆดๅคงๅฐใ",
+ "resizeMethod": "่ฐๆดๅคงๅฐๆนๆณ",
+ "resultTitle": "่ฐๆดๅคงๅฐ็ๅพๅ",
+ "setHeight": "่ฎพ็ฝฎ้ซๅบฆ",
+ "setHeightDescription": "ไปฅๅ็ด ไธบๅไฝๆๅฎ้ซๅบฆๅนถๆ นๆฎ็บตๆจชๆฏ่ฎก็ฎๅฎฝๅบฆใ",
+ "setWidth": "่ฎพ็ฝฎๅฎฝๅบฆ",
+ "setWidthDescription": "ไปฅๅ็ด ไธบๅไฝๆๅฎๅฎฝๅบฆๅนถๆ นๆฎ็บตๆจชๆฏ่ฎก็ฎ้ซๅบฆใ",
+ "shortDescription": "่ฝปๆพ่ฐๆดๅพๅๅคงๅฐใ",
+ "title": "่ฐๆดๅพๅๅคงๅฐ",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจ่ฐๆด JPGใPNGใSVG ๆ GIF ๅพๅ็ๅคงๅฐใๆจๅฏไปฅๆๅฎๅ็ด ๆ็พๅๆฏๆฅ่ฐๆดๅคงๅฐ๏ผๅนถๅฏ้ๆฉไฟๆๅๅงๅฎฝ้ซๆฏใ",
+ "title": "่ฐๆดๅพๅๅคงๅฐ"
+ },
+ "widthDescription": "ๅฎฝๅบฆ๏ผๅ็ด ๏ผ"
+ },
+ "rotate": {
+ "description": "ๆๆๅฎ่งๅบฆๆ่ฝฌๅพๅใ",
+ "shortDescription": "่ฝปๆพๆ่ฝฌๅพๅใ",
+ "title": "ๆ่ฝฌๅพๅ"
+ }
+}
diff --git a/public/locales/zh/json.json b/public/locales/zh/json.json
new file mode 100644
index 0000000..94366ff
--- /dev/null
+++ b/public/locales/zh/json.json
@@ -0,0 +1,62 @@
+{
+ "escapeJson": {
+ "description": "่ฝฌไน JSON ๅญ็ฌฆไธฒไธญ็็นๆฎๅญ็ฌฆใๅฐ JSON ๆฐๆฎ่ฝฌๆขไธบๆญฃ็กฎ็่ฝฌไนๆ ผๅผ๏ผไปฅไพฟๅฎๅ
จไผ ่พๆๅญๅจใ",
+ "shortDescription": "่ฝฌไน JSON ไธญ็็นๆฎๅญ็ฌฆ",
+ "title": "่ฝฌไน JSON"
+ },
+ "jsonToXml": {
+ "description": "ๅฐ JSON ๆฐๆฎ่ฝฌๆขไธบ XML ๆ ผๅผใๅฐ็ปๆๅ็ JSON ๅฏน่ฑก่ฝฌๆขไธบๆ ผๅผ่ฏๅฅฝ็ XML ๆๆกฃใ",
+ "shortDescription": "ๅฐ JSON ่ฝฌๆขไธบ XML ๆ ผๅผ",
+ "title": "JSON ๅฐ XML"
+ },
+ "minify": {
+ "description": "ไป JSON ไธญๅ ้คๆๆไธๅฟ
่ฆ็็ฉบๆ ผใ",
+ "inputTitle": "่พๅ
ฅ JSON",
+ "resultTitle": "ๆๅฐๅ JSON",
+ "shortDescription": "้่ฟๅ ้ค็ฉบๆ ผๆฅ็ผฉๅฐ JSON",
+ "title": "ๆๅฐๅ JSON",
+ "toolInfo": {
+ "description": "JSON ๅ็ผฉๆฏๆๅจไฟๆ JSON ๆฐๆฎๆๆๆง็ๅๆถ๏ผไปไธญ็งป้คๆๆไธๅฟ
่ฆ็็ฉบๆ ผๅญ็ฌฆ็่ฟ็จใ่ฟๅ
ๆฌ็งป้ค JSON ๆญฃ็กฎ่งฃๆๆ้็็ฉบๆ ผใๆข่ก็ฌฆๅ็ผฉ่ฟใๅ็ผฉๅฏไปฅๅๅฐ JSON ๆฐๆฎ็ๅคงๅฐ๏ผไฝฟๅ
ถๅจไฟๆๅฎๅ
จ็ธๅ็ๆฐๆฎ็ปๆๅๅผ็ๅๆถ๏ผๆด้ซๆๅฐๅญๅจๅไผ ่พใ",
+ "title": "ไปไนๆฏ JSON ๆๅฐๅ๏ผ"
+ }
+ },
+ "prettify": {
+ "description": "ไฝฟ็จ้ๅฝ็็ผฉ่ฟๅ้ด่ทๆฅๆ ผๅผๅ JSONใ",
+ "indentation": "็ผฉ่ฟ",
+ "inputTitle": "่พๅ
ฅ JSON",
+ "resultTitle": "็พๅ JSON",
+ "shortDescription": "ๆ ผๅผๅๅนถ็พๅ JSON ไปฃ็ ",
+ "title": "็พๅ JSON",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจไฝฟ็จ้ๅฝ็็ผฉ่ฟๅ้ด่ทๆ ผๅผๅ JSON ๆฐๆฎ๏ผไฝฟๅ
ถๆดๅ
ทๅฏ่ฏปๆงไธๆดๆไบไฝฟ็จใ",
+ "title": "็พๅ JSON"
+ },
+ "useSpaces": "ไฝฟ็จ็ฉบๆ ผ",
+ "useSpacesDescription": "ไฝฟ็จ็ฉบๆ ผ็ผฉ่ฟ่พๅบ",
+ "useTabs": "ไฝฟ็จๆ ็ญพ",
+ "useTabsDescription": "ไฝฟ็จๅถ่กจ็ฌฆ็ผฉ่ฟ่พๅบใ"
+ },
+ "stringify": {
+ "description": "ๅฐ JavaScript ๅฏน่ฑก่ฝฌๆขไธบ JSON ๅญ็ฌฆไธฒๆ ผๅผใๅฐๆฐๆฎ็ปๆๅบๅๅไธบ JSON ๅญ็ฌฆไธฒไปฅไพฟๅญๅจๆไผ ่พใ",
+ "shortDescription": "ๅฐๅฏน่ฑก่ฝฌๆขไธบ JSON ๅญ็ฌฆไธฒ",
+ "title": "ๅญ็ฌฆไธฒๅ JSON"
+ },
+ "tsvToJson": {
+ "description": "ๅฐ TSV๏ผๅถ่กจ็ฌฆๅ้ๅผ๏ผๆฐๆฎ่ฝฌๆขไธบ JSON ๆ ผๅผใๅฐ่กจๆ ผๆฐๆฎ่ฝฌๆขไธบ็ปๆๅ็ JSON ๅฏน่ฑกใ",
+ "shortDescription": "ๅฐ TSV ่ฝฌๆขไธบ JSON ๆ ผๅผ",
+ "title": "TSV ๅฐ JSON"
+ },
+ "validateJson": {
+ "description": "ๆฃๆฅ JSON ๆฏๅฆๆๆไธๆ ผๅผๆญฃ็กฎใ",
+ "inputTitle": "่พๅ
ฅ JSON",
+ "invalidJson": "โ {{error}}",
+ "resultTitle": "้ช่ฏ็ปๆ",
+ "shortDescription": "้ช่ฏ JSON ไปฃ็ ๆฏๅฆๅญๅจ้่ฏฏ",
+ "title": "้ช่ฏ JSON",
+ "toolInfo": {
+ "description": "JSON๏ผJavaScript ๅฏน่ฑก่กจ็คบๆณ๏ผๆฏไธ็ง่ฝป้็บงๆฐๆฎไบคๆขๆ ผๅผใJSON ้ช่ฏๅฏ็กฎไฟๆฐๆฎ็ปๆ็ฌฆๅ JSON ๆ ๅใๆๆ็ JSON ๅฏน่ฑกๅฟ
้กปๅ
ทๅคไปฅไธ็นๅพ๏ผ- ๅฑๆงๅ็งฐ็จๅๅผๅทๆฌ่ตทๆฅใ- ๆญฃ็กฎๅน้
็่ฑๆฌๅท {}ใ- ๆๅไธไธช้ฎๅผๅฏนๅๆฒกๆๅฐพ้้ๅทใ- ๅฏน่ฑกๅๆฐ็ป็ๅตๅฅๆญฃ็กฎใๆญคๅทฅๅ
ทไผๆฃๆฅ่พๅ
ฅ็ JSON ๅนถๆไพๅ้ฆ๏ผไปฅๅธฎๅฉ่ฏๅซๅไฟฎๅคๅธธ่ง้่ฏฏใ",
+ "title": "ไปไนๆฏ JSON ้ช่ฏ๏ผ"
+ },
+ "validJson": "โ
ๆๆ็ JSON"
+ }
+}
diff --git a/public/locales/zh/list.json b/public/locales/zh/list.json
new file mode 100644
index 0000000..1e119ef
--- /dev/null
+++ b/public/locales/zh/list.json
@@ -0,0 +1,208 @@
+{
+ "duplicate": {
+ "concatenate": "่ฟๆฅ",
+ "concatenateDescription": "่ฟๆฅๅฏๆฌ๏ผๅฆๆๆช้ไธญ๏ผๅ้กน็ฎๅฐไบค็ปๅจไธ่ตท๏ผ",
+ "copyDescription": "ไปฝๆฐ๏ผๅฏไปฅๆฏๅๆฐ๏ผ",
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅ่กจ้กนๅคๅถๅฎ็จ็จๅบใ่พๅ
ฅๆจ็ๅ่กจๅนถๆๅฎๅคๅถๆกไปถๅณๅฏๅๅปบ้กน็ฎๅฏๆฌใ้ๅธธ้ๅๆฐๆฎๆฉๅฑใๆต่ฏๆๅๅปบ้ๅคๆจกๅผใ",
+ "duplicationOptions": "ๅคๅถ้้กน",
+ "examples": {
+ "fractional": {
+ "description": "ๆญค็คบไพๆพ็คบๅฆไฝๅคๅถๅ
ทๆๅฐๆฐไปฝๅฏๆฌ็ๅ่กจใ",
+ "title": "้จๅ้ๅค"
+ },
+ "interweave": {
+ "description": "ๆญค็คบไพๆพ็คบๅฆไฝไบค็ป้กน็ฎ่ไธๆฏ่ฟๆฅๅฎไปฌใ",
+ "title": "ไบค็ป็ฉๅ"
+ },
+ "reverse": {
+ "description": "ๆญค็คบไพๆพ็คบๅฆไฝไปฅ็ธๅ็้กบๅบๅคๅถๅ่กจใ",
+ "title": "ๅๅๅคๅถ"
+ },
+ "simple": {
+ "description": "ๆญค็คบไพๆพ็คบๅฆไฝๅคๅถๅ่ฏๅ่กจใ",
+ "title": "็ฎๅๅคๅถ"
+ }
+ },
+ "inputTitle": "่พๅ
ฅๅ่กจ",
+ "joinSeparatorDescription": "็จไบ่ฟๆฅ้ๅคๅ่กจ็ๅ้็ฌฆ",
+ "resultTitle": "้ๅคๅ่กจ",
+ "reverse": "ๆค้",
+ "reverseDescription": "ๅ่ฝฌ้ๅค้กน",
+ "shortDescription": "ๆ็
งๆๅฎๆกไปถๅคๅถๅ่กจ้กน",
+ "splitByRegex": "ๆๆญฃๅ่กจ่พพๅผๆๅ",
+ "splitBySymbol": "ๆ็ฌฆๅทๆๅ",
+ "splitOptions": "ๆๅ้้กน",
+ "splitSeparatorDescription": "็จไบๅๅฒๅ่กจ็ๅ้็ฌฆ",
+ "title": "ๅคๅถ",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจๅคๅถๅ่กจไธญ็้กน็ฎใๆจๅฏไปฅๆๅฎๅฏๆฌๆฐ้๏ผๅ
ๆฌๅฐๆฐ๏ผ๏ผๆงๅถ้กน็ฎๆฏ่ฟๆฅ่ฟๆฏไบค็ป๏ผ็่ณๅฏไปฅๅ่ฝฌ้ๅค็้กน็ฎใๅฎ้ๅธธ้ๅๅๅปบ้ๅคๆจกๅผใ็ๆๆต่ฏๆฐๆฎๆๆฉๅฑๅ
ทๆๅฏ้ขๆตๅ
ๅฎน็ๅ่กจใ",
+ "title": "ๅ่กจ้ๅค"
+ }
+ },
+ "findMostPopular": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅฎ็จ็จๅบ๏ผ็จไบๆฅๆพๅ่กจไธญๆ็ญ้จ็้กน็ฎใ่พๅ
ฅๆจ็ๅ่กจ๏ผๅณๅฏ็ซๅณ่ทๅๅบ็ฐ้ข็ๆ้ซ็้กน็ฎใ้ๅธธ้ๅๆฐๆฎๅๆใ่ถๅฟ่ฏๅซๆๆฅๆพๅ
ฑๅ็นใ",
+ "shortDescription": "ๆฅๆพๆๅธธๅบ็ฐ็้กน็ฎ",
+ "title": "ๆฅๆพๆๅๆฌข่ฟ็"
+ },
+ "findUnique": {
+ "caseSensitiveItems": "ๅบๅๅคงๅฐๅ็้กน็ฎ",
+ "caseSensitiveItemsDescription": "ๅฐๅ
ทๆไธๅๅคงๅฐๅ็้กน็ฎไฝไธบๅ่กจไธญ็ๅฏไธๅ
็ด ่พๅบใ",
+ "delimiterDescription": "่ฎพ็ฝฎๅ้็ฌฆๅทๆๆญฃๅ่กจ่พพๅผใ",
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅฎ็จ็จๅบ๏ผ็จไบๅจๅ่กจไธญๆฅๆพๅฏไธ้กนใ่พๅ
ฅๆจ็ๅ่กจ๏ผๅณๅฏ็ซๅณ่ทๅๆๆๅฏไธๅผ๏ผๅทฒๅ ้ค้ๅค้กน๏ผใ้ๅธธ้ๅๆฐๆฎๆธ
็ใ้ๅคๆฐๆฎๅ ้คๆๆฅๆพไธๅๅ
็ด ใ",
+ "findAbsolutelyUniqueItems": "ๅฏปๆพ็ปๅฏน็ฌ็น็็ฉๅ",
+ "findAbsolutelyUniqueItemsDescription": "ไป
ๆพ็คบๅ่กจไธญๅญๅจไบๅไธชๅฏๆฌไธญ็้กน็ฎใ",
+ "inputListDelimiter": "่พๅ
ฅๅ่กจๅ้็ฌฆ",
+ "inputTitle": "่พๅ
ฅๅ่กจ",
+ "outputListDelimiter": "่พๅบๅ่กจๅ้็ฌฆ",
+ "resultTitle": "็ฌ็น็ฉๅ",
+ "shortDescription": "ๅจๅ่กจไธญๆฅๆพๅฏไธ้กน",
+ "skipEmptyItems": "่ทณ่ฟ็ฉบ้กน็ฎ",
+ "skipEmptyItemsDescription": "ไธ่ฆๅจ่พๅบไธญๅ
ๅซ็ฉบๅ่กจ้กนใ",
+ "title": "ๅฏปๆพ็ฌ็น็",
+ "trimItems": "ไฟฎๅชๅ่กจ้กน",
+ "trimItemsDescription": "ๆฏ่พ้กน็ฎไนๅๅ ้คๅๅฏผๅๅฐพ้็ฉบๆ ผใ",
+ "uniqueItemOptions": "็ฌ็น็ฉๅ้้กน"
+ },
+ "group": {
+ "deleteEmptyItems": "ๅ ้ค็ฉบ้กน็ฎ",
+ "deleteEmptyItemsDescription": "ๅฟฝ็ฅ็ฉบ้กน็ฎๅนถไธไธ่ฆๅฐๅฎไปฌๅ
ๅซๅจ็ปไธญใ",
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅ่กจ้กนๅ็ปๅทฅๅ
ทใ่พๅ
ฅๆจ็ๅ่กจๅนถๆๅฎๅ็ปๆกไปถ๏ผๅณๅฏๅฐ้กน็ฎๆ้ป่พๅ็ปใ้ๅธธ้ๅๅ็ฑปๆฐๆฎใ็ป็ปไฟกๆฏๆๅๅปบ็ปๆๅๅ่กจใๆฏๆ่ชๅฎไนๅ้็ฌฆๅๅ็งๅ็ป้้กนใ",
+ "emptyItemsAndPadding": "็ฉบ้กน็ฎๅๅกซๅ
",
+ "groupNumberDescription": "็ปไธญ้กน็ฎ็ๆฐ้",
+ "groupSeparatorDescription": "็ปๅ้็ฌฆ",
+ "groupSizeAndSeparators": "็ปๅคงๅฐๅๅ้็ฌฆ",
+ "inputItemSeparator": "่พๅ
ฅ้กนๅ้็ฌฆ",
+ "inputTitle": "่พๅ
ฅๅ่กจ",
+ "itemSeparatorDescription": "้กน็ฎๅ้็ฌฆ",
+ "leftWrapDescription": "็ป็ๅทฆๆข่ก็ฌฆๅทใ",
+ "padNonFullGroups": "ๅกซๅ
้ๆปก็ป",
+ "padNonFullGroupsDescription": "ไฝฟ็จ่ชๅฎไน้กน็ฎ๏ผๅจไธ้ข่พๅ
ฅ๏ผๅกซๅ
้ๅฎๆด็ปใ",
+ "paddingCharDescription": "ไฝฟ็จๆญคๅญ็ฌฆๆ้กน็ฎๆฅๅกซๅ
้ๅฎๆด็ปใ",
+ "resultTitle": "ๅ็ป้กน็ฎ",
+ "rightWrapDescription": "็ป็ๅณๆข่ก็ฌฆๅทใ",
+ "shortDescription": "ๆๅ
ฑๅๅฑๆงๅฏนๅ่กจ้กน่ฟ่กๅ็ป",
+ "splitOperators": {
+ "regex": {
+ "description": "ไฝฟ็จๆญฃๅ่กจ่พพๅผๅ้่พๅ
ฅๅ่กจ้กนใ",
+ "title": "ไฝฟ็จๆญฃๅ่กจ่พพๅผ่ฟ่กๆๅ"
+ },
+ "symbol": {
+ "description": "็จๅญ็ฌฆๅ้่พๅ
ฅๅ่กจ้กนใ",
+ "title": "ไฝฟ็จ็ฌฆๅท่ฟ่กๆๅ"
+ }
+ },
+ "splitSeparatorDescription": "่ฎพ็ฝฎๅ้็ฌฆๅทๆๆญฃๅ่กจ่พพๅผใ",
+ "title": "ๅขไฝ"
+ },
+ "reverse": {
+ "description": "่ฟๆฏไธไธชๅบไบๆต่งๅจ็่ถ
็บง็ฎๅ็ๅบ็จ็จๅบ๏ผๅฏไปฅๅๅๆๅฐๆๆๅ่กจ้กนใ่พๅ
ฅ้กนๅฏไปฅ็จไปปๆ็ฌฆๅทๅ้๏ผๅนถไธๆจ่ฟๅฏไปฅๆดๆนๅๅๅ่กจ้กน็ๅ้็ฌฆใ",
+ "inputTitle": "่พๅ
ฅๅ่กจ",
+ "itemSeparator": "้กน็ฎๅ้็ฌฆ",
+ "itemSeparatorDescription": "่ฎพ็ฝฎๅ้็ฌฆๅทๆๆญฃๅ่กจ่พพๅผใ",
+ "outputListOptions": "่พๅบๅ่กจ้้กน",
+ "outputSeparatorDescription": "่พๅบๅ่กจ้กนๅ้็ฌฆใ",
+ "resultTitle": "ๅ่ฝฌๅ่กจ",
+ "shortDescription": "ๅฟซ้ๅ่ฝฌๅ่กจ",
+ "splitOperators": {
+ "regex": {
+ "description": "ไฝฟ็จๆญฃๅ่กจ่พพๅผๅ้่พๅ
ฅๅ่กจ้กนใ",
+ "title": "ไฝฟ็จๆญฃๅ่กจ่พพๅผ่ฟ่กๆๅ"
+ },
+ "symbol": {
+ "description": "็จๅญ็ฌฆๅ้่พๅ
ฅๅ่กจ้กนใ",
+ "title": "ไฝฟ็จ็ฌฆๅท่ฟ่กๆๅ"
+ }
+ },
+ "splitterMode": "ๅ็ฆปๅจๆจกๅผ",
+ "title": "ๆค้",
+ "toolInfo": {
+ "description": "ไฝฟ็จๆญคๅฎ็จ็จๅบ๏ผๆจๅฏไปฅๅ่ฝฌๅ่กจไธญ้กน็ฎ็้กบๅบใ่ฏฅๅฎ็จ็จๅบ้ฆๅ
ๅฐ่พๅ
ฅๅ่กจๆๅๆๅไธช้กน็ฎ๏ผ็ถๅไปๆๅไธไธช้กน็ฎๅฐ็ฌฌไธไธช้กน็ฎ่ฟ่ก่ฟญไปฃ๏ผๅนถๅจ่ฟญไปฃ่ฟ็จไธญๅฐๆฏไธช้กน็ฎๆๅฐๅฐ่พๅบไธญใ่พๅ
ฅๅ่กจๅฏไปฅๅ
ๅซไปปไฝๅฏไปฅ่กจ็คบไธบๆๆฌๆฐๆฎ็ๅ
ๅฎน๏ผๅ
ๆฌๆฐๅญใๆฐๅผใๅญ็ฌฆไธฒใๅ่ฏใๅฅๅญ็ญใ่พๅ
ฅ้กนๅ้็ฌฆไนๅฏไปฅๆฏๆญฃๅ่กจ่พพๅผใไพๅฆ๏ผๆญฃๅ่กจ่พพๅผ /[;,]/ ๅ
่ฎธๆจไฝฟ็จ้ๅทๆๅๅทๅ้็้กน็ฎใ่พๅ
ฅๅ่พๅบๅ่กจ้กนๅ้็ฌฆๅฏไปฅๅจ้้กนไธญ่ชๅฎไนใ้ป่ฎคๆ
ๅตไธ๏ผ่พๅ
ฅๅ่พๅบๅ่กจๅไปฅ้ๅทๅ้ใListabulous๏ผ",
+ "title": "ไปไนๆฏๅ่กจๅ่ฝฌๅจ๏ผ"
+ }
+ },
+ "rotate": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅ่กจ้กนๆ่ฝฌๅทฅๅ
ทใ่พๅ
ฅๆจ็ๅ่กจๅนถๆๅฎๆ่ฝฌ้๏ผๅณๅฏๅฐๅ่กจ้กน็งปๅจๆๅฎ็ไฝ็ฝฎใ้ๅธธ้ๅๆฐๆฎๆไฝใๅพช็ฏ็งปๅจๆๅ่กจ้ๆฐๆๅบใ",
+ "shortDescription": "ๆๆๅฎไฝ็ฝฎๆ่ฝฌๅ่กจ้กน",
+ "title": "ๆ่ฝฌ"
+ },
+ "shuffle": {
+ "delimiterDescription": "่ฎพ็ฝฎๅ้็ฌฆๅทๆๆญฃๅ่กจ่พพๅผใ",
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅ่กจ้กน้ๆบๆๅบๅทฅๅ
ทใ่พๅ
ฅๆจ็ๅ่กจ๏ผๅณๅฏ็ซๅณ่ทๅพไธไธชๆ้ๆบ้กบๅบๆๅ็ๅ่กจ้กน้ๆบ็ๆฌใ้ๅธธ้ๅๅๅปบๅคๆ ทๆงใๆต่ฏ้ๆบๆงๆๆททๅๆๅบๆฐๆฎใ",
+ "inputListSeparator": "่พๅ
ฅๅ่กจๅ้็ฌฆ",
+ "inputTitle": "่พๅ
ฅๅ่กจ",
+ "joinSeparatorDescription": "ๅจ้ๆบๅ่กจไธญไฝฟ็จๆญคๅ้็ฌฆใ",
+ "outputLengthDescription": "่พๅบ่ฟไนๅค็้ๆบ็ฉๅ",
+ "resultTitle": "้ๆบๅ่กจ",
+ "shortDescription": "้ๆบๅๅ่กจ้กน็้กบๅบ",
+ "shuffledListLength": "ๆไนฑๅ่กจ้ฟๅบฆ",
+ "shuffledListSeparator": "้ๆบๅ่กจๅ้็ฌฆ",
+ "title": "้ๆบๆญๆพ"
+ },
+ "sort": {
+ "caseSensitive": "ๅบๅๅคงๅฐๅๆๅบ",
+ "caseSensitiveDescription": "ๅๅซๅฏนๅคงๅๅๅฐๅๅญๆฏ่ฟ่กๆๅบใๆๅๅบๆๅๆถ๏ผๅคงๅๅญๆฏไผๅ
ไบๅฐๅๅญๆฏใ๏ผไป
้็จไบๅญๆฏๆๅบๆจกๅผใ๏ผ",
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅ่กจ้กนๆๅบๅทฅๅ
ทใ่พๅ
ฅๆจ็ๅ่กจๅนถๆๅฎๆๅบๆกไปถ๏ผๅณๅฏๆๅๅบๆ้ๅบๆๅ้กน็ฎใ้ๅธธ้ๅๆฐๆฎๆด็ใๆๆฌๅค็ๆๅๅปบๆๅบๅ่กจใ",
+ "inputItemSeparator": "่พๅ
ฅ้กนๅ้็ฌฆ",
+ "inputTitle": "่พๅ
ฅๅ่กจ",
+ "joinSeparatorDescription": "ไฝฟ็จๆญค็ฌฆๅทไฝไธบๆๅบๅ่กจไธญ้กน็ฎไน้ด็่ฟๆฅ็ฌฆใ",
+ "orderDescription": "้ๆฉๆๅบ้กบๅบใ",
+ "orderOptions": {
+ "decreasing": "้ๅบๆๅ",
+ "increasing": "ๅขๅ ่ฎขๅ"
+ },
+ "removeDuplicates": "ๅ ้ค้ๅค้กน",
+ "removeDuplicatesDescription": "ๅ ้ค้ๅค็ๅ่กจ้กนใ",
+ "resultTitle": "ๆๅบๅ่กจ",
+ "shortDescription": "ๆๆๅฎ้กบๅบๅฏนๅ่กจ้กน่ฟ่กๆๅบ",
+ "sortMethod": "ๆๅบๆนๆณ",
+ "sortMethodDescription": "้ๆฉๆๅบๆนๆณใ",
+ "sortOptions": {
+ "alphabetic": "ๆๅญๆฏ้กบๅบๆๅบ",
+ "length": "ๆ้ฟๅบฆๆๅบ",
+ "numeric": "ๆๆฐๅญๆๅบ"
+ },
+ "sortedItemProperties": "ๆๅบ็้กน็ฎๅฑๆง",
+ "splitOperators": {
+ "regex": {
+ "description": "ไฝฟ็จๆญฃๅ่กจ่พพๅผๅ้่พๅ
ฅๅ่กจ้กนใ",
+ "title": "ไฝฟ็จๆญฃๅ่กจ่พพๅผ่ฟ่กๆๅ"
+ },
+ "symbol": {
+ "description": "็จๅญ็ฌฆๅ้่พๅ
ฅๅ่กจ้กนใ",
+ "title": "ไฝฟ็จ็ฌฆๅท่ฟ่กๆๅ"
+ }
+ },
+ "splitSeparatorDescription": "่ฎพ็ฝฎๅ้็ฌฆๅทๆๆญฃๅ่กจ่พพๅผใ",
+ "title": "็ง็ฑป"
+ },
+ "truncate": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅ่กจๆชๆญๅทฅๅ
ทใ่พๅ
ฅๆจ็ๅ่กจๅนถๆๅฎ่ฆไฟ็็ๆๅคง้กน็ฎๆฐใ้ๅธธ้ๅๆฐๆฎๅค็ใๅ่กจ็ฎก็ๆ้ๅถๅ
ๅฎน้ฟๅบฆใ",
+ "shortDescription": "ๅฐๅ่กจๆชๆญไธบๆๅฎๆฐ้็้กน็ฎ",
+ "title": "ๆช็ญ"
+ },
+ "unwrap": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅ่กจ้กนๅฑๅผๅทฅๅ
ทใ่พๅ
ฅๅทฒๅฑๅผ็ๅ่กจ๏ผๅนถๆๅฎๅฑๅผๆกไปถไปฅๅฑๅนณๆๅบ็ๅ่กจ้กนใ้ๅธธ้ๅๆฐๆฎๅค็ใๆๆฌๆไฝๆไป็ปๆๅๅ่กจไธญๆๅๅ
ๅฎนใ",
+ "shortDescription": "ไป็ปๆๅๆ ผๅผไธญ่งฃๅผๅ่กจ้กน",
+ "title": "ๅฑๅผ"
+ },
+ "wrap": {
+ "description": "ๅจๆฏไธชๅ่กจ้กนไนๅๅไนๅๆทปๅ ๆๆฌใ",
+ "inputTitle": "่พๅ
ฅๅ่กจ",
+ "joinSeparatorDescription": "็จไบ่ฟๆฅๅ
่ฃ
ๅ่กจ็ๅ้็ฌฆ",
+ "leftTextDescription": "ๆฏไธช้กน็ฎๅๆทปๅ ็ๆๆฌ",
+ "removeEmptyItems": "ๅ ้ค็ฉบ้กน็ฎ",
+ "resultTitle": "ๅ
่ฃ
ๅ่กจ",
+ "rightTextDescription": "ๆฏ้กนๅๆทปๅ ็ๆๆฌ",
+ "shortDescription": "ไฝฟ็จๆๅฎๆกไปถๅ
่ฃ
ๅ่กจ้กน",
+ "splitByRegex": "ๆๆญฃๅ่กจ่พพๅผๆๅ",
+ "splitBySymbol": "ๆ็ฌฆๅทๆๅ",
+ "splitOptions": "ๆๅ้้กน",
+ "splitSeparatorDescription": "็จไบๅๅฒๅ่กจ็ๅ้็ฌฆ",
+ "title": "่ฃน",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจๅจๅ่กจไธญๆฏไธช้กน็ฎๅๅๆทปๅ ๆๆฌใๆจๅฏไปฅไธบๅทฆๅณไธคไพงๆๅฎไธๅ็ๆๆฌ๏ผๅนถๆงๅถๅ่กจ็ๅค็ๆนๅผใๅฎ้็จไบไธบๅ่กจ้กนๆทปๅ ๅผๅทใๆฌๅทๆๅ
ถไปๆ ผๅผ๏ผๅๅคไธๅๆ ผๅผ็ๆฐๆฎ๏ผๆๅๅปบ็ปๆๅๆๆฌใ",
+ "title": "ๅ่กจๅ
่ฃ
"
+ },
+ "wrapOptions": "ๅ
่ฃ
้้กน"
+ }
+}
diff --git a/public/locales/zh/number.json b/public/locales/zh/number.json
new file mode 100644
index 0000000..220c1fe
--- /dev/null
+++ b/public/locales/zh/number.json
@@ -0,0 +1,89 @@
+{
+ "arithmeticSequence": {
+ "commonDifferenceDescription": "ๆฏ่ฏญไน้ด็ๅ
ฑๅๅทฎๅผ๏ผd๏ผ",
+ "description": "็ๆๅ
ทๆๅฏๅฎๅถๅๆฐ็็ฎๆฏๅบๅใ",
+ "firstTermDescription": "ๅบๅ็็ฌฌไธ้กน (aโ)",
+ "numberOfTermsDescription": "็ๆ็ๆฏ่ฏญๆฐ๏ผn๏ผ",
+ "outputFormat": "่พๅบๆ ผๅผ",
+ "resultTitle": "็ๆ็ๅบๅ",
+ "separatorDescription": "ๆฏ่ฏญไน้ด็ๅ้็ฌฆ",
+ "sequenceParameters": "ๅบๅๅๆฐ",
+ "shortDescription": "็ๆ็ญๅทฎๅบๅ",
+ "title": "็ญๅทฎๅบๅ",
+ "toolInfo": {
+ "description": "็ญๅทฎๆฐๅๆฏๆไธ็ณปๅ่ฟ็ปญๆฐๅไธญ๏ผๅ่ฟ็ปญ้กนไน้ด็ๅทฎไธบๅธธๆฐใ่ฟไธชๅธธๆฐๅทฎ็งฐไธบๅ
ฌๅทฎใ็ปๅฎ็ฌฌไธ้กน (aโ) ๅๅ
ฌๅทฎ (d)๏ผๅฏไปฅ้่ฟๅฐๅ
ฌๅทฎๅ ๅฐๅไธ้กนๆฅๆฑๅบๆฏไธ้กนใ",
+ "title": "ไปไนๆฏ็ญๅทฎๅบๅ๏ผ"
+ }
+ },
+ "generate": {
+ "arithmeticSequenceOption": "็ฎๆฏๅบๅ้้กน",
+ "description": "็ๆๅ
ทๆๅฏๅฎๅถๅๆฐ็ๆฐๅญๅบๅใ",
+ "numberOfElementsDescription": "ๅบๅไธญ็ๅ
็ด ๆฐ้ใ",
+ "resultTitle": "็ๆ็ๆฐๅญ",
+ "separator": "ๅ้็ฌฆ",
+ "separatorDescription": "็จ่ฏฅๅญ็ฌฆๅ้็ฎๆฏๅบๅไธญ็ๅ
็ด ใ",
+ "shortDescription": "็ๆๆๅฎ่ๅดๅ
็้ๆบๆฐ",
+ "startSequenceDescription": "ไป่ฏฅๆฐๅญๅผๅงๅบๅใ",
+ "stepDescription": "ๅฐๆฏไธชๅ
็ด ๅขๅ ๆญค้",
+ "title": "ไบง็",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจ็ๆๅ
ทๆๅฏ่ชๅฎไนๅๆฐ็ๆฐๅญๅบๅใๆจๅฏไปฅๆๅฎ่ตทๅงๅผใๆญฅ้ฟๅๅ
็ด ๆฐ้ใ",
+ "title": "็ๆๆฐๅญ"
+ }
+ },
+ "ohmsLaw": {
+ "description": "่ฎก็ฎ็ตๅใ็ตๆตๅ็ต้ป",
+ "longDescription": "ๆญค่ฎก็ฎๅจๅบ็จๆฌงๅงๅฎๅพ (V = I ร R)๏ผๅจๅทฒ็ฅๅ
ถไปไธคไธช็ตๅๆฐ็ๆ
ๅตไธ๏ผ็กฎๅฎไปปๆไธไธช็ตๅๆฐใๆฌงๅงๅฎๅพๆฏ็ตๆฐๅทฅ็จไธญ็ไธไธชๅบๆฌๅ็๏ผๆ่ฟฐไบ็ตๅ (V)ใ็ตๆต (I) ๅ็ต้ป (R) ไน้ด็ๅ
ณ็ณปใๅฏนไบ็ตๅญ็ฑๅฅฝ่
ใ็ตๆฐๅทฅ็จๅธๅไปไบ็ต่ทฏ่ฎพ่ฎก็ๅญฆ็ๆฅ่ฏด๏ผๆญคๅทฅๅ
ทๅฟ
ไธๅฏๅฐ๏ผๅฏไปฅๅธฎๅฉไปไปฌๅฟซ้ๆฑ่งฃ็ตๆฐ่ฎพ่ฎกไธญ็ๆช็ฅๅผใ",
+ "shortDescription": "ไฝฟ็จๆฌงๅงๅฎๅพ่ฎก็ฎ็ต่ทฏไธญ็็ตๅใ็ตๆตๆ็ต้ป",
+ "title": "ๆฌงๅงๅฎๅพ"
+ },
+ "slackline": {
+ "description": "่ฎก็ฎๆพๅผ็บฟ็ๅผ ๅ",
+ "longDescription": "่ฏฅ่ฎก็ฎๅจๅ่ฎพ็ปณ็ดขไธญๅฟๆ่ด่ฝฝ",
+ "shortDescription": "่ฎก็ฎๆพๅผ็ปณๆๆพ่กฃ็ปณ็ๅคง่ดๅผ ๅใไธ่ฆไพ่ตๅฎๆฅ็กฎไฟๅฎๅ
จใ",
+ "title": "ๆพๅผ็บฟๅผ ๅ"
+ },
+ "sphereArea": {
+ "description": "็ไฝ็้ข็งฏ",
+ "longDescription": "ๆญค่ฎก็ฎๅจไฝฟ็จๅ
ฌๅผ A = 4ฯrยฒ ่ฎก็ฎ็ไฝ็่กจ้ข็งฏใๆจๅฏไปฅ่พๅ
ฅๅๅพๆฅ่ฎก็ฎ่กจ้ข็งฏ๏ผไนๅฏไปฅ็ดๆฅ่พๅ
ฅ่กจ้ข็งฏๆฅ่ฎก็ฎๆ้็ๅๅพใๆญคๅทฅๅ
ท้็จไบๅญฆไน ๅ ไฝ็ๅญฆ็ใๅค็็ๅฝข็ฉไฝ็ๅทฅ็จๅธไปฅๅไปปไฝ้่ฆ่ฟ่ก็้ข่ฎก็ฎ็ไบบใ",
+ "shortDescription": "ๆ นๆฎ็ไฝ็ๅๅพ่ฎก็ฎๅ
ถ่กจ้ข็งฏ",
+ "title": "็ไฝ็้ข็งฏ"
+ },
+ "sphereVolume": {
+ "description": "็ไฝ็ไฝ็งฏ",
+ "longDescription": "ๆญค่ฎก็ฎๅจไฝฟ็จๅ
ฌๅผ V = (4/3)ฯrยณ ่ฎก็ฎ็ไฝ็ไฝ็งฏใๆจๅฏไปฅ่พๅ
ฅๅๅพๆ็ดๅพๆฅ่ฎก็ฎไฝ็งฏ๏ผไนๅฏไปฅ็ดๆฅ่พๅ
ฅไฝ็งฏๆฅ็กฎๅฎๆ้็ๅๅพใๅฏนไบๅจ็ฉ็ใๅทฅ็จๅๅถ้ ็ญ้ขๅๅค็็ๅฝข็ฉไฝ็ๅญฆ็ใๅทฅ็จๅธๅไธไธไบบๅฃซๆฅ่ฏด๏ผๆญคๅทฅๅ
ท้ๅธธๆ็จใ",
+ "shortDescription": "ไฝฟ็จๅๅพๆ็ดๅพ่ฎก็ฎ็ไฝ็ไฝ็งฏ",
+ "title": "็ไฝ็ไฝ็งฏ"
+ },
+ "sum": {
+ "description": "่ฎก็ฎไธไธฒๆฐๅญ็ๆปๅใ่พๅ
ฅไปฅ้ๅทๆๆข่ก็ฌฆๅ้็ๆฐๅญ๏ผๅณๅฏ่ฎก็ฎๅบๅฎไปฌ็ๆปๅใ",
+ "extractionTypes": {
+ "delimiter": {
+ "description": "ๅจๆญค่ชๅฎไนๆฐๅญๅ้็ฌฆใ๏ผ้ป่ฎคไธบๆข่ก็ฌฆใ๏ผ",
+ "title": "ๆฐๅญๅ้็ฌฆ"
+ },
+ "smart": {
+ "description": "่ชๅจๆฃๆต่พๅ
ฅไธญ็ๆฐๅญใ",
+ "title": "ๆบ่ฝๆปๅ"
+ }
+ },
+ "inputTitle": "่พๅ
ฅ",
+ "numberExtraction": "ๆฐๅญๆๅ",
+ "printRunningSum": "ๆๅฐ่ฟ่กๆปๅ",
+ "printRunningSumDescription": "ๆพ็คบ้ๆญฅ่ฎก็ฎ็ๆปๅใ",
+ "resultTitle": "ๅ
จ้จ็",
+ "runningSum": "่ฟ่กๆปๅ",
+ "shortDescription": "่ฎก็ฎๆฐๅญไนๅ",
+ "title": "ๅ",
+ "toolInfo": {
+ "description": "่ฟๆฏไธไธชๅบไบๆต่งๅจ็ๅจ็บฟๅฎ็จ็จๅบ๏ผ็จไบ่ฎก็ฎไธ็ปๆฐๅญ็ๆปๅใๆจๅฏไปฅ่พๅ
ฅ็จ้ๅทใ็ฉบๆ ผๆไปปไฝๅ
ถไปๅญ็ฌฆ๏ผๅ
ๆฌๆข่ก็ฌฆ๏ผๅ้็ๆฐๅญใๆจไนๅฏไปฅ็ดๆฅ็ฒ่ดดไธๆฎตๅ
ๅซ่ฆๆฑๅ็ๆฐๅผ็ๆๆฌๆฐๆฎ๏ผ่ฏฅๅฎ็จ็จๅบไผๆๅ่ฟไบๆฐๆฎๅนถ่ฎก็ฎๆปๅใ",
+ "title": "ไปไนๆฏๆฐๅญๆปๅ่ฎก็ฎๅจ๏ผ"
+ }
+ },
+ "voltageDropInWire": {
+ "description": "่ฎก็ฎๅ่ฏ็ต็ผ็ๅพ่ฟ็ตๅๅๅ็ๆ่",
+ "longDescription": "่ฟๆฌพ่ฎก็ฎๅจๅฏๅธฎๅฉ่ฎก็ฎๅ่ฏ็ต็ผ็็ตๅ้ๅๅ็ๆ่ใๅฎ่่ไบ็ต็ผ้ฟๅบฆใ็บฟ่ง๏ผๆจชๆช้ข็งฏ๏ผใๆๆ็ต้ป็ๅ็ตๆตใ่ฏฅๅทฅๅ
ทๅฏ่ฎก็ฎๅพ่ฟ็ตๅ้ใ็ต็ผๆป็ต้ปไปฅๅไปฅ็ญ้ๅฝขๅผ่ๆฃ็ๅ็ใ่ฟๅฏนไบ็ตๆฐๅทฅ็จๅธใ็ตๅทฅๅไธไฝ็ฑๅฅฝ่
ๅจ่ฎพ่ฎก็ตๆฐ็ณป็ปๆถๅฐคๅ
ถๆ็จ๏ผๅฏ็กฎไฟ่ด่ฝฝไธ็็ตๅๆฐดๅนณไฟๆๅจๅฏๆฅๅ็่ๅดๅ
ใ",
+ "shortDescription": "ๆ นๆฎ้ฟๅบฆใๆๆๅ็ตๆต่ฎก็ฎ็ต็ผ็็ตๅ้ๅๅ็ๆ่",
+ "title": "็ต็ผๅพ่ฟ็ตๅ้"
+ }
+}
diff --git a/public/locales/zh/pdf.json b/public/locales/zh/pdf.json
new file mode 100644
index 0000000..aeb3726
--- /dev/null
+++ b/public/locales/zh/pdf.json
@@ -0,0 +1,113 @@
+{
+ "compressPdf": {
+ "compressedFileSize": "ๅ็ผฉๆไปถๅคงๅฐ",
+ "compressingPdf": "ๆญฃๅจๅ็ผฉ PDF...",
+ "compressionLevel": "ๅ็ผฉ็บงๅซ",
+ "compressionSettings": "ๅ็ผฉ่ฎพ็ฝฎ",
+ "description": "ไฝฟ็จ Ghostscript ๅๅฐ PDF ๆไปถๅคงๅฐๅๆถไฟๆ่ดจ้",
+ "errorCompressingPdf": "ๅ็ผฉ PDF ๅคฑ่ดฅ๏ผ {{error}}",
+ "errorReadingPdf": "ๆ ๆณ่ฏปๅ PDF ๆไปถใ่ฏท็กฎไฟๅฎๆฏๆๆ็ PDFใ",
+ "fileSize": "ๅๅงๆไปถๅคงๅฐ",
+ "highCompression": "้ซๅ็ผฉ",
+ "highCompressionDescription": "ๆๅคง็จๅบฆๅฐๅๅฐๆไปถๅคงๅฐ๏ผไฝไผๆๅคฑไธไบ่ดจ้",
+ "inputTitle": "่พๅ
ฅ PDF",
+ "lowCompression": "ไฝๅ็ผฉ",
+ "lowCompressionDescription": "ๅจๅฐฝ้ๅๅฐ่ดจ้ๆๅคฑ็ๆ
ๅตไธ็จๅพฎๅๅฐๆไปถๅคงๅฐ",
+ "mediumCompression": "ไธญ็ญๅ็ผฉ",
+ "mediumCompressionDescription": "ๆไปถๅคงๅฐๅ่ดจ้ไน้ด็ๅนณ่กก",
+ "pages": "้กตๆฐ",
+ "resultTitle": "ๅ็ผฉ PDF",
+ "shortDescription": "ๅจๆต่งๅจไธญๅฎๅ
จๅฐๅ็ผฉ PDF ๆไปถ",
+ "title": "ๅ็ผฉPDF"
+ },
+ "editor": {
+ "description": "้ซ็บง PDF ็ผ่พๅจ๏ผๅ
ทๅคๆณจ้ใ่กจๅๅกซๅใ้ซไบฎๆพ็คบๅๅฏผๅบๅ่ฝใๆจๅฏไปฅไฝฟ็จไธไธ็บงๅทฅๅ
ท๏ผๅ
ๆฌๆๆฌๆๅ
ฅใ็ปๅพใ้ซไบฎๆพ็คบใ็ญพๅๅ่กจๅๅกซๅ๏ผ็ดๆฅๅจๆต่งๅจไธญ็ผ่พ PDFใ",
+ "shortDescription": "ไฝฟ็จ้ซ็บงๆณจ้ใ็ญพๅๅ็ผ่พๅทฅๅ
ท็ผ่พ PDF",
+ "title": "PDF็ผ่พๅจ"
+ },
+ "merge": {
+ "inputTitle": "่พๅ
ฅ PDF",
+ "loadingText": "ๆๅ้กต้ข",
+ "resultTitle": "่พๅบๅๅนถ็ PDF",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจๅฐๅคไธช PDF ๆไปถๅๅนถไธบไธไธชๆๆกฃใ่ฆไฝฟ็จ่ฏฅๅทฅๅ
ท๏ผๅช้ไธไผ ่ฆๅๅนถ็ PDF ๆไปถๅณๅฏใ็ถๅ๏ผ่ฏฅๅทฅๅ
ทไผๅฐ่พๅ
ฅๆไปถไธญ็ๆๆ้กต้ขๅๅนถไธบไธไธช PDF ๆๆกฃใ",
+ "title": "ๅฆไฝไฝฟ็จๅๅนถ PDF ๅทฅๅ
ท๏ผ"
+ }
+ },
+ "mergePdf": {
+ "description": "ๅๅนถๅคไธช PDF ๆไปถไธบไธไธชๆๆกฃใ",
+ "inputTitle": "่พๅ
ฅ PDF",
+ "mergingPdfs": "ๅๅนถ PDF",
+ "pdfOptions": "PDF ้้กน",
+ "resultTitle": "ๅๅนถ็ PDF",
+ "shortDescription": "ๅฐๅคไธช PDF ๆไปถๅๅนถไธบไธไธชๆๆกฃ",
+ "sortByFileName": "ๆๆไปถๅๆๅบ",
+ "sortByFileNameDescription": "ๆๆไปถๅๅญๆฏ้กบๅบๅฏน PDF ่ฟ่กๆๅบ",
+ "sortByUploadOrder": "ๆไธไผ ้กบๅบๆๅบ",
+ "sortByUploadOrderDescription": "ไฟๆ PDF ๆ็
งไธไผ ้กบๅบๆๅ",
+ "title": "ๅๅนถ PDF",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจๅฐๅคไธช PDF ๆไปถๅๅนถไธบไธไธชๆๆกฃใๆจๅฏไปฅ้ๆฉๅฏน PDF ่ฟ่กๆๅบ๏ผ่ฏฅๅทฅๅ
ทๅฐๆ็
งๆๅฎ็้กบๅบ่ฟ่กๅๅนถใ",
+ "title": "ๅๅนถPDFๆไปถ"
+ }
+ },
+ "pdfToEpub": {
+ "description": "ๅฐ PDF ๆๆกฃ่ฝฌๆขไธบ EPUB ๆไปถ๏ผไปฅๅฎ็ฐๆดๅฅฝ็็ตๅญ้
่ฏปๅจๅ
ผๅฎนๆงใ', icon: 'material-symbols:import-contacts', component: lazy(() => import('./index')), keywords: ['pdf', 'epub', 'convert', 'ebook'], path: 'pdf-to-epub', i18n: { name: 'pdf:pdfToEpub.title', description: 'pdf:pdfToEpub.description",
+ "shortDescription": "ๅฐ PDF ๆไปถ่ฝฌๆขไธบ EPUB ๆ ผๅผ",
+ "title": "PDF ่ฝฌ EPUB"
+ },
+ "pdfToPng": {
+ "description": "ๅฐ PDF ๆๆกฃ่ฝฌๆขไธบ PNG ้ขๆฟใ",
+ "longDescription": "ไธไผ PDF ๅ๏ผ็ดๆฅๅจๆต่งๅจไธญๅฐๆฏไธช้กต้ข่ฝฌๆขไธบ้ซ่ดจ้็ PNG ๅพๅใๆญคๅทฅๅ
ท้ๅธธ้ๅๆๅ่ง่งๅ
ๅฎนๆๅไบซๅไธช้กต้ขใๆ ้ไธไผ ๆฐๆฎ๏ผๆๆๆไฝๅๅจๆฌๅฐ่ฟ่กใ",
+ "shortDescription": "ๅฐ PDF ่ฝฌๆขไธบ PNG ๅพๅ",
+ "title": "PDF ่ฝฌ PNG"
+ },
+ "protectPdf": {
+ "description": "ๅจๆต่งๅจไธญๅฎๅ
จๅฐไธบ PDF ๆไปถๆทปๅ ๅฏ็ ไฟๆค",
+ "shortDescription": "ไฝฟ็จๅฏ็ ๅฎๅ
จๅฐไฟๆค PDF ๆไปถ",
+ "title": "ไฟๆค PDF"
+ },
+ "rotatePdf": {
+ "allPagesWillBeRotated": "ๅ
จ้จ {{count}} ้กต้ขๅฐไผๆ่ฝฌ",
+ "angleOptions": {
+ "clockwise90": "้กบๆถ้ 90ยฐ",
+ "counterClockwise270": "270ยฐ๏ผ้ๆถ้90ยฐ๏ผ",
+ "upsideDown180": "180ยฐ๏ผไธไธ้ข ๅ๏ผ"
+ },
+ "applyToAllPages": "ๅบ็จไบๆๆ้กต้ข",
+ "description": "ๆ่ฝฌ PDF ๆๆกฃไธญ็้กต้ขใ",
+ "inputTitle": "่พๅ
ฅ PDF",
+ "longDescription": "้่ฟๅฐ PDF ้กต้ขๆ่ฝฌ 90 ๅบฆใ180 ๅบฆๆ 270 ๅบฆๆฅๆดๆนๅ
ถๆนๅใ่ฟๅฏนไบไฟฎๅคๆซๆ้่ฏฏ็ๆๆกฃๆๅๅคๆๅฐ PDF ้ๅธธๆ็จใ",
+ "pageRangesDescription": "่พๅ
ฅ้กต็ ๆ่ๅด๏ผไปฅ้ๅทๅ้๏ผไพๅฆ๏ผ1,3,5-7๏ผ",
+ "pageRangesPlaceholder": "ไพๅฆ๏ผ1.5-8",
+ "pagesWillBeRotated": "{{count}} ้กต{{count !== 1 ? 's' : ''}} ๅฐไผ่ฝฎๆข",
+ "pdfPageCount": "PDF ๆ {{count}} ้กต{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "ๆ่ฝฌ็ PDF",
+ "rotatingPages": "ๆ่ฝฌ้กต้ข",
+ "rotationAngle": "ๆ่ฝฌ่งๅบฆ",
+ "rotationSettings": "ๆ่ฝฌ่ฎพ็ฝฎ",
+ "shortDescription": "ๆ่ฝฌ PDF ๆๆกฃไธญ็้กต้ข",
+ "title": "ๆ่ฝฌ PDF",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจๆ่ฝฌ PDF ๆๆกฃไธญ็้กต้ขใๆจๅฏไปฅๆ่ฝฌๆๆ้กต้ข๏ผไนๅฏไปฅๆๅฎๅไธช้กต้ข่ฟ่กๆ่ฝฌใ้ๆฉๆ่ฝฌ่งๅบฆ๏ผ้กบๆถ้ 90ยฐใไธไธ 180ยฐ ๆ้ๆถ้ 270ยฐใ่ฆๆ่ฝฌ็นๅฎ้กต้ข๏ผ่ฏทๅๆถๅพ้โๅบ็จไบๆๆ้กต้ขโ๏ผๅนถ่พๅ
ฅ้กต็ ๆไปฅ้ๅทๅ้็่ๅด๏ผไพๅฆ๏ผ1,3,5-7๏ผใ",
+ "title": "ๅฆไฝไฝฟ็จๆ่ฝฌ PDF ๅทฅๅ
ท"
+ }
+ },
+ "splitPdf": {
+ "description": "ไป PDF ๆๆกฃไธญๆๅ็นๅฎ้กต้ขใ",
+ "extractingPages": "ๆๅ้กต้ข",
+ "inputTitle": "่พๅ
ฅ PDF",
+ "pageExtractionPreview": "{{count}} ้กต{{count !== 1 ? 's' : ''}} ๅฐ่ขซๆๅ",
+ "pageRangesDescription": "่พๅ
ฅ้กต็ ๆ่ๅด๏ผไปฅ้ๅทๅ้๏ผไพๅฆ๏ผ1,3,5-7๏ผ",
+ "pageRangesPlaceholder": "ไพๅฆ๏ผ1.5-8",
+ "pageSelection": "้กต้ข้ๆฉ",
+ "pdfPageCount": "PDF ๆ {{count}} ้กต{{count !== 1 ? 's' : ''}}",
+ "resultTitle": "ๆๅ็ PDF",
+ "shortDescription": "ไป PDF ๆไปถไธญๆๅ็นๅฎ้กต้ข",
+ "title": "ๆๅ PDF",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจไป PDF ๆๆกฃไธญๆๅ็นๅฎ้กต้ขใๆจๅฏไปฅๆๅฎ่ฆๆๅ็ๅไธช้กต้ขๆ้กต้ข่ๅดใ",
+ "title": "ๆๅ PDF"
+ }
+ }
+}
diff --git a/public/locales/zh/string.json b/public/locales/zh/string.json
new file mode 100644
index 0000000..fd483ff
--- /dev/null
+++ b/public/locales/zh/string.json
@@ -0,0 +1,261 @@
+{
+ "base64": {
+ "decode": "Base64่งฃ็ ",
+ "description": "ไฝฟ็จ Base64 ็ผ็ ๅฏนๆๆฌ่ฟ่ก็ผ็ ๆ่งฃ็ ใ",
+ "encode": "Base64็ผ็ ",
+ "inputTitle": "่พๅ
ฅๆฐๆฎ",
+ "optionsTitle": "Base64 ้้กน",
+ "resultTitle": "็ปๆ",
+ "shortDescription": "ไฝฟ็จ Base64 ๅฏนๆฐๆฎ่ฟ่ก็ผ็ ๆ่งฃ็ ใ",
+ "title": "Base64 ็ผ็ ๅจ/่งฃ็ ๅจ",
+ "toolInfo": {
+ "description": "Base64 ๆฏไธ็ง็ผ็ ๆนๆก๏ผๅฎๅฐ ASCII ๅญ็ฌฆไธฒๆ ผๅผ็ๆฐๆฎ่ฝฌๆขไธบ radix-64 ่กจ็คบๅฝขๅผใ่ฝ็ถ Base64 ไนๅฏไปฅ็จๆฅ็ผ็ ๅญ็ฌฆไธฒ๏ผไฝๅฎๆดๅธธ็จไบ็ผ็ ไบ่ฟๅถๆฐๆฎ๏ผไปฅไพฟๅจไธ้จๅค็ๆๆฌๆฐๆฎ็ไป่ดจไธไผ ่พใ",
+ "title": "ไปไนๆฏBase64๏ผ"
+ }
+ },
+ "censor": {
+ "description": "็จไบๅฎกๆฅๆๆฌไธญๅ่ฏ็ๅฎ็จ็จๅบใๅจๅทฆไพง็่พๅ
ฅ่กจๅไธญๅ ่ฝฝๆจ็ๆๆฌ๏ผๅนถๅจ้้กนไธญๆๅฎๆๆ่่ฏ๏ผๆจๅฐ็ซๅณๅจ่พๅบๅบๅ่ทๅพๅทฒๅฎกๆฅ็ๆๆฌใ\", longDescription: 'ไฝฟ็จๆญคๅจ็บฟๅทฅๅ
ท๏ผๆจๅฏไปฅๅฎกๆฅไปปไฝๆๆฌไธญ็ๆไบๅ่ฏใๆจๅฏไปฅๆๅฎไธๆณ่ฆ็ๅ่ฏๅ่กจ๏ผไพๅฆ่่ฏๆ็งๅฏๅ่ฏ๏ผ๏ผ็จๅบไผ็จๆฟไปฃๅ่ฏๆฟๆขๅฎไปฌ๏ผๅนถๅๅปบๅฏๅฎๅ
จ้
่ฏป็ๆๆฌใๆจๅฏไปฅๅจ้้กนไธญ็ๅค่กๆๆฌๅญๆฎตไธญ้่ฟๆฏ่ก่พๅ
ฅไธไธชๅ่ฏๆฅๆๅฎ่ฟไบๅ่ฏใ', keywords: ['text', 'censor', 'words', 'characters'], component: lazy(() => import('./index')), i18n: { name: 'string:censor.title', description: 'string:censor.description",
+ "shortDescription": "ๅฟซ้ๆฉ็่่ฏๆ็จๆฟไปฃ่ฏไปฃๆฟใ",
+ "title": "ๆๆฌๅฎกๆฅ"
+ },
+ "createPalindrome": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅๆๅๅปบๅทฅๅ
ท๏ผๅฏไปไปปไฝๆๆฌๅๅปบๅๆใ่พๅ
ฅๆๆฌๅณๅฏ็ซๅณๅฐๅ
ถ่ฝฌๆขไธบๆญฃๅ่ฏป็ธๅ็ๅๆใ้ๅธธ้ๅๆๅญๆธธๆใๅๅปบๅฏน็งฐๆๆฌๆจกๅผๆๆข็ดข่ฏญ่จๅญฆ็ฅ่ฏใ",
+ "shortDescription": "ๅๅปบๆญฃ่ฏปๅๅ่ฏป็ธๅ็ๆๆฌ",
+ "title": "ๅๅปบๅๆ"
+ },
+ "extractSubstring": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๆๆฌๅญๅญ็ฌฆไธฒๆๅๅทฅๅ
ทใ่พๅ
ฅๆๆฌๅนถๆๅฎ่ตทๅงๅ็ปๆญขไฝ็ฝฎๅณๅฏๆๅๆ้้จๅใ้ๅธธ้ๅๆฐๆฎๅค็ใๆๆฌๅๆๆไป่พๅคงๆๆฌๅไธญๆๅ็นๅฎๅ
ๅฎนใ",
+ "shortDescription": "ๆๅๆๅฎไฝ็ฝฎไน้ด็้จๅๆๆฌ",
+ "title": "ๆๅๅญๅญ็ฌฆไธฒ"
+ },
+ "join": {
+ "blankLinesAndTrailingSpaces": "็ฉบ่กๅๅฐพ้็ฉบๆ ผ",
+ "deleteBlankDescription": "ๅ ้คๆฒกๆๆๆฌ็ฌฆๅท็่กใ",
+ "deleteBlankTitle": "ๅ ้ค็ฉบ็ฝ่ก",
+ "deleteTrailingDescription": "ๅ ้ค่กๅฐพ็็ฉบๆ ผๅๅถ่กจ็ฌฆใ",
+ "deleteTrailingTitle": "ๅ ้คๅฐพ้็ฉบๆ ผ",
+ "description": "ไฝฟ็จๅฏ่ชๅฎไน็ๅ้็ฌฆๅฐๆๆฌ็ๆฎต่ฟๆฅๅจไธ่ตทใ",
+ "inputTitle": "ๆๆฌ็ๆฎต",
+ "joinCharacterDescription": "่ฟๆฅๆๆฌ็ๆฎต็็ฌฆๅทใ๏ผ้ป่ฎคไธบ็ฉบๆ ผใ๏ผ",
+ "joinCharacterPlaceholder": "ๅ ๅ
ฅ่ง่ฒ",
+ "resultTitle": "่ฟๆฅๆๆฌ",
+ "shortDescription": "ไฝฟ็จๆๅฎ็ๅ้็ฌฆ่ฟๆฅๆๆฌๅ
็ด ",
+ "textMergedOptions": "ๆๆฌๅๅนถ้้กน",
+ "title": "ๅ ๅ
ฅๆๆฌ",
+ "toolInfo": {
+ "description": "ไฝฟ็จๆญคๅทฅๅ
ท๏ผๆจๅฏไปฅๅฐๆๆฌ็ๅไธช้จๅ่ฟๆฅๅจไธ่ตทใๅฎๆฅๆถไธไธชไปฅๆข่ก็ฌฆๅ้็ๆๆฌๅผๅ่กจ๏ผๅนถๅฐๅฎไปฌๅๅนถๅจไธ่ตทใๆจๅฏไปฅ่ฎพ็ฝฎๅๅนถๆๆฌๅ้จๅไน้ด็ๅญ็ฌฆใๆญคๅค๏ผๆจ่ฟๅฏไปฅๅฟฝ็ฅๆๆ็ฉบ่ก๏ผๅนถๅ ้คๆๆ่กๆซ็็ฉบๆ ผๅๅถ่กจ็ฌฆใTextabulous๏ผ",
+ "title": "ไปไนๆฏๆๆฌ่ฟๆฅๅจ๏ผ"
+ }
+ },
+ "palindrome": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅๆๆฃๆตๅทฅๅ
ทใๅณๆถ้ช่ฏๆๆฌๆญฃ่ฏปๅๅ่ฏปๆฏๅฆไธ่ดใ้ๅธธ้ๅๅญ่ฐๆธธๆใ่ฏญ่จๅๆๆ้ช่ฏๅฏน็งฐๆๆฌๆจกๅผใๆฏๆๅ็งๅ้็ฌฆๅๅค่ฏๅๆๆฃๆตใ",
+ "shortDescription": "ๆฃๆฅๆๆฌๆญฃ่ฏปๅๅ่ฏปๆฏๅฆ็ธๅ",
+ "title": "ๅๆ"
+ },
+ "passwordGenerator": {
+ "avoidAmbiguous": "้ฟๅ
ไฝฟ็จๆญงไนๅญ็ฌฆ๏ผiใIใlใ0ใO๏ผ",
+ "description": "็ๆๅฎๅ
จ็้ๆบๅฏ็ ๏ผๅฏ่ชๅฎไน้ฟๅบฆๅๅญ็ฌฆ็ฑปๅใๅฏ็ ็ฑปๅๅ
ๆฌๅฐๅๅญๆฏใๅคงๅๅญๆฏใๆฐๅญๅ็นๆฎๅญ็ฌฆใๆญคๅค๏ผ่ฟๅฏ้ๆฉ้ฟๅ
ไฝฟ็จๆจก็ณๅญ็ฌฆ๏ผไปฅๆ้ซๅฏ่ฏปๆงใ",
+ "includeLowercase": "ๅ
ๅซๅฐๅๅญๆฏ๏ผa-z๏ผ",
+ "includeNumbers": "ๅ
ๅซๆฐๅญ (0-9)",
+ "includeSymbols": "ๅ
ๅซ็นๆฎๅญ็ฌฆ",
+ "includeUppercase": "ๅ
ๅซๅคงๅๅญๆฏ๏ผA-Z๏ผ",
+ "lengthDesc": "ๅฏ็ ้ฟๅบฆ",
+ "lengthPlaceholder": "ไพๅฆ 12",
+ "optionsTitle": "ๅฏ็ ้้กน",
+ "resultTitle": "็ๆ็ๅฏ็ ",
+ "shortDescription": "ไฝฟ็จ่ชๅฎไน้้กน็ๆๅฎๅ
จ็้ๆบๅฏ็ ",
+ "title": "ๅฏ็ ็ๆๅจ",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅฏๆ นๆฎๆจ้ๆฉ็ๆกไปถ็ๆๅฎๅ
จ็้ๆบๅฏ็ ใๆจๅฏไปฅ่ชๅฎไน้ฟๅบฆ๏ผๅ
ๅซๆๆ้คไธๅ็ๅญ็ฌฆ็ฑปๅ๏ผๅนถ้ฟๅ
ไฝฟ็จๆจก็ณๅญ็ฌฆไปฅๆ้ซๅฏ่ฏปๆงใ้ๅธธ้ๅไธบๅธๆทใๅบ็จ็จๅบๆไปปไฝๅฎๅ
จ้ๆฑๅๅปบๅผบๅฏ็ ใ",
+ "title": "ๅ
ณไบๅฏ็ ็ๆๅจ"
+ }
+ },
+ "quote": {
+ "allowDoubleQuotation": "ๅ
่ฎธๅๅผๅท",
+ "description": "ไฝฟ็จๅฏ่ชๅฎไน็้้กนๅจๆๆฌๅจๅดๆทปๅ ๅผๅทใ",
+ "inputTitle": "่พๅ
ฅๆๆฌ",
+ "leftQuoteDescription": "ๅทฆๅผๅทๅญ็ฌฆ",
+ "processAsMultiLine": "ไฝไธบๅค่กๆๆฌๅค็",
+ "quoteEmptyLines": "ๅผ็จ็ฉบ่ก",
+ "quoteOptions": "ๆฅไปท้้กน",
+ "resultTitle": "ๅผ็จๆๆฌ",
+ "rightQuoteDescription": "ๅณๅผๅทๅญ็ฌฆ",
+ "shortDescription": "ไฝฟ็จๅ็งๆ ทๅผๅจๆๆฌๅจๅดๆทปๅ ๅผๅท",
+ "title": "ๆๅญๅผ่ฟฐ่
",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅฏ็จไบๅจๆๆฌๅจๅดๆทปๅ ๅผๅทใๆจๅฏไปฅ้ๆฉไธๅ็ๅผๅทๅญ็ฌฆใๅค็ๅค่กๆๆฌไปฅๅๆงๅถ็ฉบ่ก็ๅค็ๆนๅผใๅฎๅฏนไบๅๅค็ผ็จๆๆฌใๆ ผๅผๅๆฐๆฎๆๅๅปบ้ฃๆ ผๅๆๆฌ้ๅธธๆ็จใ",
+ "title": "ๆๅญๅผ่ฟฐ่
"
+ }
+ },
+ "randomizeCase": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๆๆฌๅคงๅฐๅ้ๆบๅๅทฅๅ
ทใ่พๅ
ฅๆๆฌๅ๏ผๅณๅฏ็ซๅณๅฐๅ
ถ่ฝฌๆขไธบ้ๆบ็ๅคงๅฐๅๅญๆฏใ้ๅธธ้ๅๅๅปบ็ฌ็น็ๆๆฌๆๆใๆต่ฏๅคงๅฐๅๆๆๅบฆๆ็ๆไธฐๅฏ็ๆๆฌๆจกๅผใ",
+ "shortDescription": "้ๆบๅๆๆฌไธญๅญๆฏ็ๅคงๅฐๅ",
+ "title": "้ๆบๅๆกไพ"
+ },
+ "removeDuplicateLines": {
+ "description": "ๅจๅทฆไพง็่พๅ
ฅ่กจๅไธญๅ ่ฝฝๆๆฌ๏ผๅณๅฏ็ซๅณๅจ่พๅบๅบๅ่ทๅพๆ ้ๅค่ก็ๆๆฌใๅ่ฝๅผบๅคงใๅ
่ดนไธๅฟซ้ใๅ ่ฝฝๆๆฌ่ก โ ่ทๅ็ฌ็น็ๆๆฌ่ก",
+ "shortDescription": "ๅฟซ้ๅ ้คๆๆฌไธญๆๆ้ๅค็่ก",
+ "title": "ๅ ้ค้ๅค็่ก"
+ },
+ "repeat": {
+ "delimiterDescription": "่พๅบๅฏๆฌ็ๅ้็ฌฆใ",
+ "delimiterPlaceholder": "ๅ้็ฌฆ",
+ "description": "ไฝฟ็จๅฏ่ชๅฎไน็ๅ้็ฌฆๅคๆฌก้ๅคๆๆฌใ",
+ "inputTitle": "่พๅ
ฅๆๆฌ",
+ "numberPlaceholder": "ๆฐๅญ",
+ "repeatAmountDescription": "้ๅคๆฌกๆฐใ",
+ "repetitionsDelimiter": "้ๅคๅ้็ฌฆ",
+ "resultTitle": "้ๅค็ๆๆฌ",
+ "shortDescription": "้ๅคๆๆฌๅคๆฌก",
+ "textRepetitions": "ๆๆฌ้ๅค",
+ "title": "้ๅคๆๆฌ",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจไฝฟ็จๅฏ้ๅ้็ฌฆๅคๆฌก้ๅค็ปๅฎ็ๆๆฌใ",
+ "title": "้ๅคๆๆฌ"
+ }
+ },
+ "reverse": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๆๆฌๅ่ฝฌๅทฅๅ
ทใ่พๅ
ฅไปปๆๆๆฌๅณๅฏ็ซๅณ้ๅญ็ฌฆๅ่ฝฌใ้ๅธธ้ๅๅๅปบ้ๅๆๆฌใๅๆๅๆๆ็ฉ่ฝฌๆๆฌๆจกๅผใๅ่ฝฌๆถไฟ็็ฉบๆ ผๅ็นๆฎๅญ็ฌฆใ",
+ "inputTitle": "ๅ่ฝฌๆๆฌ",
+ "processMultiLine": "ๅค็ๅค่กๆๆฌ",
+ "processMultiLineDescription": "ๆฏ่กๅฐๅ็ฌๅ่ฝฌ",
+ "resultTitle": "ๅ่ฝฌๆๆฌ",
+ "reversalOptions": "้่ฝฌๆๆ",
+ "shortDescription": "้ไธชๅญ็ฌฆๅฐๅ่ฝฌไปปไฝๆๆฌ",
+ "skipEmptyLines": "่ทณ่ฟ็ฉบ่ก",
+ "skipEmptyLinesDescription": "่พๅบไธญ็็ฉบ่กๅฐ่ขซๅ ้ค",
+ "title": "ๆค้",
+ "trimWhitespace": "ไฟฎๅช็ฉบๆ ผ",
+ "trimWhitespaceDescription": "ๅ ้คๆฏ่ก็ๅๅฏผๅๅฐพ้็ฉบๆ ผ"
+ },
+ "rot13": {
+ "description": "ไฝฟ็จ ROT13 ๅฏ็ ๅฏนๆๆฌ่ฟ่ก็ผ็ ๆ่งฃ็ ใ",
+ "inputTitle": "่พๅ
ฅๆๆฌ",
+ "resultTitle": "ROT13 ็ปๆ",
+ "shortDescription": "ไฝฟ็จ ROT13 ๅฏ็ ๅฏนๆๆฌ่ฟ่ก็ผ็ ๆ่งฃ็ ใ",
+ "title": "ROT13็ผ็ ๅจ/่งฃ็ ๅจ",
+ "toolInfo": {
+ "description": "ROT13๏ผๅพช็ฏ13ไฝ๏ผๆฏไธ็ง็ฎๅ็ๅญๆฏๆฟๆขๅฏ็ ๏ผ็จๅญๆฏ่กจไธญ่ฏฅๅญๆฏๅ้ข็็ฌฌ13ไธชๅญๆฏๆฟๆข่ฏฅๅญๆฏใROT13ๆฏๅค็ฝ้ฉฌๅฏๆๅฏ็ ็ไธไธช็นไพใ็ฑไบ่ฑ่ฏญๅญๆฏ่กจๆ26ไธชๅญๆฏ๏ผๅ ๆญคROT13ๆฏๅ
ถ่ช่บซ็้๏ผไนๅฐฑๆฏ่ฏด๏ผ่ฆๆค้ROT13๏ผ้่ฆๅบ็จ็ธๅ็็ฎๆณ๏ผๅ ๆญค็ผ็ ๅ่งฃ็ ็ๆไฝ็ธๅใ",
+ "title": "ROT13 ๆฏไปไน๏ผ"
+ }
+ },
+ "rotate": {
+ "description": "ๆๆๅฎไฝ็ฝฎๆ่ฝฌๆๆฌไธญ็ๅญ็ฌฆใ",
+ "inputTitle": "่พๅ
ฅๆๆฌ",
+ "processAsMultiLine": "ไฝไธบๅค่กๆๆฌๅค็๏ผๅๅซๆ่ฝฌๆฏไธ่ก๏ผ",
+ "resultTitle": "ๆ่ฝฌๆๆฌ",
+ "rotateLeft": "ๅๅทฆๆ่ฝฌ",
+ "rotateRight": "ๅๅณๆ่ฝฌ",
+ "rotationOptions": "ๆ่ฝฌ้้กน",
+ "shortDescription": "ๆไฝ็ฝฎ็งปๅจๆๆฌไธญ็ๅญ็ฌฆใ",
+ "stepDescription": "ๆ่ฝฌไฝ็ฝฎๆฐ",
+ "title": "ๆ่ฝฌๆๆฌ",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจๅฐๅญ็ฌฆไธฒไธญ็ๅญ็ฌฆๆ่ฝฌๆๅฎไฝๆฐใๆจๅฏไปฅๅๅทฆๆๅๅณๆ่ฝฌ๏ผๅนถ้่ฟๅๅซๆ่ฝฌๆฏไธ่กๆฅๅค็ๅค่กๆๆฌใๅญ็ฌฆไธฒๆ่ฝฌๅฏนไบ็ฎๅ็ๆๆฌ่ฝฌๆขใๅๅปบๆจกๅผๆๅฎ็ฐๅบๆฌ็ๅ ๅฏๆๆฏ้ๅธธๆ็จใ",
+ "title": "็ดๅผฆๆ่ฝฌ"
+ }
+ },
+ "split": {
+ "charAfterChunkDescription": "ๆฏไธชๅๅ็ๅญ็ฌฆ",
+ "charBeforeChunkDescription": "ๆฏไธชๅๅ็ๅญ็ฌฆ",
+ "chunksDescription": "่พๅบไธญ็ญ้ฟๆฐๆฎๅ็ๆฐ้ใ",
+ "chunksTitle": "ไฝฟ็จๅคไธชๅ",
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๆๆฌๅๅฒๅทฅๅ
ทใ่พๅ
ฅๆๆฌๅนถๆๅฎๅ้็ฌฆๅณๅฏๅฐๅ
ถๆๅไธบๅคไธช้จๅใ้ๅธธ้ๅๆฐๆฎๅค็ใๆๆฌๆไฝๆไป่พๅคง็ๆๆฌๅไธญๆๅ็นๅฎๅ
ๅฎนใ",
+ "lengthDescription": "ๆฏไธช่พๅบๅไธญๆพๅ
ฅ็็ฌฆๅทๆฐ้ใ",
+ "lengthTitle": "ไฝฟ็จ้ฟๅบฆ่ฟ่กๆๅ",
+ "outputSeparatorDescription": "ๆๅ
ฅๆๅๅไน้ด็ๅญ็ฌฆใ๏ผ้ป่ฎคไธบๆข่ก็ฌฆโ\\nโใ๏ผ",
+ "outputSeparatorOptions": "่พๅบๅ้็ฌฆ้้กน",
+ "regexDescription": "็จไบๅฐๆๆฌๆๅๆๅคไธช้จๅ็ๆญฃๅ่กจ่พพๅผใ๏ผ้ป่ฎคไธบๅคไธช็ฉบๆ ผใ๏ผ",
+ "regexTitle": "ไฝฟ็จๆญฃๅ่กจ่พพๅผ่ฟ่กๆๅ",
+ "resultTitle": "ๆๆฌ็ๆฎต",
+ "shortDescription": "ไฝฟ็จๅ้็ฌฆๅฐๆๆฌๆๅไธบๅคไธช้จๅ",
+ "splitSeparatorOptions": "ๆๅๅ้็ฌฆ้้กน",
+ "symbolDescription": "็จไบๅฐๆๆฌๆๅๆๅคไธช้จๅ็ๅญ็ฌฆใ๏ผ้ป่ฎคไธบ็ฉบๆ ผใ๏ผ",
+ "symbolTitle": "ไฝฟ็จ็ฌฆๅท่ฟ่กๆๅ",
+ "title": "ๅ่ฃ"
+ },
+ "statistic": {
+ "characterFrequencyAnalysis": "ๅญ้ขๅๆ",
+ "characterFrequencyAnalysisDescription": "่ฎก็ฎๆฏไธชๅญ็ฌฆๅจๆๆฌไธญๅบ็ฐ็้ข็",
+ "delimitersOptions": "ๅ้็ฌฆ้้กน",
+ "description": "ๅๆๆๆฌๅนถ็ๆ็ปผๅ็ป่ฎกๆฐๆฎใ",
+ "includeEmptyLines": "ๅ
ๅซ็ฉบ่ก",
+ "includeEmptyLinesDescription": "่ฎก็ฎ่กๆฐๆถๅ
ๅซ็ฉบ่ก",
+ "inputTitle": "่พๅ
ฅๆๆฌ",
+ "resultTitle": "ๆๆฌ็ป่ฎก",
+ "sentenceDelimitersDescription": "่พๅ
ฅ็จไบๅ้ๆจ่ฏญ่จไธญ็ๅฅๅญ็่ชๅฎไนๅญ็ฌฆ๏ผไปฅ้ๅทๅ้๏ผๆๅฐๅ
ถ็็ฉบไฝไธบ้ป่ฎค่ฎพ็ฝฎใ",
+ "sentenceDelimitersPlaceholder": "ไพๅฆใ๏ผ๏ผ๏ผ๏ผ๏ผ...",
+ "shortDescription": "่ทๅๆๅ
ณๆๆฌ็็ป่ฎกๆฐๆฎ",
+ "statisticsOptions": "็ป่ฎก้้กน",
+ "title": "ๆๆฌ็ป่ฎก",
+ "toolInfo": {
+ "description": "่ฏฅๅทฅๅ
ทๅ
่ฎธๆจๅๆๆๆฌๅนถ็ๆๅ
จ้ข็็ป่ฎกๆฐๆฎ๏ผๅ
ๆฌๅญ็ฌฆๆฐใๅญๆฐใ่กๆฐไปฅๅๅญ็ฌฆๅๅ่ฏ็้ข็ๅๆใ",
+ "title": "ไปไนๆฏ {{title}}๏ผ"
+ },
+ "wordDelimitersDescription": "่พๅ
ฅ่ชๅฎไนๆญฃๅ่กจ่พพๅผๆฅ่ฎก็ฎๅ่ฏๆฐ๏ผๆๅฐๅ
ถ็็ฉบไฝไธบ้ป่ฎคๅผใ",
+ "wordDelimitersPlaceholder": "ไพๅฆใ \\s.,;:!?โยซยป()โฆ",
+ "wordFrequencyAnalysis": "่ฏ้ขๅๆ",
+ "wordFrequencyAnalysisDescription": "่ฎก็ฎๆฏไธชๅ่ฏๅจๆๆฌไธญๅบ็ฐ็้ข็"
+ },
+ "textReplacer": {
+ "description": "็จๆฐๅ
ๅฎนๆฟๆขๆๆฌๆจกๅผใ",
+ "findPatternInText": "ๅจๆๆฌไธญๆฅๆพๆญคๆจกๅผ",
+ "findPatternUsingRegexp": "ไฝฟ็จๆญฃๅ่กจ่พพๅผๆฅๆพๆจกๅผ",
+ "inputTitle": "่ฆๆฟๆข็ๆๆฌ",
+ "newTextPlaceholder": "ๆฐๆๆฌ",
+ "regexpDescription": "่พๅ
ฅ่ฆๆฟๆข็ๆญฃๅ่กจ่พพๅผใ",
+ "replacePatternDescription": "่พๅ
ฅ็จไบๆฟๆข็ๆจกๅผใ",
+ "replaceText": "ๆฟๆขๆๆฌ",
+ "resultTitle": "ๅธฆๆฟๆข็ๆๆฌ",
+ "searchPatternDescription": "่พๅ
ฅๆจๆณ่ฆๆฟๆข็ๆๆฌๆจกๅผใ",
+ "searchText": "ๆ็ดขๆๆฌ",
+ "shortDescription": "ๅฟซ้ๆฟๆขๅ
ๅฎนไธญ็ๆๆฌ",
+ "title": "ๆๆฌๆฟๆขๅจ",
+ "toolInfo": {
+ "description": "ไฝฟ็จ่ฟๆฌพๅบไบๆต่งๅจ็็ฎๅๅทฅๅ
ท๏ผ่ฝปๆพๆฟๆขๅ
ๅฎนไธญ็็นๅฎๆๆฌใๅช้่พๅ
ฅๆๆฌ๏ผ่ฎพ็ฝฎ่ฆๆฟๆข็ๆๆฌๅๆฟๆขๅผ๏ผๅณๅฏ็ซๅณ่ทๅๆดๆฐ็ๆฌใ",
+ "title": "ๆๆฌๆฟๆขๅจ"
+ }
+ },
+ "toMorse": {
+ "dashSymbolDescription": "ไธๆฉๅฐๆฏ็ต็ ไธญ็็ ดๆๅท็ธๅฏนๅบ็็ฌฆๅทใ",
+ "description": "ๅฐๆๆฌ่ฝฌๆขไธบๆฉๅฐๆฏ็ต็ ใ",
+ "dotSymbolDescription": "ไธๆฉๅฐๆฏ็ต็ ไธญ็็นๅฏนๅบ็็ฌฆๅทใ",
+ "longSignal": "้ฟไฟกๅท",
+ "resultTitle": "ๆฉๅฐๆฏ็ต็ ",
+ "shortDescription": "ๅฟซ้ๅฐๆๆฌ็ผ็ ไธบๆฉๅฐๆฏ็ต็ ",
+ "shortSignal": "็ญไฟกๅท",
+ "title": "ๅญ็ฌฆไธฒๅฐ่ซๅฐๆฏ"
+ },
+ "truncate": {
+ "addTruncationIndicator": "ๆทปๅ ๆชๆญๆ็คบ็ฌฆ",
+ "charactersPlaceholder": "ไบบ็ฉ",
+ "description": "ๅฐๆๆฌ็ผฉ็ญ่ณๆๅฎ้ฟๅบฆใ",
+ "indicatorDescription": "ๅจๆๆฌๆซๅฐพ๏ผๆๅผๅคด๏ผๆทปๅ ็ๅญ็ฌฆใๆณจๆ๏ผ่ฟไบๅญ็ฌฆ่ฎกๅ
ฅ้ฟๅบฆใ",
+ "inputTitle": "่พๅ
ฅๆๆฌ",
+ "leftSideDescription": "ไปๆๆฌๅผๅคดๅ ้คๅญ็ฌฆใ",
+ "leftSideTruncation": "ๅทฆไพงๆชๆญ",
+ "lengthAndLines": "้ฟๅบฆๅ็บฟๆก",
+ "lineByLineDescription": "ๅๅซๆชๆญๆฏไธ่กใ",
+ "lineByLineTruncating": "้่กๆชๆญ",
+ "maxLengthDescription": "ๆๆฌไธญไฟ็็ๅญ็ฌฆๆฐใ",
+ "numberPlaceholder": "ๆฐๅญ",
+ "resultTitle": "ๆๆฌ่ขซๆชๆญ",
+ "rightSideDescription": "ๅ ้คๆๆฌๆซๅฐพ็ๅญ็ฌฆใ",
+ "rightSideTruncation": "ๅณไพงๆชๆญ",
+ "shortDescription": "ๅฐๆๆฌๆชๆญไธบๆๅฎ้ฟๅบฆ",
+ "suffixAndAffix": "ๅ็ผๅ่ฏ็ผ",
+ "title": "ๆชๆญๆๆฌ",
+ "toolInfo": {
+ "description": "ๅจๅทฆไพง็่พๅ
ฅ่กจๅไธญๅ ่ฝฝๆจ็ๆๆฌ๏ผๆจๅฐ่ชๅจๅจๅณไพง่ทๅพๆชๆญๆๆฌใ",
+ "title": "ๆชๆญๆๆฌ"
+ },
+ "truncationSide": "ๆชๆญไพง"
+ },
+ "uppercase": {
+ "description": "ๅฐๆๆฌ่ฝฌๆขไธบๅคงๅๅญๆฏใ",
+ "inputTitle": "่พๅ
ฅๆๆฌ",
+ "resultTitle": "ๅคงๅๆๆฌ",
+ "shortDescription": "ๅฐๆๆฌ่ฝฌๆขไธบๅคงๅ",
+ "title": "่ฝฌๆขไธบๅคงๅ"
+ }
+}
diff --git a/public/locales/zh/time.json b/public/locales/zh/time.json
new file mode 100644
index 0000000..ffcf212
--- /dev/null
+++ b/public/locales/zh/time.json
@@ -0,0 +1,100 @@
+{
+ "checkLeapYears": {
+ "description": "ๆฃๆฅๆไธๅนดไปฝๆฏๅฆไธบ้ฐๅนดๅนถ่ทๅ้ฐๅนดไฟกๆฏใ",
+ "inputTitle": "่พๅ
ฅๅนดไปฝ",
+ "resultTitle": "้ฐๅนด็ปๆ",
+ "shortDescription": "ๆฃๆฅๅนดไปฝๆฏๅฆไธบ้ฐๅนด",
+ "title": "ๆฃๆฅ้ฐๅนด",
+ "toolInfo": {
+ "description": "้ฐๅนดๆฏๆๅจๆฏๅนด็2ๆ29ๆฅๅขๅ ไธๅคฉ๏ผไปฅไฝฟๆฅๅๅนดไธๅคฉๆๅนดไฟๆไธ่ดใ้ฐๅนดๆฏ4ๅนดไธๆฌก๏ผไฝ่ฝ่ขซ100ๆด้คไฝไธ่ฝ่ขซ400ๆด้ค็ๅนดไปฝ้คๅคใ",
+ "title": "ไปไนๆฏ้ฐๅนด๏ผ"
+ }
+ },
+ "convertDaysToHours": {
+ "addHoursName": "ๆทปๅ ่ฅไธๆถ้ดๅ็งฐ",
+ "addHoursNameDescription": "ๅฐๅญ็ฌฆไธฒ hours ้ๅ ๅฐ่พๅบๅผ",
+ "description": "ไฝฟ็จๅฏ่ชๅฎไน็้้กนๅฐๅคฉๆฐ่ฝฌๆขไธบๅฐๆถๆฐใ",
+ "hoursName": "่ฅไธๆถ้ดๅ็งฐ",
+ "shortDescription": "ๅฐๅคฉๆฐ่ฝฌๆขไธบๅฐๆถๆฐ",
+ "title": "ๅฐๅคฉๆฐ่ฝฌๆขไธบๅฐๆถๆฐ",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅฏ่ฎฉๆจๅฐๅคฉๆฐ่ฝฌๆขไธบๅฐๆถๆฐใๆจๅฏไปฅ่พๅ
ฅๆฐๅญๆๅไฝๅฝขๅผ็ๅคฉๆฐ๏ผ่ฏฅๅทฅๅ
ทไผๅฐๅ
ถ่ฝฌๆขไธบๅฐๆถๆฐใๆจ่ฟๅฏไปฅ้ๆฉๅจ่พๅบๅผๅ้ๅ โๅฐๆถโๅ็ผใ",
+ "title": "ๅฐๅคฉๆฐ่ฝฌๆขไธบๅฐๆถๆฐ"
+ }
+ },
+ "convertHoursToDays": {
+ "addDaysName": "ๆทปๅ ๆฅๆๅ็งฐ",
+ "addDaysNameDescription": "ๅฐๅญ็ฌฆไธฒ days ้ๅ ๅฐ่พๅบๅผ",
+ "daysName": "ๆฅๆๅ็งฐ",
+ "description": "ไฝฟ็จๅฏ่ชๅฎไน็้้กนๅฐๅฐๆถ่ฝฌๆขไธบๅคฉใ",
+ "shortDescription": "ๅฐๅฐๆถ่ฝฌๆขไธบๅคฉ",
+ "title": "ๅฐๅฐๆถ่ฝฌๆขไธบๅคฉ",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅฏ่ฎฉๆจๅฐๅฐๆถ่ฝฌๆขไธบๅคฉใๆจๅฏไปฅ่พๅ
ฅๆฐๅญๆๅไฝๅฝขๅผ็ๅฐๆถ๏ผ่ฏฅๅทฅๅ
ทไผๅฐๅ
ถ่ฝฌๆขไธบๅคฉใๆจ่ฟๅฏไปฅ้ๆฉๅจ่พๅบๅผๅ้ๅ โๅคฉโๅ็ผใ",
+ "title": "ๅฐๅฐๆถ่ฝฌๆขไธบๅคฉ"
+ }
+ },
+ "convertSecondsToTime": {
+ "addPadding": "ๆทปๅ ๅกซๅ
",
+ "addPaddingDescription": "ๅจๅฐๆถใๅ้ๅ็งๅๆทปๅ ้ถๅกซๅ
ใ",
+ "description": "ๅฐ็ง่ฝฌๆขไธบๅฏ่ฏป็ๆถ้ดๆ ผๅผ๏ผๅฐๆถ:ๅ้:็ง๏ผใ่พๅ
ฅ็งๆฐๅณๅฏ่ทๅๆ ผๅผๅ็ๆถ้ดใ",
+ "shortDescription": "ๅฐ็งๆฐ่ฝฌๆขไธบๆถ้ดๆ ผๅผ",
+ "timePadding": "ๆถ้ดๅกซๅ
",
+ "title": "ๅฐ็ง่ฝฌๆขไธบๆถ้ด",
+ "toolInfo": {
+ "title": "ไปไนๆฏ {{title}}๏ผ"
+ }
+ },
+ "convertTimeToSeconds": {
+ "description": "ๅฐๆ ผๅผๅ็ๆถ้ด๏ผHH๏ผMM๏ผSS๏ผ่ฝฌๆขไธบ็งใ",
+ "inputTitle": "่พๅ
ฅๆถ้ด",
+ "resultTitle": "็ง",
+ "shortDescription": "ๅฐๆถ้ดๆ ผๅผ่ฝฌๆขไธบ็ง",
+ "title": "ๅฐๆถ้ด่ฝฌๆขไธบ็ง",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅฏ่ฎฉๆจๅฐๆ ผๅผๅ็ๆถ้ดๅญ็ฌฆไธฒ (HH:MM:SS) ่ฝฌๆขไธบ็งใๅฎๅฏนไบ่ฎก็ฎๆ็ปญๆถ้ดๅๆถ้ด้ด้้ๅธธๆ็จใ",
+ "title": "ๅฐๆถ้ด่ฝฌๆขไธบ็ง"
+ }
+ },
+ "crontabGuru": {
+ "description": "็ๆๅนถ็่งฃ cron ่กจ่พพๅผใไธบ่ชๅจๅไปปๅกๅ็ณป็ปไฝไธๅๅปบ cron ่ฎกๅใ",
+ "shortDescription": "็ๆๅนถ็่งฃ cron ่กจ่พพๅผ",
+ "title": "Crontab ๅคงๅธ"
+ },
+ "timeBetweenDates": {
+ "description": "่ฎก็ฎไธคไธชๆฅๆไน้ด็ๆถๅทฎใ่ทๅ็ฒพ็กฎ็ๅคฉใๅฐๆถใๅ้ๅ็งๆฐใ",
+ "endDate": "็ปๆๆฅๆ",
+ "endDateTime": "็ปๆๆฅๆๅๆถ้ด",
+ "endTime": "็ปๆๆถ้ด",
+ "endTimezone": "็ปๆๆถๅบ",
+ "shortDescription": "่ฎก็ฎไธคไธชๆฅๆไน้ด็ๆถ้ด",
+ "startDate": "ๅผๅงๆฅๆ",
+ "startDateTime": "ๅผๅงๆฅๆๅๆถ้ด",
+ "startTime": "ๅผๅงๆถ้ด",
+ "startTimezone": "ๅผๅงๆถๅบ",
+ "title": "ๆฅๆ้ด้ๆถ้ด",
+ "toolInfo": {
+ "description": "่ฎก็ฎไธคไธชๆฅๆๅๆถ้ดไน้ด็็ฒพ็กฎๆถๅทฎ๏ผๆฏๆไธๅๆถๅบใๆญคๅทฅๅ
ทๆไพๆไธๅๅไฝ๏ผๅนดใๆใๆฅใๆถใๅใ็ง๏ผ่ฎก็ฎ็่ฏฆ็ปๆถๅทฎ็ปๅใ",
+ "title": "ๆฅๆ้ด้ๆถ้ด่ฎก็ฎๅจ"
+ }
+ },
+ "truncateClockTime": {
+ "description": "ๆชๆญๆถ้ๆถ้ดไปฅๅ ้ค็งๆฐๆๅ้ๆฐใๅฐๆถ้ดๅ่ไบๅ
ฅๅฐๆๆฅ่ฟ็ๅฐๆถๆฐใๅ้ๆฐๆ่ชๅฎไน้ด้ใ",
+ "printDroppedComponents": "ๆๅฐๆ่ฝ็็ปไปถ",
+ "shortDescription": "ๅฐๆถ้ๆถ้ดๆชๆญไธบๆๅฎ็็ฒพๅบฆ",
+ "timePadding": "ๆถ้ดๅกซๅ
",
+ "title": "ๆชๆญๆถ้ๆถ้ด",
+ "toolInfo": {
+ "title": "ไปไนๆฏ {{title}}๏ผ"
+ },
+ "truncateMinutesAndSeconds": "ๆชๆญๅ้ๅ็ง",
+ "truncateMinutesAndSecondsDescription": "ๅ ้คๆฏไธชๆถ้ๆถ้ดไธญ็ๅ้ๅ็ง้จๅใ",
+ "truncateOnlySeconds": "ไป
ๆชๆญ็งๆฐ",
+ "truncateOnlySecondsDescription": "ไปๆฏไธชๆถ้ๆถ้ดไธญๅ ้ค็งๆฐ้จๅใ",
+ "truncationSide": "ๆชๆญไพง",
+ "useZeroPadding": "ไฝฟ็จ้ถๅกซๅ
",
+ "zeroPaddingDescription": "ไฝฟๆๆๆถ้ด้จๅๅง็ปไธบไธคไฝๆฐๅฎฝๅบฆใ",
+ "zeroPrintDescription": "ๅฐๅ ้ค็้จๅๆพ็คบไธบ้ถๅผโ00โใ",
+ "zeroPrintTruncatedParts": "้ถๆๅฐๆชๆญ้จไปถ"
+ }
+}
diff --git a/public/locales/zh/translation.json b/public/locales/zh/translation.json
new file mode 100644
index 0000000..e240e2d
--- /dev/null
+++ b/public/locales/zh/translation.json
@@ -0,0 +1,250 @@
+{
+ "audio": {
+ "changeSpeed": {
+ "description": "ๆดๆน้ณ้ขๆไปถ็ๆญๆพ้ๅบฆใๅจไฟๆ้ณ่ฐไธๅ็ๆ
ๅตไธๅ ๅฟซๆๅๆ
ข้ณ้ข้ๅบฆใ",
+ "name": "ๆดๆน้ณ้ข้ๅบฆ",
+ "shortDescription": "ๆดๆน้ณ้ขๆไปถ็้ๅบฆ"
+ },
+ "extractAudio": {
+ "description": "ไป่ง้ขๆไปถไธญๆๅ้ณ่ฝจๅนถๅฐๅ
ถไฟๅญไธบๆจ้ๆฉ็ๆ ผๅผ๏ผAACใMP3ใWAV๏ผ็ๅ็ฌ้ณ้ขๆไปถใ",
+ "name": "ๆๅ้ณ้ข",
+ "shortDescription": "ๅฐ่ง้ขๆไปถ๏ผMP4ใMOV ็ญ๏ผไธญ็้ณ้ขๆๅไธบ AACใMP3 ๆ WAVใ"
+ }
+ },
+ "baseFileInput": {
+ "copyFailed": "ๅคๅถๅคฑ่ดฅ๏ผ {{error}}",
+ "dropFileHere": "ๆพไธไฝ ็ {{type}} ่ฟ้",
+ "fileCopied": "ๆไปถๅทฒๅคๅถ",
+ "selectFileDescription": "ๅๅปๆญคๅค้ๆฉไธไธช {{type}} ๅจๆจ็่ฎพๅคไธ๏ผๆ Ctrl+V ไฝฟ็จ {{type}} ไปๅช่ดดๆฟไธญ๏ผๆไปๆก้ขๆๆพๆไปถ"
+ },
+ "categories": {
+ "audio": {
+ "description": "ๅค็้ณ้ข็ๅทฅๅ
ทโโไป่ง้ขไธญๆๅ้ณ้ขใ่ฐๆด้ณ้ข้ๅบฆใๅๅนถๅคไธช้ณ้ขๆไปถ็ญ็ญใ",
+ "title": "้ณ้ขๅทฅๅ
ท"
+ },
+ "csv": {
+ "description": "ๅค็ CSV ๆไปถ็ๅทฅๅ
ท - ๅฐ CSV ่ฝฌๆขไธบไธๅ็ๆ ผๅผใๆไฝ CSV ๆฐๆฎใ้ช่ฏ CSV ็ปๆไปฅๅๆๆๅฐๅค็ CSV ๆไปถใ",
+ "title": "CSV ๅทฅๅ
ท"
+ },
+ "gif": {
+ "description": "ๅค็ GIF ๅจ็ป็ๅทฅๅ
ท - ๅๅปบ้ๆ GIFใๆๅ GIF ๅธงใๅ GIF ๆทปๅ ๆๆฌใ่ฃๅชใๆ่ฝฌใๅ่ฝฌ GIF ็ญ็ญใ",
+ "title": "GIFๅทฅๅ
ท"
+ },
+ "image-generic": {
+ "description": "ๅค็ๅพ็็ๅทฅๅ
ทโโๅ็ผฉใ่ฐๆดๅคงๅฐใ่ฃๅชใ่ฝฌๆขไธบ JPGใๆ่ฝฌใๅ ้ค่ๆฏ็ญ็ญใ",
+ "title": "ๅพๅๅทฅๅ
ท"
+ },
+ "json": {
+ "description": "ๅค็ JSON ๆฐๆฎ็ปๆ็ๅทฅๅ
ทโโ็พๅๅ็ผฉๅฐ JSON ๅฏน่ฑกใๅฑๅนณ JSON ๆฐ็ปใๅญ็ฌฆไธฒๅ JSON ๅผใๅๆๆฐๆฎ็ญ็ญ",
+ "title": "JSON ๅทฅๅ
ท"
+ },
+ "list": {
+ "description": "ๅค็ๅ่กจ็ๅทฅๅ
ทโโๆๅบใๅ่ฝฌใ้ๆบๅๅ่กจใๆฅๆพๅฏไธๅ้ๅค็ๅ่กจ้กนใๆดๆนๅ่กจ้กนๅ้็ฌฆ็ญ็ญใ",
+ "title": "ๅ่กจๅทฅๅ
ท"
+ },
+ "number": {
+ "description": "ๅค็ๆฐๅญ็ๅทฅๅ
ทโโ็ๆๆฐๅญๅบๅใๅฐๆฐๅญ่ฝฌๆขไธบๆๅญใๅฐๆๅญ่ฝฌๆขไธบๆฐๅญใๆๅบใ่ๅ
ฅใๅ ๅผๅ่งฃ็ญ็ญใ",
+ "title": "ๆฐๅญๅทฅๅ
ท"
+ },
+ "pdf": {
+ "description": "ๅค็ PDF ๆไปถ็ๅทฅๅ
ท - ไป PDF ไธญๆๅๆๆฌใๅฐ PDF ่ฝฌๆขไธบๅ
ถไปๆ ผๅผใๆไฝ PDF ็ญ็ญใ",
+ "title": "PDFๅทฅๅ
ท"
+ },
+ "png": {
+ "description": "ๅค็ PNG ๅพๅ็ๅทฅๅ
ท - ๅฐ PNG ่ฝฌๆขไธบ JPGใๅๅปบ้ๆ PNGใๆดๆน PNG ้ข่ฒใ่ฃๅชใๆ่ฝฌใ่ฐๆด PNG ๅคงๅฐ็ญ็ญใ",
+ "title": "PNGๅทฅๅ
ท"
+ },
+ "seeAll": "ๆฅ็ๅ
จ้จ {{title}}",
+ "string": {
+ "description": "ๅค็ๆๆฌ็ๅทฅๅ
ทโโๅฐๆๆฌ่ฝฌๆขไธบๅพๅใๆฅๆพๅๆฟๆขๆๆฌใๅฐๆๆฌๆๅๆ็ๆฎตใ่ฟๆฅๆๆฌ่กใ้ๅคๆๆฌ็ญ็ญใ",
+ "title": "ๆๆฌๅทฅๅ
ท"
+ },
+ "time": {
+ "description": "ๅค็ๆถ้ดๅๆฅๆ็ๅทฅๅ
ทโโ่ฎก็ฎๆถๅทฎใๅจๆถๅบไน้ด่ฝฌๆขใๆ ผๅผๅๆฅๆใ็ๆๆฅๆๅบๅ็ญ็ญใ",
+ "title": "ๆถ้ดๅทฅๅ
ท"
+ },
+ "try": "ๅฐ่ฏ {{title}}",
+ "video": {
+ "description": "ๅค็่ง้ข็ๅทฅๅ
ทโโไป่ง้ขไธญๆๅๅธงใไป่ง้ขๅๅปบ GIFใๅฐ่ง้ข่ฝฌๆขไธบไธๅ็ๆ ผๅผ็ญ็ญใ",
+ "title": "่ง้ขๅทฅๅ
ท"
+ },
+ "xml": {
+ "description": "ๅค็ XML ๆฐๆฎ็ปๆ็ๅทฅๅ
ท - ๆฅ็ๅจใ็พๅๅจใ้ช่ฏๅจ็ญ็ญ",
+ "title": "XML ๅทฅๅ
ท"
+ }
+ },
+ "csv": {
+ "findIncompleteCsvRecords": {
+ "description": "ๅช้ๅฐๆจ็ CSV ๆไปถไธไผ ๅฐไธๆน่กจๅ๏ผๆญคๅทฅๅ
ทๅฐฑไผ่ชๅจๆฃๆฅๆๆ่กๆๅๆฏๅฆๅ็ผบๅคฑๅผใๅจๅทฅๅ
ท้้กนไธญ๏ผๆจๅฏไปฅ่ฐๆด่พๅ
ฅๆไปถๆ ผๅผ๏ผๆๅฎๅ้็ฌฆใๅผๅทๅๆณจ้็ฌฆ๏ผใๆญคๅค๏ผๆจ่ฟๅฏไปฅๅฏ็จ็ฉบๅผๆฃๆฅใ่ทณ่ฟ็ฉบ่ก๏ผไปฅๅ่ฎพ็ฝฎ่พๅบไธญ้่ฏฏๆถๆฏ็ๆฐ้้ๅถใ",
+ "name": "ๆฅๆพไธๅฎๆด็ CSV ่ฎฐๅฝ",
+ "shortDescription": "ๅฟซ้ๆฅๆพ CSV ไธญ็ผบๅฐๅผ็่กๅๅใ"
+ }
+ },
+ "hero": {
+ "brand": "OmniTools",
+ "description": "ไฝฟ็จ OmniTools ๆๅๆจ็ๅทฅไฝๆ็๏ผ่ฟๆฏไธๆฌพๅฟซ้ๅฎๆไปปๅก็็ปๆๅทฅๅ
ทๅ
๏ผๆฐๅไธช็จๆทๅๅฅฝ็ๅฎ็จ็จๅบ๏ผๅฏ็ดๆฅ้่ฟๆต่งๅจ็ผ่พๅพๅใๆๆฌใๅ่กจๅๆฐๆฎใ",
+ "examples": {
+ "calculateNumberSum": "่ฎก็ฎๆฐๅญๅ",
+ "changeGifSpeed": "ๆดๆน GIF ้ๅบฆ",
+ "compressPng": "ๅ็ผฉ PNG",
+ "createTransparentImage": "ๅๅปบ้ๆๅพๅ",
+ "prettifyJson": "็พๅ JSON",
+ "sortList": "ๅฏนๅ่กจ่ฟ่กๆๅบ",
+ "splitPdf": "ๆๅ PDF",
+ "splitText": "ๆๅๆๆฌ",
+ "trimVideo": "ไฟฎๅช่ง้ข"
+ },
+ "searchPlaceholder": "ๆ็ดขๆๆๅทฅๅ
ท",
+ "title": "ๅฟซ้ๅฎๆๅทฅไฝ"
+ },
+ "inputFooter": {
+ "clear": "ๆธ
้ค",
+ "copyToClipboard": "ๅคๅถๅฐๅช่ดดๆฟ",
+ "importFromFile": "ไปๆไปถๅฏผๅ
ฅ"
+ },
+ "list": {
+ "group": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅ่กจ้กนๅ็ปๅทฅๅ
ทใ่พๅ
ฅๆจ็ๅ่กจๅนถๆๅฎๅ็ปๆกไปถ๏ผๅณๅฏๅฐ้กน็ฎๆ้ป่พๅ็ปใ้ๅธธ้ๅๅ็ฑปๆฐๆฎใ็ป็ปไฟกๆฏๆๅๅปบ็ปๆๅๅ่กจใๆฏๆ่ชๅฎไนๅ้็ฌฆๅๅ็งๅ็ป้้กนใ",
+ "name": "ๅขไฝ",
+ "shortDescription": "ๆๅ
ฑๅๅฑๆงๅฏนๅ่กจ้กน่ฟ่กๅ็ป"
+ },
+ "reverse": {
+ "description": "่ฟๆฏไธไธชๅบไบๆต่งๅจ็่ถ
็บง็ฎๅ็ๅบ็จ็จๅบ๏ผๅฏไปฅๅๅๆๅฐๆๆๅ่กจ้กนใ่พๅ
ฅ้กนๅฏไปฅ็จไปปๆ็ฌฆๅทๅ้๏ผๅนถไธๆจ่ฟๅฏไปฅๆดๆนๅๅๅ่กจ้กน็ๅ้็ฌฆใ",
+ "name": "ๆค้",
+ "shortDescription": "ๅฟซ้ๅ่ฝฌๅ่กจ"
+ },
+ "sort": {
+ "description": "่ฟๆฏไธๆฌพๅบไบๆต่งๅจ็่ถ
็บง็ฎๅๅบ็จ็จๅบ๏ผๅฏไปฅๅฏนๅ่กจไธญ็้กน็ฎ่ฟ่กๆๅบ๏ผๅนถๆๅๅบๆ้ๅบๆๅใๆจๅฏไปฅๆๅญๆฏ้กบๅบใๆฐๅญๆ้ฟๅบฆๅฏน้กน็ฎ่ฟ่กๆๅบใๆจ่ฟๅฏไปฅๅ ้ค้ๅคๅ็ฉบ็ฝ็้กน็ฎ๏ผไปฅๅไฟฎๅชๅจๅดๆ็ฉบๆ ผ็ๅไธช้กน็ฎใๆจๅฏไปฅไฝฟ็จไปปไฝๅ้็ฌฆๅ้่พๅ
ฅๅ่กจ้กน๏ผไนๅฏไปฅไฝฟ็จๆญฃๅ่กจ่พพๅผๅ้ๅฎไปฌใๆญคๅค๏ผๆจ่ฟๅฏไปฅไธบๆๅบๅ็่พๅบๅ่กจๅๅปบๆฐ็ๅ้็ฌฆใ",
+ "name": "็ง็ฑป",
+ "shortDescription": "ๅฟซ้ๅฏนๅ่กจ่ฟ่กๆๅบ"
+ }
+ },
+ "navbar": {
+ "buyMeACoffee": "่ฏทๆๅๆฏๅๅก",
+ "home": "ๅฎถ",
+ "tools": "ๅทฅๅ
ท"
+ },
+ "number": {
+ "generate": {
+ "description": "ๅจๆต่งๅจไธญๅฟซ้่ฎก็ฎๆดๆฐๅ่กจใ่ฆ่ทๅๅ่กจ๏ผๅช้ๆๅฎ็ฌฌไธไธชๆดๆฐ๏ผๅนถๅจไธๆน้้กนไธญๆดๆนๅผๅๆปๆฐ๏ผๆญคๅฎ็จ็จๅบๅฐฑไผ็ๆ็ธๅบๆฐ้็ๆดๆฐใ",
+ "name": "็ๆๆฐๅญ",
+ "shortDescription": "ๅจๆต่งๅจไธญๅฟซ้่ฎก็ฎๆดๆฐๅ่กจ"
+ },
+ "sum": {
+ "description": "่ฟๆฏไธๆฌพๅบไบๆต่งๅจ็่ถ
็บง็ฎๅ็ๆฑๅๅบ็จ็จๅบใ่พๅ
ฅ็ๆฐๅญๅฏไปฅ็จไปปๆ็ฌฆๅทๅ้๏ผๅนถไธๆจ่ฟๅฏไปฅๆดๆนๆฑๅ็ปๆ็ๅ้็ฌฆใ",
+ "name": "ๆปๅๆฐ",
+ "shortDescription": "ๅฟซ้ๅฏนๆฐๅญๅ่กจๆฑๅ"
+ }
+ },
+ "numericInputWithUnit": {
+ "unit": "ๅๅ
"
+ },
+ "pdf": {
+ "compressPdf": {
+ "description": "ไฝฟ็จ Ghostscript ๅๅฐ PDF ๆไปถๅคงๅฐๅๆถไฟๆ่ดจ้",
+ "name": "ๅ็ผฉPDF",
+ "shortDescription": "ๅจๆต่งๅจไธญๅฎๅ
จๅฐๅ็ผฉ PDF ๆไปถ"
+ },
+ "mergePdf": {
+ "description": "ๅๅนถๅคไธช PDF ๆไปถไธบไธไธชๆๆกฃใ",
+ "name": "ๅๅนถ PDF",
+ "shortDescription": "ๅฐๅคไธช PDF ๆไปถๅๅนถไธบไธไธชๆๆกฃ"
+ },
+ "pdfToEpub": {
+ "description": "ๅฐ PDF ๆๆกฃ่ฝฌๆขไธบ EPUB ๆไปถ๏ผไปฅๅฎ็ฐๆดๅฅฝ็็ตๅญ้
่ฏปๅจๅ
ผๅฎนๆงใ",
+ "name": "PDF ่ฝฌ EPUB",
+ "shortDescription": "ๅฐ PDF ๆไปถ่ฝฌๆขไธบ EPUB ๆ ผๅผ"
+ },
+ "protectPdf": {
+ "description": "ๅจๆต่งๅจไธญๅฎๅ
จๅฐไธบ PDF ๆไปถๆทปๅ ๅฏ็ ไฟๆค",
+ "name": "ไฟๆค PDF",
+ "shortDescription": "ไฝฟ็จๅฏ็ ๅฎๅ
จๅฐไฟๆค PDF ๆไปถ"
+ },
+ "splitPdf": {
+ "description": "ไฝฟ็จ้กต็ ๆ่ๅด๏ผไพๅฆ 1,5-8๏ผไป PDF ๆไปถไธญๆๅ็นๅฎ้กต้ข",
+ "name": "ๆๅ PDF",
+ "shortDescription": "ไป PDF ๆไปถไธญๆๅ็นๅฎ้กต้ข"
+ }
+ },
+ "resultFooter": {
+ "copy": "ๅคๅถๅฐๅช่ดดๆฟ",
+ "download": "ไธ่ฝฝ"
+ },
+ "string": {
+ "createPalindrome": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅๆๅๅปบๅทฅๅ
ท๏ผๅฏไปไปปไฝๆๆฌๅๅปบๅๆใ่พๅ
ฅๆๆฌๅณๅฏ็ซๅณๅฐๅ
ถ่ฝฌๆขไธบๆญฃๅ่ฏป็ธๅ็ๅๆใ้ๅธธ้ๅๆๅญๆธธๆใๅๅปบๅฏน็งฐๆๆฌๆจกๅผๆๆข็ดข่ฏญ่จๅญฆ็ฅ่ฏใ",
+ "name": "ๅๅปบๅๆ",
+ "shortDescription": "ๅๅปบๆญฃ่ฏปๅๅ่ฏป็ธๅ็ๆๆฌ"
+ },
+ "palindrome": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅๆๆฃๆตๅทฅๅ
ทใๅณๆถ้ช่ฏๆๆฌๆญฃ่ฏปๅๅ่ฏปๆฏๅฆไธ่ดใ้ๅธธ้ๅๅญ่ฐๆธธๆใ่ฏญ่จๅๆๆ้ช่ฏๅฏน็งฐๆๆฌๆจกๅผใๆฏๆๅ็งๅ้็ฌฆๅๅค่ฏๅๆๆฃๆตใ",
+ "name": "ๅๆ",
+ "shortDescription": "ๆฃๆฅๆๆฌๆญฃ่ฏปๅๅ่ฏปๆฏๅฆ็ธๅ"
+ },
+ "repeat": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจไฝฟ็จๅฏ้ๅ้็ฌฆๅคๆฌก้ๅค็ปๅฎ็ๆๆฌใ",
+ "name": "้ๅคๆๆฌ",
+ "shortDescription": "้ๅคๆๆฌๅคๆฌก"
+ },
+ "reverse": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๆๆฌๅ่ฝฌๅทฅๅ
ทใ่พๅ
ฅไปปๆๆๆฌๅณๅฏ็ซๅณ้ๅญ็ฌฆๅ่ฝฌใ้ๅธธ้ๅๅๅปบ้ๅๆๆฌใๅๆๅๆๆ็ฉ่ฝฌๆๆฌๆจกๅผใๅ่ฝฌๆถไฟ็็ฉบๆ ผๅ็นๆฎๅญ็ฌฆใ",
+ "name": "ๆค้",
+ "shortDescription": "้ไธชๅญ็ฌฆๅฐๅ่ฝฌไปปไฝๆๆฌ"
+ },
+ "toMorse": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๆๆฌ่ฝฌๆฉๅฐๆฏ็ต็ ๅทฅๅ
ทใๅช้ๅจๅทฆไพง่พๅ
ฅๆกไธญ่พๅ
ฅๆๆฌ๏ผๅณๅฏ็ซๅณๅจ่พๅบๅบๅ่ทๅพๆฉๅฐๆฏ็ต็ ใๅ่ฝๅผบๅคงใๅ
่ดนไธๅฟซ้ใ่พๅ
ฅๆๆฌ๏ผๅณๅฏ่ทๅพๆฉๅฐๆฏ็ต็ ใ",
+ "name": "ๅญ็ฌฆไธฒๅฐ่ซๅฐๆฏ",
+ "shortDescription": "ๅฟซ้ๅฐๆๆฌ็ผ็ ไธบๆฉๅฐๆฏ็ต็ "
+ },
+ "uppercase": {
+ "description": "ไธ็ไธๆ็ฎๅ็ๅบไบๆต่งๅจ็ๅคงๅๆๆฌ่ฝฌๆขๅทฅๅ
ทใๅช้่พๅ
ฅๆๆฌ๏ผๅณๅฏ่ชๅจ่ฝฌๆขไธบๅ
จ้จๅคงๅๅญๆฏใ้ๅธธ้ๅๅๅปบๆ ้ขใๅผบ่ฐๆๆฌๆๆ ๅๅๆๆฌๆ ผๅผใๆฏๆๅ็งๆๆฌๆ ผๅผๅนถไฟ็็นๆฎๅญ็ฌฆใ",
+ "name": "ๅคงๅ",
+ "shortDescription": "ๅฐๆๆฌ่ฝฌๆขไธบๅคงๅๅญๆฏ"
+ }
+ },
+ "toolExamples": {
+ "subtitle": "็นๅปๅฐ่ฏ๏ผ",
+ "title": "{{title}} ็คบไพ"
+ },
+ "toolFileResult": {
+ "copied": "ๆไปถๅทฒๅคๅถ",
+ "copyFailed": "ๅคๅถๅคฑ่ดฅ๏ผ {{error}}",
+ "loading": "ๆญฃๅจๅ ่ฝฝ...่ฟๅฏ่ฝ้่ฆไธ็นๆถ้ดใ",
+ "result": "็ปๆ"
+ },
+ "toolHeader": {
+ "seeExamples": "ๆฅ็็คบไพ"
+ },
+ "toolLayout": {
+ "allToolsTitle": "ๅ
จ้จ {{type}}"
+ },
+ "toolMultiFileResult": {
+ "copied": "ๆไปถๅทฒๅคๅถ",
+ "copyFailed": "ๅคๅถๅคฑ่ดฅ๏ผ {{error}}",
+ "loading": "ๆญฃๅจๅ ่ฝฝ...่ฟๅฏ่ฝ้่ฆไธ็นๆถ้ดใ",
+ "result": "็ปๆ"
+ },
+ "toolMultipleAudioInput": {
+ "inputTitle": "่พๅ
ฅ {{type}}",
+ "noFilesSelected": "ๆช้ๆฉไปปไฝๆไปถ"
+ },
+ "toolMultiplePdfInput": {
+ "inputTitle": "่พๅ
ฅ {{type}}",
+ "noFilesSelected": "ๆช้ๆฉไปปไฝๆไปถ"
+ },
+ "toolOptions": {
+ "title": "ๅทฅๅ
ท้้กน"
+ },
+ "toolTextInput": {
+ "copied": "ๆๆฌๅทฒๅคๅถ",
+ "copyFailed": "ๅคๅถๅคฑ่ดฅ๏ผ {{error}}",
+ "input": "่พๅ
ฅๆๆฌ",
+ "placeholder": "ๅจๆญคๅค่พๅ
ฅๆจ็ๆๆฌ..."
+ },
+ "toolTextResult": {
+ "copied": "ๆๆฌๅทฒๅคๅถ",
+ "copyFailed": "ๅคๅถๅคฑ่ดฅ๏ผ {{error}}",
+ "loading": "ๆญฃๅจๅ ่ฝฝ...่ฟๅฏ่ฝ้่ฆไธ็นๆถ้ดใ",
+ "result": "็ปๆ"
+ }
+}
diff --git a/public/locales/zh/video.json b/public/locales/zh/video.json
new file mode 100644
index 0000000..c37ea1a
--- /dev/null
+++ b/public/locales/zh/video.json
@@ -0,0 +1,113 @@
+{
+ "changeSpeed": {
+ "defaultMultiplier": "้ป่ฎคไนๆฐ๏ผ2 ่กจ็คบ้ๅบฆๅฟซ 2 ๅ",
+ "description": "ๆดๆน่ง้ขๆไปถ็ๆญๆพ้ๅบฆใๅจไฟๆ้ณ้ขๅๆญฅ็ๅๆถ๏ผๅ ๅฟซๆๅๆ
ข่ง้ข้ๅบฆใๆฏๆๅ็งๅ้ๅจๅๅธธ่ง่ง้ขๆ ผๅผใ",
+ "inputTitle": "่พๅ
ฅ่ง้ข",
+ "newVideoSpeed": "ๆฐ่ง้ข้ๅบฆ",
+ "resultTitle": "็ผ่พ่ง้ข",
+ "settingSpeed": "่ฎพๅฎ้ๅบฆ",
+ "shortDescription": "ๆดๆน่ง้ขๆญๆพ้ๅบฆ",
+ "title": "ๆดๆน่ง้ข้ๅบฆ",
+ "toolInfo": {
+ "title": "ไปไนๆฏ {{title}}๏ผ"
+ }
+ },
+ "compress": {
+ "default": "้ป่ฎค",
+ "description": "้่ฟๅฐ่ง้ข็ผฉๆพๅฐไธๅ็ๅ่พจ็๏ผไพๅฆ 240pใ480pใ720p ็ญ๏ผๆฅๅ็ผฉ่ง้ขใๆญคๅทฅๅ
ทๆๅฉไบๅจไฟๆๅฏๆฅๅ่ดจ้็ๅๆถๅๅฐๆไปถๅคงๅฐใๆฏๆ MP4ใWebM ๅ OGG ็ญๅธธ่ง่ง้ขๆ ผๅผใ",
+ "inputTitle": "่พๅ
ฅ่ง้ข",
+ "loadingText": "ๆญฃๅจๅ็ผฉ่ง้ข...",
+ "lossless": "ๆ ๆ",
+ "quality": "่ดจ้๏ผCRF๏ผ",
+ "resolution": "่งฃๅณ",
+ "resultTitle": "ๅ็ผฉ่ง้ข",
+ "shortDescription": "้่ฟ็ผฉๆพๅฐไธๅ็ๅ่พจ็ๆฅๅ็ผฉ่ง้ข",
+ "title": "ๅ็ผฉ่ง้ข",
+ "worst": "ๆๅทฎ"
+ },
+ "cropVideo": {
+ "cropCoordinates": "ไฝ็ฉๅๆ ",
+ "croppingVideo": "่ฃๅช่ง้ข",
+ "description": "่ฃๅช่ง้ขไปฅๅ ้คไธ้่ฆ็ๅบๅใ",
+ "errorBeyondHeight": "่ฃๅชๅบๅ่ถ
ๅบ่ง้ข้ซๅบฆ๏ผ{{height}}ๅ็ด ๏ผ",
+ "errorBeyondWidth": "่ฃๅชๅบๅ่ถ
ๅบ่ง้ขๅฎฝๅบฆ๏ผ{{width}}ๅ็ด ๏ผ",
+ "errorCroppingVideo": "่ฃๅช่ง้ขๆถๅบ้ใ่ฏทๆฃๆฅๅๆฐๅ่ง้ขๆไปถใ",
+ "errorLoadingDimensions": "ๆ ๆณๅ ่ฝฝ่ง้ขๅฐบๅฏธ",
+ "errorNonNegativeCoordinates": "X ๅ Y ๅๆ ๅฟ
้กปไธบ้่ดๆฐ",
+ "errorPositiveDimensions": "ๅฎฝๅบฆๅ้ซๅบฆๅฟ
้กปไธบๆญฃๆฐ",
+ "height": "้ซๅบฆ",
+ "inputTitle": "่พๅ
ฅ่ง้ข",
+ "loadVideoForDimensions": "ๅ ่ฝฝ่ง้ขไปฅๆฅ็ๅฐบๅฏธ",
+ "resultTitle": "่ฃๅช่ง้ข",
+ "shortDescription": "่ฃๅช่ง้ขไปฅๅ ้คไธ้่ฆ็ๅบๅ",
+ "title": "่ฃๅช่ง้ข",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจ่ฃๅช่ง้ขๆไปถไปฅๅ ้คไธ้่ฆ็ๅบๅใๆจๅฏไปฅ้่ฟ่ฎพ็ฝฎ XใY ๅๆ ไปฅๅๅฎฝๅบฆๅ้ซๅบฆๅฐบๅฏธๆฅๆๅฎ่ฃๅชๅบๅใ",
+ "title": "่ฃๅช่ง้ข"
+ },
+ "videoDimensions": "่ง้ขๅฐบๅฏธ๏ผ {{width}} ร {{height}} ๅ็ด ",
+ "videoInformation": "่ง้ขไฟกๆฏ",
+ "width": "ๅฎฝๅบฆ",
+ "xCoordinate": "X๏ผๅทฆ๏ผ",
+ "yCoordinate": "Y๏ผ้กถ้จ๏ผ"
+ },
+ "flip": {
+ "description": "ๆฐดๅนณๆๅ็ด็ฟป่ฝฌ่ง้ขๆไปถใ้ๅ่ง้ขไปฅ่ทๅพ็นๆฎๆๆๆ็บ ๆญฃๆนๅ้ฎ้ขใ",
+ "flippingVideo": "็ฟป่ฝฌ่ง้ข",
+ "horizontalLabel": "ๆฐดๅนณ๏ผ้ๅ๏ผ",
+ "inputTitle": "่พๅ
ฅ่ง้ข",
+ "orientation": "ๆนๅ",
+ "resultTitle": "็ฟป่ฝฌ่ง้ข",
+ "shortDescription": "ๆฐดๅนณๆๅ็ด็ฟป่ฝฌ่ง้ข",
+ "title": "็ฟป่ฝฌ่ง้ข",
+ "verticalLabel": "ๅ็ด๏ผๅ็ฝฎ๏ผ"
+ },
+ "gif": {
+ "changeSpeed": {
+ "description": "ๆดๆน GIF ๅจ็ป็ๆญๆพ้ๅบฆใๅจไฟๆๅจ็ปๆต็
็ๆ
ๅตไธ๏ผๅ ๅฟซๆๅๆ
ข GIF ็้ๅบฆใ",
+ "shortDescription": "ๆดๆน GIF ๅจ็ป้ๅบฆ",
+ "title": "ๆดๆน GIF ้ๅบฆ"
+ }
+ },
+ "loop": {
+ "description": "้่ฟๅคๆฌก้ๅคๆญๆพๅๅง่ง้ขๆฅๅๅปบๅพช็ฏ่ง้ขใ",
+ "inputTitle": "่พๅ
ฅ่ง้ข",
+ "loopingVideo": "ๅพช็ฏ่ง้ข",
+ "loops": "ๅพช็ฏ",
+ "numberOfLoops": "ๅพช็ฏๆฌกๆฐ",
+ "resultTitle": "ๅพช็ฏ่ง้ข",
+ "shortDescription": "ๅๅปบๅพช็ฏ่ง้ขๆไปถ",
+ "title": "ๅพช็ฏ่ง้ข",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅฏ่ฎฉๆจ้่ฟๅคๆฌก้ๅคๆญๆพๅๅง่ง้ขๆฅๅๅปบๅพช็ฏ่ง้ขใๆจๅฏไปฅๆๅฎ่ง้ขๅพช็ฏๆญๆพ็ๆฌกๆฐใ",
+ "title": "ไปไนๆฏ {{title}}๏ผ"
+ }
+ },
+ "rotate": {
+ "180Degrees": "180ยฐ๏ผไธไธ้ข ๅ๏ผ",
+ "270Degrees": "270ยฐ๏ผ้ๆถ้90ยฐ๏ผ",
+ "90Degrees": "้กบๆถ้ 90ยฐ",
+ "description": "ๅฐ่ง้ขๆไปถๆ่ฝฌ 90 ๅบฆใ180 ๅบฆๆ 270 ๅบฆใ้่ฟ็ฒพ็กฎ็ๆ่ฝฌๆงๅถๆฅๆ กๆญฃ่ง้ขๆนๅๆๅๅปบ็นๆฎๆๆใ",
+ "inputTitle": "่พๅ
ฅ่ง้ข",
+ "resultTitle": "ๆ่ฝฌ่ง้ข",
+ "rotatingVideo": "ๆ่ฝฌ่ง้ข",
+ "rotation": "ๆ่ฝฌ",
+ "shortDescription": "ๆๆๅฎ่งๅบฆๆ่ฝฌ่ง้ข",
+ "title": "ๆ่ฝฌ่ง้ข"
+ },
+ "trim": {
+ "description": "้่ฟๆๅฎๅผๅงๅ็ปๆๆถ้ดๆฅไฟฎๅช่ง้ขๆไปถใไป่ง้ข็ๅผๅคดๆ็ปๅฐพๅ ้คไธ้่ฆ็้จๅใ",
+ "endTime": "็ปๆๆถ้ด",
+ "inputTitle": "่พๅ
ฅ่ง้ข",
+ "resultTitle": "ไฟฎๅช็่ง้ข",
+ "shortDescription": "้่ฟๅ ้คไธ้่ฆ็้จๅๆฅไฟฎๅช่ง้ข",
+ "startTime": "ๅผๅงๆถ้ด",
+ "timestamps": "ๆถ้ดๆณ",
+ "title": "ไฟฎๅช่ง้ข"
+ },
+ "videoToGif": {
+ "description": "ๅฐ่ง้ขๆไปถ่ฝฌๆขไธบ GIF ๅจ็ปๆ ผๅผใๆๅ็นๅฎๆถ้ด่ๅดๅนถๅๅปบๅฏๅ
ฑไบซ็ๅจ็ปๅพๅใ",
+ "shortDescription": "ๅฐ่ง้ข่ฝฌๆขไธบๅจ็ป GIF",
+ "title": "่ง้ข่ฝฌGIF"
+ }
+}
diff --git a/public/locales/zh/xml.json b/public/locales/zh/xml.json
new file mode 100644
index 0000000..e9cdbc8
--- /dev/null
+++ b/public/locales/zh/xml.json
@@ -0,0 +1,38 @@
+{
+ "xmlBeautifier": {
+ "description": "ไฝฟ็จ้ๅฝ็็ผฉ่ฟๅ้ด่ทๆฅๆ ผๅผๅ XMLใ",
+ "indentation": "็ผฉ่ฟ",
+ "inputTitle": "่พๅ
ฅ XML",
+ "resultTitle": "็พๅ XML",
+ "shortDescription": "ๆ ผๅผๅๅ็พๅ XML ไปฃ็ ",
+ "title": "XML็พๅๅจ",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅ
่ฎธๆจไฝฟ็จ้ๅฝ็็ผฉ่ฟๅ้ด่ทๆฅๆ ผๅผๅ XML ๆฐๆฎ๏ผไฝฟๅ
ถๆดๆ่ฏปไธๆดๆไบไฝฟ็จใ",
+ "title": "XML็พๅๅจ"
+ },
+ "useSpaces": "ไฝฟ็จ็ฉบๆ ผ",
+ "useSpacesDescription": "ไฝฟ็จ็ฉบๆ ผ็ผฉ่ฟ่พๅบ",
+ "useTabs": "ไฝฟ็จๆ ็ญพ",
+ "useTabsDescription": "ไฝฟ็จๅถ่กจ็ฌฆ็ผฉ่ฟ่พๅบใ"
+ },
+ "xmlValidator": {
+ "description": "้ช่ฏ XML ่ฏญๆณๅ็ปๆใ",
+ "placeholder": "ๅจๆญคๅค็ฒ่ดดๆๅฏผๅ
ฅ XML...",
+ "shortDescription": "้ช่ฏ XML ไปฃ็ ๆฏๅฆๅญๅจ้่ฏฏ",
+ "title": "XML้ช่ฏๅจ",
+ "toolInfo": {
+ "description": "ๆญคๅทฅๅ
ทๅฏ็จไบ้ช่ฏ XML ็่ฏญๆณๅ็ปๆใๅฎไผๆฃๆฅ XML ๆ ผๅผๆฏๅฆๆญฃ็กฎ๏ผๅนถ้ๅฏนๅ็ฐ็ไปปไฝ้ฎ้ขๆไพ่ฏฆ็ป็้่ฏฏๆถๆฏใ",
+ "title": "XML้ช่ฏๅจ"
+ }
+ },
+ "xmlViewer": {
+ "description": "ไปฅๆ ็ถๆ ผๅผๆฅ็ๅๆข็ดข XML ็ปๆใ",
+ "inputTitle": "่พๅ
ฅ XML",
+ "resultTitle": "XML ๆ ่งๅพ",
+ "title": "XML ๆฅ็ๅจ",
+ "toolInfo": {
+ "description": "่ฏฅๅทฅๅ
ทๅ
่ฎธๆจไปฅๅๅฑๆ ๆ ผๅผๆฅ็ XML ๆฐๆฎ๏ผไป่ๆดๅฎนๆๆข็ดขๅ็่งฃ XML ๆๆกฃ็็ปๆใ",
+ "title": "XML ๆฅ็ๅจ"
+ }
+ }
+}
diff --git a/scripts/add-i18n-to-meta.js b/scripts/add-i18n-to-meta.js
new file mode 100644
index 0000000..b5fac00
--- /dev/null
+++ b/scripts/add-i18n-to-meta.js
@@ -0,0 +1,260 @@
+const fs = require('fs');
+const path = require('path');
+
+const TYPE_MAPPING = { 'image-generic': 'image', png: 'image' };
+// Helper function to convert kebab-case to camelCase
+function toCamelCase(str) {
+ return str.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase());
+}
+
+// Helper function to parse meta.ts file and extract required fields
+function parseMeta(filePath) {
+ const content = fs.readFileSync(filePath, 'utf8');
+
+ // Extract category from defineTool first parameter
+ const categoryMatch = content.match(/defineTool\s*\(\s*['"]([^'"]+)['"]/);
+ if (!categoryMatch) {
+ throw new Error(`Could not find category in ${filePath}`);
+ }
+ const category = categoryMatch[1];
+
+ // Extract name, description, shortDescription, and longDescription
+ const nameMatch = content.match(/name\s*:\s*['"`]([^'"`]+)['"`]/);
+ const descMatch = content.match(/description\s*:\s*['"`]([\s\S]*?)['"`]/);
+ const shortMatch = content.match(
+ /shortDescription\s*:\s*['"`]([^'"`]+)['"`]/
+ );
+ const longMatch = content.match(/longDescription\s*:\s*['"`]([\s\S]*?)['"`]/);
+
+ if (!nameMatch || !descMatch || !shortMatch) {
+ console.warn(`โ ๏ธ Missing required fields in ${filePath}`);
+ console.warn(
+ ` name: ${!!nameMatch}, description: ${!!descMatch}, shortDescription: ${!!shortMatch}`
+ );
+ return null;
+ }
+
+ return {
+ category,
+ name: nameMatch[1],
+ description: descMatch[1].replace(/\s+/g, ' ').trim(),
+ shortDescription: shortMatch[1],
+ longDescription: longMatch ? longMatch[1].replace(/\s+/g, ' ').trim() : null
+ };
+}
+
+// Helper function to check if meta.ts already has i18n field
+function hasI18nField(filePath) {
+ const content = fs.readFileSync(filePath, 'utf8');
+ return content.includes('i18n:');
+}
+
+// Helper function to add i18n field to meta.ts
+function addI18nToMeta(filePath, category, toolName, hasLongDescription) {
+ const content = fs.readFileSync(filePath, 'utf8');
+
+ // Build i18n object
+ let i18nObject = ` i18n: {
+ name: '${category}:${toolName}.title',
+ description: '${category}:${toolName}.description',
+ shortDescription: '${category}:${toolName}.shortDescription'`;
+
+ if (hasLongDescription) {
+ i18nObject += `,
+ longDescription: '${category}:${toolName}.longDescription'`;
+ }
+
+ i18nObject += `
+ },`;
+
+ // Find the position to insert i18n (after the export line but before the closing bracket)
+ const exportMatch = content.match(/export const tool = defineTool\([^{]*\{/);
+ if (!exportMatch) {
+ throw new Error(`Could not find export structure in ${filePath}`);
+ }
+
+ const insertPosition = exportMatch.index + exportMatch[0].length;
+ const beforeInsert = content.substring(0, insertPosition);
+ const afterInsert = content.substring(insertPosition);
+
+ // Insert i18n field at the beginning of the object
+ const updatedContent = beforeInsert + '\n' + i18nObject + afterInsert;
+
+ fs.writeFileSync(filePath, updatedContent, 'utf8');
+}
+
+// Helper function to get category i18n file path
+function getCategoryI18nPath(category) {
+ const PROJECT_ROOT = path.resolve(__dirname, '..');
+ // Special case: image-generic tools use the image folder for i18n
+ const folderName = TYPE_MAPPING[category] || category;
+ return path.join(
+ PROJECT_ROOT,
+ 'src',
+ 'pages',
+ 'tools',
+ folderName,
+ 'i18n',
+ 'en.json'
+ );
+}
+
+// Helper function to load category i18n data
+function loadCategoryI18n(category) {
+ const i18nPath = getCategoryI18nPath(category);
+
+ try {
+ if (fs.existsSync(i18nPath)) {
+ const i18nRaw = fs.readFileSync(i18nPath, 'utf8');
+ return JSON.parse(i18nRaw);
+ } else {
+ const i18nDir = path.dirname(i18nPath);
+ if (!fs.existsSync(i18nDir)) {
+ fs.mkdirSync(i18nDir, { recursive: true });
+ }
+ return {};
+ }
+ } catch (err) {
+ console.error(`โ Failed to parse ${i18nPath}:`, err.message);
+ return {};
+ }
+}
+
+// Helper function to save category i18n data
+function saveCategoryI18n(category, data) {
+ const i18nPath = getCategoryI18nPath(category);
+ fs.writeFileSync(i18nPath, JSON.stringify(data, null, 2) + '\n', 'utf8');
+ return i18nPath;
+}
+
+// Main execution
+console.log('๐ Adding i18n fields to meta.ts files...\n');
+
+const PROJECT_ROOT = path.resolve(__dirname, '..');
+
+// Target files as specified
+const rootDir = path.join(PROJECT_ROOT, 'src/pages/tools');
+const metaFiles = [];
+
+function findMetaFiles(dir) {
+ const items = fs.readdirSync(dir, { withFileTypes: true });
+
+ for (const item of items) {
+ const fullPath = path.join(dir, item.name);
+
+ if (item.isDirectory()) {
+ findMetaFiles(fullPath); // Recurse
+ } else if (item.isFile() && item.name === 'meta.ts') {
+ metaFiles.push(fullPath);
+ }
+ }
+}
+
+findMetaFiles(rootDir);
+
+let processedCount = 0;
+let skippedCount = 0;
+let errorCount = 0;
+const updatedCategories = new Set();
+const categoryData = {};
+
+// Process each target file
+metaFiles.forEach((filePath) => {
+ try {
+ // Check if file exists
+ if (!fs.existsSync(filePath)) {
+ console.error(`โ File not found: ${filePath}`);
+ errorCount++;
+ return;
+ }
+
+ // Check if i18n field already exists
+ if (hasI18nField(filePath)) {
+ console.log(`โญ๏ธ Skipped ${filePath} (already has i18n field)`);
+ skippedCount++;
+ return;
+ }
+
+ // Parse meta.ts file
+ const parsed = parseMeta(filePath);
+ if (!parsed) {
+ errorCount++;
+ return;
+ }
+
+ const {
+ category: rawCategory,
+ name,
+ description,
+ shortDescription,
+ longDescription
+ } = parsed;
+
+ const category = TYPE_MAPPING[rawCategory] || rawCategory;
+ // Get tool name from folder path
+ const toolFolderName = path.basename(path.dirname(filePath));
+ const toolKey = toCamelCase(toolFolderName); // camelCase for i18n file keys
+
+ // Load category i18n data if not already loaded
+ if (!categoryData[category]) {
+ categoryData[category] = loadCategoryI18n(category);
+ }
+
+ // Ensure tool entry exists in i18n
+ if (!categoryData[category][toolKey]) {
+ categoryData[category][toolKey] = {};
+ }
+
+ const entry = categoryData[category][toolKey];
+ let hasI18nChanges = false;
+
+ // Add missing fields to i18n
+ if (!entry.title) {
+ entry.title = name;
+ hasI18nChanges = true;
+ }
+ if (!entry.description) {
+ entry.description = description;
+ hasI18nChanges = true;
+ }
+ if (!entry.shortDescription) {
+ entry.shortDescription = shortDescription;
+ hasI18nChanges = true;
+ }
+ if (longDescription && !entry.longDescription) {
+ entry.longDescription = longDescription;
+ hasI18nChanges = true;
+ }
+
+ // Add i18n field to meta.ts
+ addI18nToMeta(filePath, category, toolKey, !!longDescription);
+
+ if (hasI18nChanges) {
+ updatedCategories.add(category);
+ }
+
+ console.log(`โ
Added i18n to ${filePath}`);
+ processedCount++;
+ } catch (err) {
+ console.error(`โ Error processing ${filePath}:`, err.message);
+ errorCount++;
+ }
+});
+
+// Save updated category i18n files
+if (updatedCategories.size > 0) {
+ console.log('\n๐พ Saving updated i18n files...');
+ for (const category of updatedCategories) {
+ const savedPath = saveCategoryI18n(category, categoryData[category]);
+ console.log(` ๐ ${path.relative(PROJECT_ROOT, savedPath)}`);
+ }
+}
+
+// Summary
+console.log('\n๐ Summary:');
+console.log(` โ
Processed: ${processedCount} files`);
+console.log(` โญ๏ธ Skipped: ${skippedCount} files (already had i18n)`);
+console.log(` โ Errors: ${errorCount} files`);
+console.log(
+ `\n๐ Successfully updated ${processedCount} meta.ts files and ${updatedCategories.size} i18n files!`
+);
diff --git a/scripts/cleanup-empty-directories.js b/scripts/cleanup-empty-directories.js
new file mode 100644
index 0000000..e907d5a
--- /dev/null
+++ b/scripts/cleanup-empty-directories.js
@@ -0,0 +1,94 @@
+const fs = require('fs');
+const path = require('path');
+
+/**
+ * Recursively delete all empty folders in a directory
+ * @param {string} dirPath - The directory path to process
+ * @param {boolean} deleteRoot - Whether to delete the root directory if it becomes empty
+ * @returns {boolean} - Returns true if the directory is empty after processing
+ */
+function deleteEmptyFolders(dirPath, deleteRoot = false) {
+ if (!fs.existsSync(dirPath)) {
+ console.log(`Directory does not exist: ${dirPath}`);
+ return false;
+ }
+
+ if (!fs.statSync(dirPath).isDirectory()) {
+ console.log(`Path is not a directory: ${dirPath}`);
+ return false;
+ }
+
+ let files;
+ try {
+ files = fs.readdirSync(dirPath);
+ } catch (err) {
+ console.error(`Error reading directory ${dirPath}:`, err.message);
+ return false;
+ }
+
+ // Process each item in the directory
+ for (const file of files) {
+ const fullPath = path.join(dirPath, file);
+
+ try {
+ const stat = fs.statSync(fullPath);
+
+ if (stat.isDirectory()) {
+ // Recursively process subdirectories
+ const isEmpty = deleteEmptyFolders(fullPath, true);
+
+ // If subdirectory is empty, remove it from the files array
+ if (isEmpty) {
+ const index = files.indexOf(file);
+ if (index > -1) {
+ files.splice(index, 1);
+ }
+ }
+ }
+ } catch (err) {
+ console.error(`Error processing ${fullPath}:`, err.message);
+ }
+ }
+
+ // Check if directory is empty after processing
+ const isEmpty = files.length === 0;
+
+ if (isEmpty && deleteRoot) {
+ try {
+ fs.rmdirSync(dirPath);
+ console.log(`Deleted empty directory: ${dirPath}`);
+ return true;
+ } catch (err) {
+ console.error(`Error deleting directory ${dirPath}:`, err.message);
+ return false;
+ }
+ }
+
+ return isEmpty;
+}
+
+/**
+ * Main function to start the cleanup process
+ * @param {string} targetPath - The root directory to clean up
+ */
+function cleanupEmptyFolders(targetPath) {
+ console.log(`Starting cleanup of empty folders in: ${targetPath}`);
+
+ const absolutePath = path.resolve(targetPath);
+ const result = deleteEmptyFolders(absolutePath, false);
+
+ if (result) {
+ console.log(
+ 'Cleanup completed. Root directory is empty but was not deleted.'
+ );
+ } else {
+ console.log('Cleanup completed.');
+ }
+}
+
+// Usage example
+const targetDirectory = process.argv[2] || './target-folder';
+cleanupEmptyFolders(targetDirectory);
+
+// Export for use as a module
+module.exports = { deleteEmptyFolders, cleanupEmptyFolders };
diff --git a/scripts/create-tool.mjs b/scripts/create-tool.mjs
index 3032f95..1d68f1c 100644
--- a/scripts/create-tool.mjs
+++ b/scripts/create-tool.mjs
@@ -138,6 +138,40 @@ export default function ${capitalizeFirstLetter(toolNameCamelCase)}({
}
`
);
+const validNamespaces = [
+ 'string',
+ 'number',
+ 'video',
+ 'list',
+ 'json',
+ 'time',
+ 'csv',
+ 'pdf',
+ 'audio',
+ 'xml',
+ 'translation',
+ 'image'
+];
+const isValidI18nNamespace = (value) => {
+ return validNamespaces.includes(value);
+};
+
+const getI18nNamespaceFromToolCategory = (category) => {
+ // Map image-related categories to 'image'
+ if (['png', 'image-generic'].includes(category)) {
+ return 'image';
+ } else if (['gif'].includes(category)) {
+ return 'video';
+ }
+ // Use type guard to check if category is a valid I18nNamespaces
+ if (isValidI18nNamespace(category)) {
+ return category;
+ }
+
+ return 'translation';
+};
+
+const i18nNamespace = getI18nNamespaceFromToolCategory(type);
createToolFile(
`meta.ts`,
`
@@ -145,13 +179,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('${type}', {
- name: '${toolNameTitleCase}',
+ i18n: {
+ name: '${i18nNamespace}:${toolNameCamelCase}.title',
+ description: '${i18nNamespace}:${toolNameCamelCase}.description',
+ shortDescription: '${i18nNamespace}:${toolNameCamelCase}.shortDescription',
+ longDescription: '${i18nNamespace}:${toolNameCamelCase}.longDescription'
+ },
path: '${toolName}',
icon: '',
- description: '',
- shortDescription: '',
keywords: ['${toolName.split('-').join("', '")}'],
- longDescription: '',
component: lazy(() => import('./index'))
});
`
@@ -222,4 +258,30 @@ indexContent.splice(
)} } from './${toolName}/meta';`
);
writeFile(toolsIndex, indexContent.join('\n'));
+
+// Update locale JSON file
+const localeFilePath = join(
+ currentDirname,
+ '..',
+ 'public',
+ 'locales',
+ 'en',
+ `${i18nNamespace}.json`
+);
+
+let localeData = {};
+if (fs.existsSync(localeFilePath)) {
+ const localeContent = await readFile(localeFilePath, { encoding: 'utf-8' });
+ localeData = JSON.parse(localeContent);
+}
+
+localeData[toolNameCamelCase] = {
+ title: toolNameTitleCase,
+ description: '',
+ shortDescription: '',
+ longDescription: ''
+};
+
+// Write updated locale file
+await writeFile(localeFilePath, JSON.stringify(localeData, null, 2));
console.log(`Added import in: ${toolsIndex}`);
diff --git a/scripts/locize-upload.js b/scripts/locize-upload.js
new file mode 100644
index 0000000..6099a3d
--- /dev/null
+++ b/scripts/locize-upload.js
@@ -0,0 +1,213 @@
+// one-time-upload.js
+// Simple script to upload your existing translations to Locize once
+
+const fs = require('fs');
+const https = require('https');
+
+// Configuration
+const LOCIZE_PROJECT_ID = 'e7156a3e-66fb-4035-a0f0-cebf1c63a3ba';
+const LOCIZE_API_KEY = process.env.LOCIZE_API_KEY; // Replace with your actual API key
+const LOCIZE_VERSION = 'latest';
+
+// Define your translation files
+const translationFiles = [
+ // English translations
+ { lang: 'en', namespace: 'translation', file: '../src/i18n/en.json' },
+ {
+ lang: 'en',
+ namespace: 'list',
+ file: '../src/pages/tools/list/i18n/en.json'
+ },
+ {
+ lang: 'en',
+ namespace: 'string',
+ file: '../src/pages/tools/string/i18n/en.json'
+ },
+ { lang: 'en', namespace: 'csv', file: '../src/pages/tools/csv/i18n/en.json' },
+ {
+ lang: 'en',
+ namespace: 'json',
+ file: '../src/pages/tools/json/i18n/en.json'
+ },
+ { lang: 'en', namespace: 'pdf', file: '../src/pages/tools/pdf/i18n/en.json' },
+ {
+ lang: 'en',
+ namespace: 'image',
+ file: '../src/pages/tools/image/i18n/en.json'
+ },
+ {
+ lang: 'en',
+ namespace: 'audio',
+ file: '../src/pages/tools/audio/i18n/en.json'
+ },
+ {
+ lang: 'en',
+ namespace: 'video',
+ file: '../src/pages/tools/video/i18n/en.json'
+ },
+ {
+ lang: 'en',
+ namespace: 'number',
+ file: '../src/pages/tools/number/i18n/en.json'
+ },
+ {
+ lang: 'en',
+ namespace: 'time',
+ file: '../src/pages/tools/time/i18n/en.json'
+ },
+ { lang: 'en', namespace: 'xml', file: '../src/pages/tools/xml/i18n/en.json' },
+
+ // Hindi translations
+ { lang: 'hi', namespace: 'translation', file: '../src/i18n/hi.json' },
+ {
+ lang: 'hi',
+ namespace: 'list',
+ file: '../src/pages/tools/list/i18n/hi.json'
+ },
+ {
+ lang: 'hi',
+ namespace: 'string',
+ file: '../src/pages/tools/string/i18n/hi.json'
+ },
+ { lang: 'hi', namespace: 'csv', file: '../src/pages/tools/csv/i18n/hi.json' },
+ {
+ lang: 'hi',
+ namespace: 'json',
+ file: '../src/pages/tools/json/i18n/hi.json'
+ },
+ { lang: 'hi', namespace: 'pdf', file: '../src/pages/tools/pdf/i18n/hi.json' },
+ {
+ lang: 'hi',
+ namespace: 'image',
+ file: '../src/pages/tools/image/i18n/hi.json'
+ },
+ {
+ lang: 'hi',
+ namespace: 'audio',
+ file: '../src/pages/tools/audio/i18n/hi.json'
+ },
+ {
+ lang: 'hi',
+ namespace: 'video',
+ file: '../src/pages/tools/video/i18n/hi.json'
+ },
+ {
+ lang: 'hi',
+ namespace: 'number',
+ file: '../src/pages/tools/number/i18n/hi.json'
+ },
+ {
+ lang: 'hi',
+ namespace: 'time',
+ file: '../src/pages/tools/time/i18n/hi.json'
+ },
+ { lang: 'hi', namespace: 'xml', file: '../src/pages/tools/xml/i18n/hi.json' }
+];
+
+function flattenJson(obj, prefix = '') {
+ const flattened = {};
+
+ for (const key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ const newKey = prefix ? `${prefix}.${key}` : key;
+
+ if (
+ typeof obj[key] === 'object' &&
+ obj[key] !== null &&
+ !Array.isArray(obj[key])
+ ) {
+ // Recursively flatten nested objects
+ Object.assign(flattened, flattenJson(obj[key], newKey));
+ } else {
+ // It's a primitive value or array
+ flattened[newKey] = obj[key];
+ }
+ }
+ }
+
+ return flattened;
+}
+
+function uploadToLocize(lang, namespace, data) {
+ return new Promise((resolve, reject) => {
+ // Flatten the JSON structure for Locize API
+ const flattenedData = flattenJson(data);
+ const postData = JSON.stringify(flattenedData);
+
+ const options = {
+ hostname: 'api.locize.app',
+ port: 443,
+ path: `/update/${LOCIZE_PROJECT_ID}/${LOCIZE_VERSION}/${lang}/${namespace}`,
+ method: 'POST',
+ headers: {
+ Authorization: `Bearer ${LOCIZE_API_KEY}`,
+ 'Content-Type': 'application/json',
+ 'Content-Length': Buffer.byteLength(postData)
+ }
+ };
+
+ const req = https.request(options, (res) => {
+ let data = '';
+ res.on('data', (chunk) => (data += chunk));
+ res.on('end', () => {
+ if (res.statusCode === 200) {
+ resolve(JSON.parse(data));
+ } else {
+ reject(new Error(`HTTP ${res.statusCode}: ${data}`));
+ }
+ });
+ });
+
+ req.on('error', reject);
+ req.write(postData);
+ req.end();
+ });
+}
+
+async function main() {
+ console.log('Starting one-time upload to Locize...\n');
+
+ let successCount = 0;
+ let errorCount = 0;
+
+ for (const { lang, namespace, file } of translationFiles) {
+ try {
+ // Check if file exists
+ if (!fs.existsSync(file)) {
+ console.log(`โ ๏ธ File not found: ${file}`);
+ continue;
+ }
+
+ // Read translation file
+ const translations = JSON.parse(fs.readFileSync(file, 'utf8'));
+ const flattenedTranslations = flattenJson(translations);
+ const keyCount = Object.keys(flattenedTranslations).length;
+
+ if (keyCount === 0) {
+ console.log(`โ ๏ธ Empty file: ${lang}/${namespace}`);
+ continue;
+ }
+
+ // Upload to Locize
+ await uploadToLocize(lang, namespace, translations);
+ console.log(`โ
${lang}/${namespace} - ${keyCount} keys uploaded`);
+ successCount++;
+ } catch (error) {
+ console.error(`โ ${lang}/${namespace} - Error: ${error.message}`);
+ errorCount++;
+ }
+ }
+
+ console.log('\n=== Upload Summary ===');
+ console.log(`โ
Successful uploads: ${successCount}`);
+ console.log(`โ Failed uploads: ${errorCount}`);
+ console.log(`๐ Total files processed: ${successCount + errorCount}`);
+
+ if (errorCount === 0) {
+ console.log('\n๐ All translations uploaded successfully!');
+ console.log('You can now view them in your Locize dashboard.');
+ }
+}
+
+// Run the upload
+main().catch(console.error);
diff --git a/scripts/update-i18n-from-meta.js b/scripts/update-i18n-from-meta.js
new file mode 100644
index 0000000..bba4d8f
--- /dev/null
+++ b/scripts/update-i18n-from-meta.js
@@ -0,0 +1,203 @@
+const fs = require('fs');
+const path = require('path');
+
+// Helper function to convert kebab-case to camelCase
+function toCamelCase(str) {
+ return str.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase());
+}
+
+// Helper function to recursively find all meta.ts files
+function findMetaFiles(dir) {
+ const files = [];
+
+ function traverse(currentDir) {
+ const items = fs.readdirSync(currentDir, { withFileTypes: true });
+
+ for (const item of items) {
+ const fullPath = path.join(currentDir, item.name);
+
+ if (item.isDirectory()) {
+ traverse(fullPath);
+ } else if (item.name === 'meta.ts') {
+ files.push(fullPath);
+ }
+ }
+ }
+
+ traverse(dir);
+ return files;
+}
+
+// Helper function to parse meta.ts file and extract the required fields
+function parseMeta(filePath) {
+ const content = fs.readFileSync(filePath, 'utf8');
+
+ // Extract category from defineTool first parameter
+ const categoryMatch = content.match(/defineTool\s*\(\s*['"]([^'"]+)['"]/);
+ if (!categoryMatch) {
+ throw new Error(`Could not find category in ${filePath}`);
+ }
+ const category = categoryMatch[1];
+
+ // Extract name, description, and shortDescription
+ const nameMatch = content.match(/name\s*:\s*['"`]([^'"`]+)['"`]/);
+ const descMatch = content.match(
+ /description\s*:\s*['"`]([\s\S]*?)['"`]\s*,\s*shortDescription/
+ );
+ const shortMatch = content.match(
+ /shortDescription\s*:\s*['"`]([^'"`]+)['"`]/
+ );
+
+ if (!nameMatch || !descMatch || !shortMatch) {
+ console.warn(`โ ๏ธ Missing fields in ${filePath}`);
+ console.warn(
+ ` name: ${!!nameMatch}, description: ${!!descMatch}, shortDescription: ${!!shortMatch}`
+ );
+ return null;
+ }
+
+ return {
+ category,
+ name: nameMatch[1],
+ description: descMatch[1].replace(/\s+/g, ' ').trim(),
+ shortDescription: shortMatch[1]
+ };
+}
+
+// Main execution
+console.log('๐ Starting i18n extraction from meta.ts files...\n');
+
+const PROJECT_ROOT = path.resolve(__dirname, '..');
+
+// Helper function to get or create category i18n file
+function getCategoryI18nPath(category) {
+ return path.join(
+ PROJECT_ROOT,
+ 'src',
+ 'pages',
+ 'tools',
+ category,
+ 'i18n',
+ 'en.json'
+ );
+}
+
+function loadCategoryI18n(category) {
+ const i18nPath = getCategoryI18nPath(category);
+
+ try {
+ if (fs.existsSync(i18nPath)) {
+ const i18nRaw = fs.readFileSync(i18nPath, 'utf8');
+ return JSON.parse(i18nRaw);
+ } else {
+ // Create directory if it doesn't exist
+ const i18nDir = path.dirname(i18nPath);
+ if (!fs.existsSync(i18nDir)) {
+ fs.mkdirSync(i18nDir, { recursive: true });
+ }
+ return {};
+ }
+ } catch (err) {
+ console.error(`โ Failed to parse ${i18nPath}:`, err.message);
+ return {};
+ }
+}
+
+function saveCategoryI18n(category, data) {
+ const i18nPath = getCategoryI18nPath(category);
+
+ // Create backup
+ // if (fs.existsSync(i18nPath)) {
+ // fs.copyFileSync(i18nPath, i18nPath + '.bak');
+ // }
+
+ // Write updated file
+ fs.writeFileSync(i18nPath, JSON.stringify(data, null, 2) + '\n', 'utf8');
+ return i18nPath;
+}
+
+// 2) Find all meta.ts files under src/pages/tools
+const toolsDir = path.join(PROJECT_ROOT, 'src', 'pages', 'tools');
+const files = findMetaFiles(toolsDir);
+console.log(`๐ Found ${files.length} meta.ts files\n`);
+
+let addedCount = 0;
+let skippedCount = 0;
+let errorCount = 0;
+const updatedCategories = new Set();
+
+// 3) Process each meta.ts file
+const categoryData = {};
+
+files.forEach((file) => {
+ try {
+ const relativePath = path.relative(PROJECT_ROOT, file);
+ const parsed = parseMeta(file);
+
+ if (!parsed) {
+ errorCount++;
+ return;
+ }
+
+ const { category, name, description, shortDescription } = parsed;
+
+ // Load category i18n data if not already loaded
+ if (!categoryData[category]) {
+ categoryData[category] = loadCategoryI18n(category);
+ }
+
+ // Get tool key from folder name (convert kebab-case to camelCase)
+ const toolSlug = path.basename(path.dirname(file));
+ const toolKey = toCamelCase(toolSlug);
+
+ // Ensure tool entry exists
+ if (!categoryData[category][toolKey]) {
+ categoryData[category][toolKey] = {};
+ }
+
+ const entry = categoryData[category][toolKey];
+ let hasChanges = false;
+
+ // Add missing fields
+ if (!entry.name) {
+ entry.name = name;
+ hasChanges = true;
+ }
+ if (!entry.description) {
+ entry.description = description;
+ hasChanges = true;
+ }
+ if (!entry.shortDescription) {
+ entry.shortDescription = shortDescription;
+ hasChanges = true;
+ }
+
+ if (hasChanges) {
+ console.log(`โ
Updated ${category}/${toolKey}`);
+ addedCount++;
+ updatedCategories.add(category);
+ } else {
+ console.log(`โญ๏ธ Skipped ${category}/${toolKey} (already exists)`);
+ skippedCount++;
+ }
+ } catch (err) {
+ console.error(`โ Error processing ${file}:`, err.message);
+ errorCount++;
+ }
+});
+
+// 4) Save updated category i18n files
+console.log('\n๐พ Saving updated i18n files...');
+for (const category of updatedCategories) {
+ const savedPath = saveCategoryI18n(category, categoryData[category]);
+ console.log(` ๐ ${path.relative(PROJECT_ROOT, savedPath)}`);
+}
+
+// 6) Summary
+console.log('\n๐ Summary:');
+console.log(` โ
Updated: ${addedCount} tools`);
+console.log(` โญ๏ธ Skipped: ${skippedCount} tools (already had entries)`);
+console.log(` โ Errors: ${errorCount} tools`);
+console.log(
+ `\n๐ Successfully updated ${updatedCategories.size} category i18n files!`
+);
diff --git a/src/@types/i18n.d.ts b/src/@types/i18n.d.ts
new file mode 100644
index 0000000..a0554fa
--- /dev/null
+++ b/src/@types/i18n.d.ts
@@ -0,0 +1,33 @@
+import 'i18next';
+
+import translation from '../../public/locales/en/translation.json';
+import string from '../../public/locales/en/string.json';
+import number from '../../public/locales/en/number.json';
+import video from '../../public/locales/en/video.json';
+import list from '../../public/locales/en/list.json';
+import json from '../../public/locales/en/json.json';
+import time from '../../public/locales/en/time.json';
+import csv from '../../public/locales/en/csv.json';
+import pdf from '../../public/locales/en/pdf.json';
+import audio from '../../public/locales/en/audio.json';
+import xml from '../../public/locales/en/xml.json';
+import image from '../../public/locales/en/image.json';
+
+declare module 'i18next' {
+ interface CustomTypeOptions {
+ resources: {
+ translation: typeof translation;
+ string: typeof string;
+ number: typeof number;
+ video: typeof video;
+ list: typeof list;
+ json: typeof json;
+ time: typeof time;
+ csv: typeof csv;
+ pdf: typeof pdf;
+ audio: typeof audio;
+ xml: typeof xml;
+ image: typeof image;
+ };
+ }
+}
diff --git a/src/components/App.tsx b/src/components/App.tsx
index 69d4d36..b71abd8 100644
--- a/src/components/App.tsx
+++ b/src/components/App.tsx
@@ -10,6 +10,8 @@ import { tools } from '../tools';
import './index.css';
import { darkTheme, lightTheme } from '../config/muiConfig';
import ScrollToTopButton from './ScrollToTopButton';
+import { I18nextProvider } from 'react-i18next';
+import i18n from '../i18n';
export type Mode = 'dark' | 'light' | 'system';
@@ -44,32 +46,34 @@ function App() {
}, []);
return (
-
-
-
-
-
- {
- setMode((prev) => nextMode(prev));
- localStorage.setItem('theme', nextMode(mode));
- }}
- />
- }>
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {
+ setMode((prev) => nextMode(prev));
+ localStorage.setItem('theme', nextMode(mode));
+ }}
+ />
+ }>
+
+
+
+
+
+
+
+
);
}
diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx
index cfd6afc..0b4d2d3 100644
--- a/src/components/Hero.tsx
+++ b/src/components/Hero.tsx
@@ -15,10 +15,17 @@ import { useState } from 'react';
import { DefinedTool } from '@tools/defineTool';
import { filterTools, tools } from '@tools/index';
import { useNavigate } from 'react-router-dom';
-import _ from 'lodash';
import { Icon } from '@iconify/react';
import { getToolCategoryTitle } from '@utils/string';
import UserTypeFilter, { useUserTypeFilter } from './UserTypeFilter';
+import { useTranslation } from 'react-i18next';
+import { FullI18nKey, validNamespaces } from '../i18n';
+import {
+ getBookmarkedToolPaths,
+ isBookmarked,
+ toggleBookmarked
+} from '@utils/bookmark';
+import IconButton from '@mui/material/IconButton';
const GroupHeader = styled('div')(({ theme }) => ({
position: 'sticky',
@@ -34,52 +41,105 @@ const GroupHeader = styled('div')(({ theme }) => ({
const GroupItems = styled('ul')({
padding: 0
});
-const exampleTools: { label: string; url: string }[] = [
- {
- label: 'Create a transparent image',
- url: '/image-generic/create-transparent'
- },
- { label: 'Prettify JSON', url: '/json/prettify' },
- { label: 'Change GIF speed', url: '/gif/change-speed' },
- { label: 'Sort a list', url: '/list/sort' },
- { label: 'Compress PNG', url: '/png/compress-png' },
- { label: 'Split a text', url: '/string/split' },
- { label: 'Split PDF', url: '/pdf/split-pdf' },
- { label: 'Trim video', url: '/video/trim' },
- { label: 'Calculate number sum', url: '/number/sum' }
-];
+
+type ToolInfo = {
+ label: FullI18nKey;
+ url: string;
+};
export default function Hero() {
+ const { t } = useTranslation(validNamespaces);
const [inputValue, setInputValue] = useState('');
const theme = useTheme();
const { selectedUserTypes, setSelectedUserTypes } = useUserTypeFilter();
const [filteredTools, setFilteredTools] = useState(tools);
+ const [bookmarkedToolPaths, setBookmarkedToolPaths] = useState(
+ getBookmarkedToolPaths()
+ );
const navigate = useNavigate();
+ const exampleTools: ToolInfo[] = [
+ {
+ label: 'translation:hero.examples.createTransparentImage',
+ url: '/image-generic/create-transparent'
+ },
+ {
+ label: 'translation:hero.examples.prettifyJson',
+ url: '/json/prettify'
+ },
+ {
+ label: 'translation:hero.examples.changeGifSpeed',
+ url: '/gif/change-speed'
+ },
+ {
+ label: 'translation:hero.examples.sortList',
+ url: '/list/sort'
+ },
+ {
+ label: 'translation:hero.examples.compressPng',
+ url: '/png/compress-png'
+ },
+ {
+ label: 'translation:hero.examples.splitText',
+ url: '/string/split'
+ },
+ {
+ label: 'translation:hero.examples.splitPdf',
+ url: '/pdf/split-pdf'
+ },
+ {
+ label: 'translation:hero.examples.trimVideo',
+ url: '/video/trim'
+ },
+ {
+ label: 'translation:hero.examples.calculateNumberSum',
+ url: '/number/sum'
+ }
+ ];
+
const handleInputChange = (
- event: React.ChangeEvent<{}>,
+ _event: React.ChangeEvent<{}>,
newInputValue: string
) => {
setInputValue(newInputValue);
- setFilteredTools(filterTools(tools, newInputValue, selectedUserTypes));
+ setFilteredTools(filterTools(tools, newInputValue, selectedUserTypes, t));
};
const handleUserTypesChange = (userTypes: string[]) => {
setSelectedUserTypes(userTypes as any);
- setFilteredTools(filterTools(tools, inputValue, userTypes as any));
+ setFilteredTools(filterTools(tools, inputValue, userTypes as any, t));
};
+ const toolsMap = new Map();
+ for (const tool of filteredTools) {
+ toolsMap.set(tool.path, {
+ label: tool.name,
+ url: '/' + tool.path
+ });
+ }
+
+ const displayedTools =
+ bookmarkedToolPaths.length > 0
+ ? bookmarkedToolPaths.flatMap((path) => {
+ const tool = toolsMap.get(path);
+ if (tool === undefined) {
+ return [];
+ }
+ return [tool];
+ })
+ : exampleTools;
+
return (
- Get Things Done Quickly with{' '}
+ {t('translation:hero.title')}{' '}
- OmniTools
+ {t('translation:hero.brand')}
@@ -88,75 +148,98 @@ export default function Hero() {
fontSize={{ xs: 15, md: 20 }}
mb={2}
>
- Boost your productivity with OmniTools, the ultimate toolkit for getting
- things done quickly! Access thousands of user-friendly utilities for
- editing images, text, lists, and data, all directly from your browser.
+ {t('translation:hero.description')}
-
- option.type}
- renderGroup={(params) => {
- return (
-
- {getToolCategoryTitle(params.group)}
- {params.children}
-
- );
- }}
- inputValue={inputValue}
- getOptionLabel={(option) => option.name}
- renderInput={(params) => (
- ,
- sx: {
- borderRadius: 4,
- backgroundColor: 'background.paper'
- }
- }}
- onChange={(event) => handleInputChange(event, event.target.value)}
- />
- )}
- renderOption={(props, option) => (
- navigate('/' + option.path)}
+ option.type}
+ renderGroup={(params) => {
+ return (
+
+ {getToolCategoryTitle(params.group, t)}
+ {params.children}
+
+ );
+ }}
+ inputValue={inputValue}
+ getOptionLabel={(option) => t(option.name)}
+ renderInput={(params) => (
+ ,
+ sx: {
+ borderRadius: 4,
+ backgroundColor: 'background.paper'
+ }
+ }}
+ onChange={(event) => handleInputChange(event, event.target.value)}
+ />
+ )}
+ renderOption={(props, option) => (
+ navigate('/' + option.path)}
+ >
+
- {option.name}
+ {t(option.name)}
- {option.shortDescription}
+ {t(option.shortDescription)}
-
- )}
- onChange={(event, newValue) => {
- if (newValue) {
- navigate('/' + newValue.path);
- }
- }}
- />
-
-
-
-
- {exampleTools.map((tool) => (
+ {
+ e.stopPropagation();
+ toggleBookmarked(option.path);
+ setBookmarkedToolPaths(getBookmarkedToolPaths());
+ }}
+ >
+
+
+
+
+
+ )}
+ onChange={(event, newValue) => {
+ if (newValue) {
+ navigate('/' + newValue.path);
+ }
+ }}
+ />
+
+ {displayedTools.map((tool) => (
navigate(tool.url.startsWith('/') ? tool.url : `/${tool.url}`)
@@ -181,10 +264,30 @@ export default function Hero() {
cursor: 'pointer',
'&:hover': {
backgroundColor: 'background.hover'
- }
+ },
+ height: '100%'
}}
>
- {tool.label}
+
+ {t(tool.label)}
+ {bookmarkedToolPaths.length > 0 && (
+ {
+ e.stopPropagation();
+ const path = tool.url.substring(1);
+ toggleBookmarked(path);
+ setBookmarkedToolPaths(getBookmarkedToolPaths());
+ }}
+ size={'small'}
+ >
+
+
+ )}
+
))}
diff --git a/src/components/Navbar/index.tsx b/src/components/Navbar/index.tsx
index 5b1bfcf..6677266 100644
--- a/src/components/Navbar/index.tsx
+++ b/src/components/Navbar/index.tsx
@@ -13,22 +13,39 @@ import {
ListItem,
ListItemButton,
ListItemText,
- Stack
+ Stack,
+ Select,
+ MenuItem,
+ FormControl
} from '@mui/material';
import useMediaQuery from '@mui/material/useMediaQuery';
import { useTheme } from '@mui/material/styles';
import { Icon } from '@iconify/react';
import { Mode } from 'components/App';
+import { useTranslation } from 'react-i18next';
interface NavbarProps {
mode: Mode;
onChangeMode: () => void;
}
+const languages = [
+ { code: 'en', label: 'English' },
+ { code: 'de', label: 'Deutsch' },
+ { code: 'es', label: 'Espaรฑol' },
+ { code: 'fr', label: 'Franรงais' },
+ { code: 'pt', label: 'Portuguรชs' },
+ { code: 'ja', label: 'ๆฅๆฌ่ช' },
+ { code: 'hi', label: 'เคนเคฟเคเคฆเฅ' },
+ { code: 'nl', label: 'Nederlands' },
+ { code: 'ru', label: 'ะ ัััะบะธะน' },
+ { code: 'zh', label: 'ไธญๆ' }
+];
const Navbar: React.FC = ({
mode,
onChangeMode: onChangeMode
}) => {
+ const { t, i18n } = useTranslation();
const navigate = useNavigate();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
@@ -36,12 +53,51 @@ const Navbar: React.FC = ({
const toggleDrawer = (open: boolean) => () => {
setDrawerOpen(open);
};
+
+ const handleLanguageChange = (event: any) => {
+ const newLanguage = event.target.value;
+ i18n.changeLanguage(newLanguage);
+ localStorage.setItem('lang', newLanguage);
+ };
+
const navItems: { label: string; path: string }[] = [
// { label: 'Features', path: '/features' }
// { label: 'About Us', path: '/about-us' }
];
+ const languageSelector = (
+
+
+ {languages.map((lang) => (
+
+ {lang.label}
+
+ ))}
+
+
+ );
+
const buttons: ReactNode[] = [
+ languageSelector,
= ({
/>
}
>
- Buy me a coffee
+ {t('navbar.buyMeACoffee')}
];
const drawerList = (
diff --git a/src/components/ToolHeader.tsx b/src/components/ToolHeader.tsx
index 8d88f13..a39c0db 100644
--- a/src/components/ToolHeader.tsx
+++ b/src/components/ToolHeader.tsx
@@ -1,4 +1,4 @@
-import { Box, Button, styled, useTheme } from '@mui/material';
+import { Box, Button, Stack, styled, useTheme } from '@mui/material';
import Typography from '@mui/material/Typography';
import ToolBreadcrumb from './ToolBreadcrumb';
import { capitalizeFirstLetter } from '../utils/string';
@@ -7,6 +7,11 @@ import { Icon, IconifyIcon } from '@iconify/react';
import { categoriesColors } from '../config/uiConfig';
import { getToolsByCategory } from '@tools/index';
import { useEffect, useState } from 'react';
+import { isBookmarked, toggleBookmarked } from '@utils/bookmark';
+import IconButton from '@mui/material/IconButton';
+import { useTranslation } from 'react-i18next';
+import useMediaQuery from '@mui/material/useMediaQuery';
+import { validNamespaces } from '../i18n';
const StyledButton = styled(Button)(({ theme }) => ({
backgroundColor: 'white',
@@ -21,10 +26,14 @@ interface ToolHeaderProps {
description: string;
icon?: IconifyIcon | string;
type: string;
+ path: string;
}
function ToolLinks() {
+ const { t } = useTranslation();
const [examplesVisible, setExamplesVisible] = useState(false);
+ const theme = useTheme();
+ const isMd = useMediaQuery(theme.breakpoints.down('md'));
useEffect(() => {
const timeout = setTimeout(() => {
@@ -45,16 +54,18 @@ function ToolLinks() {
}
return (
-
- scrollToElement('tool')}
- >
- Use This Tool
-
-
+ {isMd && (
+
+ scrollToElement('tool')}
+ >
+ Use This Tool
+
+
+ )}
{examplesVisible && (
scrollToElement('examples')}
>
- See Examples
+ {t('toolHeader.seeExamples')}
)}
@@ -80,15 +91,19 @@ export default function ToolHeader({
icon,
title,
description,
- type
+ type,
+ path
}: ToolHeaderProps) {
+ const theme = useTheme();
+ const { t } = useTranslation();
+ const [bookmarked, setBookmarked] = useState(isBookmarked(path));
return (
category.type === type
)!.rawTitle,
link: '/categories/' + type
@@ -98,9 +113,27 @@ export default function ToolHeader({
/>
-
- {title}
-
+
+
+ {title}
+
+ {
+ toggleBookmarked(path);
+ setBookmarked(!bookmarked);
+ }}
+ >
+
+
+
{description}
diff --git a/src/components/ToolLayout.tsx b/src/components/ToolLayout.tsx
index 3da0837..5559d49 100644
--- a/src/components/ToolLayout.tsx
+++ b/src/components/ToolLayout.tsx
@@ -5,26 +5,47 @@ import ToolHeader from './ToolHeader';
import Separator from './Separator';
import AllTools from './allTools/AllTools';
import { getToolsByCategory } from '@tools/index';
-import { capitalizeFirstLetter } from '../utils/string';
+import {
+ capitalizeFirstLetter,
+ getI18nNamespaceFromToolCategory
+} from '../utils/string';
import { IconifyIcon } from '@iconify/react';
+import { useTranslation } from 'react-i18next';
+import { ToolCategory } from '@tools/defineTool';
+import { FullI18nKey } from '../i18n';
export default function ToolLayout({
children,
- title,
- description,
icon,
- type
+ i18n,
+ type,
+ fullPath
}: {
- title: string;
- description: string;
icon?: IconifyIcon | string;
- type: string;
+ type: ToolCategory;
+ fullPath: string;
children: ReactNode;
+ i18n?: {
+ name: FullI18nKey;
+ description: FullI18nKey;
+ shortDescription: FullI18nKey;
+ };
}) {
+ const { t } = useTranslation([
+ 'translation',
+ getI18nNamespaceFromToolCategory(type)
+ ]);
+
+ // Use i18n keys if available, otherwise fall back to provided strings
+ //@ts-ignore
+ const toolTitle: string = t(i18n.name);
+ //@ts-ignore
+ const toolDescription: string = t(i18n.description);
+
const otherCategoryTools =
- getToolsByCategory()
+ getToolsByCategory(t)
.find((category) => category.type === type)
- ?.tools.filter((tool) => tool.name !== title)
+ ?.tools.filter((tool) => t(tool.name) !== toolTitle)
.map((tool) => ({
title: tool.name,
description: tool.shortDescription,
@@ -41,22 +62,25 @@ export default function ToolLayout({
sx={{ backgroundColor: 'background.default' }}
>
- {`${title} - OmniTools`}
+ {`${toolTitle} - OmniTools`}
{children}
category.type === type)!
- .rawTitle
- )} tools`}
+ title={t('translation:toolLayout.allToolsTitle', '', {
+ type: capitalizeFirstLetter(
+ getToolsByCategory(t).find((category) => category.type === type)!
+ .title
+ )
+ })}
toolCards={otherCategoryTools}
/>
diff --git a/src/components/allTools/AllTools.tsx b/src/components/allTools/AllTools.tsx
index 06d663b..bd447e0 100644
--- a/src/components/allTools/AllTools.tsx
+++ b/src/components/allTools/AllTools.tsx
@@ -1,10 +1,12 @@
import { Box, Grid, Stack, Typography } from '@mui/material';
import ToolCard from './ToolCard';
import { IconifyIcon } from '@iconify/react';
+import { useTranslation } from 'react-i18next';
+import { FullI18nKey } from '../../i18n';
export interface ToolCardProps {
- title: string;
- description: string;
+ title: FullI18nKey;
+ description: FullI18nKey;
link: string;
icon: IconifyIcon | string;
}
@@ -15,6 +17,7 @@ interface AllToolsProps {
}
export default function AllTools({ title, toolCards }: AllToolsProps) {
+ const { t } = useTranslation();
return (
@@ -25,8 +28,10 @@ export default function AllTools({ title, toolCards }: AllToolsProps) {
{toolCards.map((card, index) => (
diff --git a/src/components/examples/ToolExamples.tsx b/src/components/examples/ToolExamples.tsx
index c1c00c6..1b87f16 100644
--- a/src/components/examples/ToolExamples.tsx
+++ b/src/components/examples/ToolExamples.tsx
@@ -3,6 +3,7 @@ import ExampleCard, { ExampleCardProps } from './ExampleCard';
import React from 'react';
import { GetGroupsType } from '@components/options/ToolOptions';
import { useFormikContext } from 'formik';
+import { useTranslation } from 'react-i18next';
export type CardExampleType = Omit<
ExampleCardProps,
@@ -24,6 +25,7 @@ export default function ToolExamples({
getGroups,
setInput
}: ExampleProps) {
+ const { t } = useTranslation();
const { setValues } = useFormikContext();
function changeInputResult(newInput: string | undefined, newOptions: T) {
@@ -39,10 +41,10 @@ export default function ToolExamples({
- {`${title} Examples`}
+ {t('toolExamples.title', { title })}
- {subtitle ?? 'Click to try!'}
+ {subtitle ?? t('toolExamples.subtitle')}
diff --git a/src/components/input/BaseFileInput.tsx b/src/components/input/BaseFileInput.tsx
index ebc3840..6502e6c 100644
--- a/src/components/input/BaseFileInput.tsx
+++ b/src/components/input/BaseFileInput.tsx
@@ -12,6 +12,7 @@ import { globalInputHeight } from '../../config/uiConfig';
import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
import greyPattern from '@assets/grey-pattern.png';
import { isArray } from 'lodash';
+import { useTranslation } from 'react-i18next';
interface BaseFileInputComponentProps extends BaseFileInputProps {
children: (props: { preview: string | undefined }) => ReactNode;
@@ -26,6 +27,7 @@ export default function BaseFileInput({
children,
type
}: BaseFileInputComponentProps) {
+ const { t } = useTranslation();
const [preview, setPreview] = useState(null);
const [isDragging, setIsDragging] = useState(false);
const theme = useTheme();
@@ -60,9 +62,9 @@ export default function BaseFileInput({
navigator.clipboard
.write([clipboardItem])
- .then(() => showSnackBar('File copied', 'success'))
+ .then(() => showSnackBar(t('baseFileInput.fileCopied'), 'success'))
.catch((err) => {
- showSnackBar('Failed to copy: ' + err, 'error');
+ showSnackBar(t('baseFileInput.copyFailed', { error: err }), 'error');
});
}
};
@@ -190,7 +192,7 @@ export default function BaseFileInput({
variant="h6"
align="center"
>
- Drop your {type} here
+ {t('baseFileInput.dropFileHere', { type })}
) : (
- Click here to select a {type} from your device, press Ctrl+V to
- use a {type} from your clipboard, or drag and drop a file from
- desktop
+ {t('baseFileInput.selectFileDescription', { type })}
)}
diff --git a/src/components/input/InputFooter.tsx b/src/components/input/InputFooter.tsx
index 5760022..3a4afa5 100644
--- a/src/components/input/InputFooter.tsx
+++ b/src/components/input/InputFooter.tsx
@@ -3,6 +3,7 @@ import Button from '@mui/material/Button';
import PublishIcon from '@mui/icons-material/Publish';
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
import ClearIcon from '@mui/icons-material/Clear';
+import { useTranslation } from 'react-i18next';
export default function InputFooter({
handleImport,
@@ -13,19 +14,21 @@ export default function InputFooter({
handleCopy?: () => void;
handleClear?: () => void;
}) {
+ const { t } = useTranslation();
+
return (
}>
- Import from file
+ {t('inputFooter.importFromFile')}
{handleCopy && (
}>
- Copy to clipboard
+ {t('inputFooter.copyToClipboard')}
)}
{handleClear && (
}>
- Clear
+ {t('inputFooter.clear')}
)}
diff --git a/src/components/input/NumericInputWithUnit.tsx b/src/components/input/NumericInputWithUnit.tsx
index a545685..436d933 100644
--- a/src/components/input/NumericInputWithUnit.tsx
+++ b/src/components/input/NumericInputWithUnit.tsx
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import { Grid, Select, MenuItem } from '@mui/material';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import Qty from 'js-quantities';
+import { useTranslation } from 'react-i18next';
//
const siPrefixes: { [key: string]: number } = {
@@ -23,6 +24,7 @@ export default function NumericInputWithUnit(props: {
onOwnChange?: (value: { value: number; unit: string }) => void;
defaultPrefix?: string;
}) {
+ const { t } = useTranslation();
const [inputValue, setInputValue] = useState(props.value.value);
const [prefix, setPrefix] = useState(props.defaultPrefix || 'Default prefix');
@@ -158,7 +160,7 @@ export default function NumericInputWithUnit(props: {
{
diff --git a/src/components/input/ToolCodeInput.tsx b/src/components/input/ToolCodeInput.tsx
new file mode 100644
index 0000000..c23553b
--- /dev/null
+++ b/src/components/input/ToolCodeInput.tsx
@@ -0,0 +1,75 @@
+import { Box, useTheme } from '@mui/material';
+import React, { useContext, useRef } from 'react';
+import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
+import InputHeader from '../InputHeader';
+import InputFooter from './InputFooter';
+import { useTranslation } from 'react-i18next';
+import Editor from '@monaco-editor/react';
+import { globalInputHeight } from '../../config/uiConfig';
+
+export default function ToolCodeInput({
+ value,
+ onChange,
+ title = 'Input text',
+ language
+}: {
+ title?: string;
+ value: string;
+ language: string;
+ onChange: (value: string) => void;
+}) {
+ const { t } = useTranslation();
+ const { showSnackBar } = useContext(CustomSnackBarContext);
+ const fileInputRef = useRef(null);
+ const theme = useTheme();
+
+ const handleCopy = () => {
+ navigator.clipboard
+ .writeText(value)
+ .then(() => showSnackBar(t('toolTextInput.copied'), 'success'))
+ .catch((err) => {
+ showSnackBar(t('toolTextInput.copyFailed', { error: err }), 'error');
+ });
+ };
+
+ const handleFileChange = (event: React.ChangeEvent) => {
+ const file = event.target.files?.[0];
+ if (file) {
+ const reader = new FileReader();
+ reader.onload = (e) => {
+ const text = e.target?.result;
+ if (typeof text === 'string') {
+ onChange(text);
+ }
+ };
+ reader.readAsText(file);
+ }
+ };
+
+ const handleImportClick = () => {
+ fileInputRef.current?.click();
+ };
+
+ return (
+
+
+
+ onChange(value ?? '')}
+ />
+
+
+
+
+ );
+}
diff --git a/src/components/input/ToolMultipleAudioInput.tsx b/src/components/input/ToolMultipleAudioInput.tsx
index daba468..f6729cc 100644
--- a/src/components/input/ToolMultipleAudioInput.tsx
+++ b/src/components/input/ToolMultipleAudioInput.tsx
@@ -6,6 +6,7 @@ import InputFooter from './InputFooter';
import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
import { isArray } from 'lodash';
import MusicNoteIcon from '@mui/icons-material/MusicNote';
+import { useTranslation } from 'react-i18next';
interface MultiAudioInputComponentProps {
accept: string[];
@@ -27,7 +28,10 @@ export default function ToolMultipleAudioInput({
title,
type
}: MultiAudioInputComponentProps) {
+ const { t } = useTranslation();
+ const theme = useTheme();
const fileInputRef = useRef(null);
+ const { showSnackBar } = useContext(CustomSnackBarContext);
const handleFileChange = (event: React.ChangeEvent) => {
const files = event.target.files;
@@ -93,7 +97,12 @@ export default function ToolMultipleAudioInput({
return (
- No files selected
+ {t('toolMultipleAudioInput.noFilesSelected')}
)}
diff --git a/src/components/input/ToolMultiplePdfInput.tsx b/src/components/input/ToolMultiplePdfInput.tsx
index 2afa2ff..67f874f 100644
--- a/src/components/input/ToolMultiplePdfInput.tsx
+++ b/src/components/input/ToolMultiplePdfInput.tsx
@@ -6,6 +6,7 @@ import InputFooter from './InputFooter';
import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
import { isArray } from 'lodash';
import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf';
+import { useTranslation } from 'react-i18next';
interface MultiPdfInputComponentProps {
accept: string[];
@@ -27,6 +28,7 @@ export default function ToolMultiFileInput({
title,
type
}: MultiPdfInputComponentProps) {
+ const { t } = useTranslation();
const theme = useTheme();
const fileInputRef = useRef(null);
const { showSnackBar } = useContext(CustomSnackBarContext);
@@ -96,7 +98,12 @@ export default function ToolMultiFileInput({
return (
- No files selected
+ {t('toolMultiplePdfInput.noFilesSelected')}
)}
diff --git a/src/components/input/ToolMultipleVideoInput.tsx b/src/components/input/ToolMultipleVideoInput.tsx
new file mode 100644
index 0000000..9f42b8a
--- /dev/null
+++ b/src/components/input/ToolMultipleVideoInput.tsx
@@ -0,0 +1,177 @@
+import { ReactNode, useContext, useEffect, useRef, useState } from 'react';
+import { Box, useTheme } from '@mui/material';
+import Typography from '@mui/material/Typography';
+import InputHeader from '../InputHeader';
+import InputFooter from './InputFooter';
+import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
+import { isArray } from 'lodash';
+import VideoFileIcon from '@mui/icons-material/VideoFile';
+
+interface MultiVideoInputComponentProps {
+ accept: string[];
+ title?: string;
+ type: 'video';
+ value: MultiVideoInput[];
+ onChange: (file: MultiVideoInput[]) => void;
+}
+
+export interface MultiVideoInput {
+ file: File;
+ order: number;
+}
+
+export default function ToolMultipleVideoInput({
+ value,
+ onChange,
+ accept,
+ title,
+ type
+}: MultiVideoInputComponentProps) {
+ console.log('ToolMultipleVideoInput rendering with value:', value);
+
+ const fileInputRef = useRef(null);
+
+ const handleFileChange = (event: React.ChangeEvent) => {
+ const files = event.target.files;
+ console.log('File change event:', files);
+ if (files)
+ onChange([
+ ...value,
+ ...Array.from(files).map((file) => ({ file, order: value.length }))
+ ]);
+ };
+
+ const handleImportClick = () => {
+ console.log('Import clicked');
+ fileInputRef.current?.click();
+ };
+
+ function handleClear() {
+ console.log('Clear clicked');
+ onChange([]);
+ }
+
+ function fileNameTruncate(fileName: string) {
+ const maxLength = 15;
+ if (fileName.length > maxLength) {
+ return fileName.slice(0, maxLength) + '...';
+ }
+ return fileName;
+ }
+
+ const sortList = () => {
+ const list = [...value];
+ list.sort((a, b) => a.order - b.order);
+ onChange(list);
+ };
+
+ const reorderList = (sourceIndex: number, destinationIndex: number) => {
+ if (destinationIndex === sourceIndex) {
+ return;
+ }
+ const list = [...value];
+
+ if (destinationIndex === 0) {
+ list[sourceIndex].order = list[0].order - 1;
+ sortList();
+ return;
+ }
+
+ if (destinationIndex === list.length - 1) {
+ list[sourceIndex].order = list[list.length - 1].order + 1;
+ sortList();
+ return;
+ }
+
+ if (destinationIndex < sourceIndex) {
+ list[sourceIndex].order =
+ (list[destinationIndex].order + list[destinationIndex - 1].order) / 2;
+ sortList();
+ return;
+ }
+
+ list[sourceIndex].order =
+ (list[destinationIndex].order + list[destinationIndex + 1].order) / 2;
+ sortList();
+ };
+
+ return (
+
+
+
+
+ {value?.length ? (
+ value.map((file, index) => (
+
+
+
+
+ {fileNameTruncate(file.file.name)}
+
+
+ {
+ const updatedFiles = value.filter((_, i) => i !== index);
+ onChange(updatedFiles);
+ }}
+ >
+ โ
+
+
+ ))
+ ) : (
+
+ No files selected
+
+ )}
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/input/ToolTextInput.tsx b/src/components/input/ToolTextInput.tsx
index 793e0d7..5891dee 100644
--- a/src/components/input/ToolTextInput.tsx
+++ b/src/components/input/ToolTextInput.tsx
@@ -3,6 +3,7 @@ import React, { useContext, useRef } from 'react';
import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
import InputHeader from '../InputHeader';
import InputFooter from './InputFooter';
+import { useTranslation } from 'react-i18next';
export default function ToolTextInput({
value,
@@ -15,15 +16,16 @@ export default function ToolTextInput({
onChange: (value: string) => void;
placeholder?: string;
}) {
+ const { t } = useTranslation();
const { showSnackBar } = useContext(CustomSnackBarContext);
const fileInputRef = useRef(null);
const handleCopy = () => {
navigator.clipboard
.writeText(value)
- .then(() => showSnackBar('Text copied', 'success'))
+ .then(() => showSnackBar(t('toolTextInput.copied'), 'success'))
.catch((err) => {
- showSnackBar('Failed to copy: ' + err, 'error');
+ showSnackBar(t('toolTextInput.copyFailed', { error: err }), 'error');
});
};
const handleFileChange = (event: React.ChangeEvent) => {
@@ -45,14 +47,14 @@ export default function ToolTextInput({
};
return (
-
+
onChange(event.target.value)}
fullWidth
multiline
rows={10}
- placeholder={placeholder}
+ placeholder={placeholder || t('toolTextInput.placeholder')}
sx={{
'&.MuiTextField-root': {
backgroundColor: 'background.paper'
diff --git a/src/components/options/ToolOptions.tsx b/src/components/options/ToolOptions.tsx
index b08d42a..0e14b02 100644
--- a/src/components/options/ToolOptions.tsx
+++ b/src/components/options/ToolOptions.tsx
@@ -4,6 +4,7 @@ import Typography from '@mui/material/Typography';
import React, { ReactNode } from 'react';
import { FormikProps, FormikValues, useFormikContext } from 'formik';
import ToolOptionGroups, { ToolOptionGroup } from './ToolOptionGroups';
+import { useTranslation } from 'react-i18next';
export type UpdateField = (field: Y, value: T[Y]) => void;
type NonEmptyArray = [T, ...T[]];
@@ -20,6 +21,7 @@ export default function ToolOptions({
getGroups: GetGroupsType | null;
vertical?: boolean;
}) {
+ const { t } = useTranslation();
const theme = useTheme();
const formikContext = useFormikContext();
@@ -45,7 +47,7 @@ export default function ToolOptions({
>
- Tool options
+ {t('toolOptions.title')}
diff --git a/src/components/result/ResultFooter.tsx b/src/components/result/ResultFooter.tsx
index cf8708e..58aeaca 100644
--- a/src/components/result/ResultFooter.tsx
+++ b/src/components/result/ResultFooter.tsx
@@ -3,13 +3,14 @@ import Button from '@mui/material/Button';
import DownloadIcon from '@mui/icons-material/Download';
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
import React from 'react';
+import { useTranslation } from 'react-i18next';
export default function ResultFooter({
handleDownload,
handleCopy,
disabled,
hideCopy,
- downloadLabel = 'Download'
+ downloadLabel
}: {
handleDownload: () => void;
handleCopy?: () => void;
@@ -17,6 +18,7 @@ export default function ResultFooter({
hideCopy?: boolean;
downloadLabel?: string;
}) {
+ const { t } = useTranslation();
return (
}
>
- {downloadLabel}
+ {downloadLabel || t('resultFooter.download')}
{!hideCopy && (
}
>
- Copy to clipboard
+ {t('resultFooter.copy')}
)}
diff --git a/src/components/result/ToolFileResult.tsx b/src/components/result/ToolFileResult.tsx
index 7dc9b5d..b5478c7 100644
--- a/src/components/result/ToolFileResult.tsx
+++ b/src/components/result/ToolFileResult.tsx
@@ -5,6 +5,7 @@ import greyPattern from '@assets/grey-pattern.png';
import { globalInputHeight } from '../../config/uiConfig';
import ResultFooter from './ResultFooter';
import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
+import { useTranslation } from 'react-i18next';
export default function ToolFileResult({
title = 'Result',
@@ -19,6 +20,7 @@ export default function ToolFileResult({
loading?: boolean;
loadingText?: string;
}) {
+ const { t } = useTranslation();
const [preview, setPreview] = React.useState(null);
const { showSnackBar } = useContext(CustomSnackBarContext);
const theme = useTheme();
@@ -41,9 +43,9 @@ export default function ToolFileResult({
navigator.clipboard
.write([clipboardItem])
- .then(() => showSnackBar('File copied', 'success'))
+ .then(() => showSnackBar(t('toolFileResult.copied'), 'success'))
.catch((err) => {
- showSnackBar('Failed to copy: ' + err, 'error');
+ showSnackBar(t('toolFileResult.copyFailed', { error: err }), 'error');
});
}
};
@@ -91,7 +93,7 @@ export default function ToolFileResult({
return (
-
+
- {loadingText}... This may take a moment.
+ {loadingText || t('toolFileResult.loading')}
) : (
diff --git a/src/components/result/ToolMultiFileResult.tsx b/src/components/result/ToolMultiFileResult.tsx
index d7b006e..87d8aa7 100644
--- a/src/components/result/ToolMultiFileResult.tsx
+++ b/src/components/result/ToolMultiFileResult.tsx
@@ -9,8 +9,11 @@ import InputHeader from '../InputHeader';
import greyPattern from '@assets/grey-pattern.png';
import { globalInputHeight } from '../../config/uiConfig';
import ResultFooter from './ResultFooter';
+import { useTranslation } from 'react-i18next';
+import React, { useContext } from 'react';
+import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
-export default function ToolFileResult({
+export default function ToolMultiFileResult({
title = 'Result',
value,
zipFile,
@@ -23,7 +26,9 @@ export default function ToolFileResult({
loading?: boolean;
loadingText?: string;
}) {
+ const { t } = useTranslation();
const theme = useTheme();
+ const { showSnackBar } = useContext(CustomSnackBarContext);
const getFileType = (
file: File
@@ -46,9 +51,25 @@ export default function ToolFileResult({
URL.revokeObjectURL(url);
};
+ const handleCopy = () => {
+ if (zipFile) {
+ const blob = new Blob([zipFile], { type: zipFile.type });
+ const clipboardItem = new ClipboardItem({ [zipFile.type]: blob });
+ navigator.clipboard
+ .write([clipboardItem])
+ .then(() => showSnackBar(t('toolMultiFileResult.copied'), 'success'))
+ .catch((err) => {
+ showSnackBar(
+ t('toolMultiFileResult.copyFailed', { error: err }),
+ 'error'
+ );
+ });
+ }
+ };
+
return (
-
+
- {loadingText}... This may take a moment.
+ {loadingText || t('toolMultiFileResult.loading')}
) : (
diff --git a/src/components/result/ToolTextResult.tsx b/src/components/result/ToolTextResult.tsx
index ca2b588..64ec61b 100644
--- a/src/components/result/ToolTextResult.tsx
+++ b/src/components/result/ToolTextResult.tsx
@@ -6,6 +6,7 @@ import ResultFooter from './ResultFooter';
import { replaceSpecialCharacters } from '@utils/string';
import mime from 'mime';
import { globalInputHeight } from '../../config/uiConfig';
+import { useTranslation } from 'react-i18next';
export default function ToolTextResult({
title = 'Result',
@@ -20,13 +21,14 @@ export default function ToolTextResult({
keepSpecialCharacters?: boolean;
loading?: boolean;
}) {
+ const { t } = useTranslation();
const { showSnackBar } = useContext(CustomSnackBarContext);
const handleCopy = () => {
navigator.clipboard
.writeText(value)
- .then(() => showSnackBar('Text copied', 'success'))
+ .then(() => showSnackBar(t('toolTextResult.copied'), 'success'))
.catch((err) => {
- showSnackBar('Failed to copy: ' + err, 'error');
+ showSnackBar(t('toolTextResult.copyFailed', { error: err }), 'error');
});
};
const handleDownload = () => {
@@ -48,7 +50,7 @@ export default function ToolTextResult({
};
return (
-
+
{loading ? (
- Loading... This may take a moment.
+ {t('toolTextResult.loading')}
) : (
diff --git a/src/i18n/index.ts b/src/i18n/index.ts
new file mode 100644
index 0000000..0f6a430
--- /dev/null
+++ b/src/i18n/index.ts
@@ -0,0 +1,39 @@
+import i18n, { Namespace, ParseKeys } from 'i18next';
+import { initReactI18next } from 'react-i18next';
+import Backend from 'i18next-http-backend';
+
+export const validNamespaces = [
+ 'string',
+ 'number',
+ 'video',
+ 'list',
+ 'json',
+ 'time',
+ 'csv',
+ 'pdf',
+ 'audio',
+ 'xml',
+ 'translation',
+ 'image'
+] as const satisfies readonly Namespace[];
+
+export type I18nNamespaces = (typeof validNamespaces)[number];
+export type FullI18nKey = {
+ [K in I18nNamespaces]: `${K}:${ParseKeys}`;
+}[I18nNamespaces];
+
+i18n
+ .use(Backend)
+ .use(initReactI18next)
+ .init({
+ lng: localStorage.getItem('lang') || 'en',
+ fallbackLng: 'en',
+ interpolation: {
+ escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
+ },
+ backend: {
+ loadPath: '/locales/{{lng}}/{{ns}}.json'
+ }
+ });
+
+export default i18n;
diff --git a/src/pages/home/Categories.tsx b/src/pages/home/Categories.tsx
index ba41633..99d943d 100644
--- a/src/pages/home/Categories.tsx
+++ b/src/pages/home/Categories.tsx
@@ -8,6 +8,9 @@ import { useState } from 'react';
import { categoriesColors } from 'config/uiConfig';
import { Icon } from '@iconify/react';
import { useUserTypeFilter } from '@components/UserTypeFilter';
+import { useTranslation } from 'react-i18next';
+import { getI18nNamespaceFromToolCategory } from '@utils/string';
+import { validNamespaces } from '../../i18n';
type ArrayElement =
ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
@@ -19,10 +22,26 @@ const SingleCategory = function ({
category: ArrayElement>;
index: number;
}) {
+ const { t } = useTranslation(getI18nNamespaceFromToolCategory(category.type));
const navigate = useNavigate();
const theme = useTheme();
const [hovered, setHovered] = useState(false);
const toggleHover = () => setHovered((prevState) => !prevState);
+
+ // Get translated category title and description
+ const categoryTitle = t(`categories.${category.type}.title`, category.title);
+ const categoryDescription = t(
+ `categories.${category.type}.description`,
+ category.description
+ );
+ const seeAllText = t('translation:categories.seeAll', 'See all {{title}}', {
+ title: categoryTitle
+ });
+ const tryText = t('translation:categories.try', 'Try {{title}}', {
+ //@ts-ignore
+ title: t(category.example.title)
+ });
+
return (
- {category.title}
+ {categoryTitle}
- {category.description}
+ {categoryDescription}
@@ -72,7 +91,9 @@ const SingleCategory = function ({
fullWidth
onClick={() => navigate('/categories/' + category.type)}
variant={'contained'}
- >{`See all ${category.title}`}
+ >
+ {seeAllText}
+
navigate(category.example.path)}
variant={'outlined'}
- >{`Try ${category.example.title}`}
+ >
+ {tryText}
+
@@ -92,7 +115,8 @@ const SingleCategory = function ({
export default function Categories() {
const { selectedUserTypes } = useUserTypeFilter();
- const categories = getToolsByCategory(selectedUserTypes);
+ const { t } = useTranslation();
+ const categories = getToolsByCategory(selectedUserTypes, t);
return (
diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx
index 4443975..bf891d8 100644
--- a/src/pages/home/index.tsx
+++ b/src/pages/home/index.tsx
@@ -1,6 +1,7 @@
import { Box, useTheme } from '@mui/material';
import Hero from 'components/Hero';
import Categories from './Categories';
+import { Helmet } from 'react-helmet';
export default function Home() {
const theme = useTheme();
@@ -25,6 +26,7 @@ export default function Home() {
justifyContent={'center'}
width={'100%'}
>
+
diff --git a/src/pages/tools-by-category/index.tsx b/src/pages/tools-by-category/index.tsx
index f5f9050..24fb833 100644
--- a/src/pages/tools-by-category/index.tsx
+++ b/src/pages/tools-by-category/index.tsx
@@ -2,8 +2,8 @@ import {
Box,
Divider,
Stack,
- TextField,
styled,
+ TextField,
useTheme
} from '@mui/material';
import Grid from '@mui/material/Grid';
@@ -11,17 +11,20 @@ import Typography from '@mui/material/Typography';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { filterTools, getToolsByCategory } from '../../tools';
import Hero from 'components/Hero';
-import { capitalizeFirstLetter, getToolCategoryTitle } from '@utils/string';
+import {
+ getI18nNamespaceFromToolCategory,
+ getToolCategoryTitle
+} from '@utils/string';
import { Icon } from '@iconify/react';
import { categoriesColors } from 'config/uiConfig';
import React, { useEffect } from 'react';
import IconButton from '@mui/material/IconButton';
-import { ArrowBack } from '@mui/icons-material';
-import BackButton from '@components/BackButton';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import SearchIcon from '@mui/icons-material/Search';
import { Helmet } from 'react-helmet';
import UserTypeFilter, { useUserTypeFilter } from '@components/UserTypeFilter';
+import { useTranslation } from 'react-i18next';
+import { I18nNamespaces, validNamespaces } from '../../i18n';
const StyledLink = styled(Link)(({ theme }) => ({
'&:hover': {
@@ -36,7 +39,20 @@ export default function ToolsByCategory() {
const { categoryName } = useParams();
const [searchTerm, setSearchTerm] = React.useState('');
const { selectedUserTypes, setSelectedUserTypes } = useUserTypeFilter();
- const rawTitle = getToolCategoryTitle(categoryName as string);
+ const { t } = useTranslation(validNamespaces);
+ const rawTitle = getToolCategoryTitle(categoryName as string, t);
+ // First get tools by category without filtering
+ const toolsByCategory =
+ getToolsByCategory(selectedUserTypes, t).find(
+ ({ type }) => type === categoryName
+ )?.tools ?? [];
+
+ const categoryTools = filterTools(
+ toolsByCategory,
+ searchTerm,
+ selectedUserTypes,
+ t
+ );
useEffect(() => {
if (mainContentRef.current) {
@@ -48,21 +64,10 @@ export default function ToolsByCategory() {
setSelectedUserTypes(userTypes as any);
};
- const categoryTools =
- getToolsByCategory(selectedUserTypes).find(
- ({ type }) => type === categoryName
- )?.tools ?? [];
-
- const filteredTools = filterTools(
- categoryTools,
- searchTerm,
- selectedUserTypes
- );
-
return (
- {`${rawTitle} Tools`}
+ {rawTitle}
navigate('/')}>
- {`All ${rawTitle} Tools`}
+
+ {t('translation:toolLayout.allToolsTitle', { type: rawTitle })}
+
- {filteredTools.map((tool, index) => (
+ {categoryTools.map((tool, index) => (
- {tool.name}
+ {/*@ts-ignore*/}
+ {t(tool.name)}
- {tool.shortDescription}
+ {/*@ts-ignore*/}
+ {t(tool.shortDescription)}
diff --git a/src/pages/tools/audio/change-speed/index.tsx b/src/pages/tools/audio/change-speed/index.tsx
index e799814..bb556b3 100644
--- a/src/pages/tools/audio/change-speed/index.tsx
+++ b/src/pages/tools/audio/change-speed/index.tsx
@@ -9,6 +9,7 @@ import ToolFileResult from '@components/result/ToolFileResult';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import RadioWithTextField from '@components/options/RadioWithTextField';
import { changeAudioSpeed } from './service';
+import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
newSpeed: 2,
@@ -25,6 +26,7 @@ export default function ChangeSpeed({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('audio');
const [input, setInput] = useState(null);
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
@@ -49,20 +51,20 @@ export default function ChangeSpeed({
updateField
}) => [
{
- title: 'New Audio Speed',
+ title: t('changeSpeed.newAudioSpeed'),
component: (
updateField('newSpeed', Number(val))}
- description="Default multiplier: 2 means 2x faster"
+ description={t('changeSpeed.speedDescription')}
type="number"
/>
)
},
{
- title: 'Output Format',
+ title: t('changeSpeed.outputFormat'),
component: (
}
resultComponent={
loading ? (
-
+
) : (
@@ -114,7 +120,10 @@ export default function ChangeSpeed({
getGroups={getGroups}
setInput={setInput}
compute={compute}
- toolInfo={{ title: `What is ${title}?`, description: longDescription }}
+ toolInfo={{
+ title: t('changeSpeed.toolInfo.title', { title }),
+ description: longDescription
+ }}
/>
);
}
diff --git a/src/pages/tools/audio/change-speed/meta.ts b/src/pages/tools/audio/change-speed/meta.ts
index 23fe3e4..1dfbce1 100644
--- a/src/pages/tools/audio/change-speed/meta.ts
+++ b/src/pages/tools/audio/change-speed/meta.ts
@@ -2,13 +2,25 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('audio', {
- name: 'Change audio speed',
path: 'change-speed',
- icon: 'material-symbols-light:speed-outline',
- description:
- 'This online utility lets you change the speed of an audio. You can speed it up or slow it down.',
- shortDescription: 'Quickly change audio speed',
- keywords: ['change', 'speed'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:speed',
+
+ keywords: [
+ 'audio',
+ 'speed',
+ 'tempo',
+ 'playback',
+ 'accelerate',
+ 'slow down',
+ 'pitch',
+ 'media'
+ ],
+
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'audio:changeSpeed.title',
+ description: 'audio:changeSpeed.description',
+ shortDescription: 'audio:changeSpeed.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/audio/extract-audio/index.tsx b/src/pages/tools/audio/extract-audio/index.tsx
index f5012ec..e54e290 100644
--- a/src/pages/tools/audio/extract-audio/index.tsx
+++ b/src/pages/tools/audio/extract-audio/index.tsx
@@ -8,6 +8,7 @@ import ToolVideoInput from '@components/input/ToolVideoInput';
import { GetGroupsType } from '@components/options/ToolOptions';
import ToolFileResult from '@components/result/ToolFileResult';
import SelectWithDesc from '@components/options/SelectWithDesc';
+import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
outputFormat: 'aac'
@@ -17,6 +18,7 @@ export default function ExtractAudio({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('audio');
const [file, setFile] = useState(null);
const [audioFile, setAudioFile] = useState(null);
const [loading, setLoading] = useState(false);
@@ -27,7 +29,7 @@ export default function ExtractAudio({
}) => {
return [
{
- title: 'Output Format',
+ title: t('extractAudio.outputFormat'),
component: (
)
@@ -68,23 +68,33 @@ export default function ExtractAudio({
title={title}
input={file}
inputComponent={
-
+
}
resultComponent={
loading ? (
) : (
-
+
)
}
initialValues={initialValues}
getGroups={getGroups}
compute={compute}
- toolInfo={{ title: `What is ${title}?`, description: longDescription }}
+ toolInfo={{
+ title: t('extractAudio.toolInfo.title', { title }),
+ description: longDescription
+ }}
setInput={setFile}
/>
);
diff --git a/src/pages/tools/audio/extract-audio/meta.ts b/src/pages/tools/audio/extract-audio/meta.ts
index 548b0db..bb2b234 100644
--- a/src/pages/tools/audio/extract-audio/meta.ts
+++ b/src/pages/tools/audio/extract-audio/meta.ts
@@ -2,13 +2,9 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('audio', {
- name: 'Extract audio',
path: 'extract-audio',
icon: 'mdi:music-note',
- description:
- 'Extract the audio track from a video file and save it as a separate audio file in your chosen format (AAC, MP3, WAV).',
- shortDescription:
- 'Extract audio from video files (MP4, MOV, etc.) to AAC, MP3, or WAV.',
+
keywords: [
'extract',
'audio',
@@ -20,8 +16,12 @@ export const tool = defineTool('audio', {
'media',
'convert'
],
- longDescription:
- 'This tool allows you to extract the audio track from a video file (such as MP4, MOV, AVI, etc.) and save it as a standalone audio file in your preferred format (AAC, MP3, or WAV). Useful for podcasts, music, or any scenario where you need just the audio from a video.',
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'audio:extractAudio.title',
+ description: 'audio:extractAudio.description',
+ shortDescription: 'audio:extractAudio.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/audio/merge-audio/index.tsx b/src/pages/tools/audio/merge-audio/index.tsx
index 09acd35..02ab2b8 100644
--- a/src/pages/tools/audio/merge-audio/index.tsx
+++ b/src/pages/tools/audio/merge-audio/index.tsx
@@ -1,5 +1,6 @@
import { Box, FormControlLabel, Radio, RadioGroup } from '@mui/material';
import React, { useState } from 'react';
+import { useTranslation } from 'react-i18next';
import ToolContent from '@components/ToolContent';
import { ToolComponentProps } from '@tools/defineTool';
import { GetGroupsType } from '@components/options/ToolOptions';
@@ -24,6 +25,7 @@ export default function MergeAudio({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('audio');
const [input, setInput] = useState([]);
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
@@ -51,7 +53,7 @@ export default function MergeAudio({
updateField
}) => [
{
- title: 'Output Format',
+ title: t('mergeAudio.outputFormat'),
component: (
}
resultComponent={
loading ? (
-
+
) : (
@@ -106,7 +112,10 @@ export default function MergeAudio({
getGroups={getGroups}
setInput={setInput}
compute={compute}
- toolInfo={{ title: `What is ${title}?`, description: longDescription }}
+ toolInfo={{
+ title: t('mergeAudio.toolInfo.title', { title }),
+ description: longDescription
+ }}
/>
);
}
diff --git a/src/pages/tools/audio/merge-audio/meta.ts b/src/pages/tools/audio/merge-audio/meta.ts
index e541f13..68e62ee 100644
--- a/src/pages/tools/audio/merge-audio/meta.ts
+++ b/src/pages/tools/audio/merge-audio/meta.ts
@@ -2,12 +2,17 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('audio', {
- name: 'Merge Audio',
+ i18n: {
+ name: 'audio:mergeAudio.title',
+ description: 'audio:mergeAudio.description',
+ shortDescription: 'audio:mergeAudio.shortDescription',
+ longDescription: 'audio:mergeAudio.longDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ },
+
path: 'merge-audio',
icon: 'fluent:merge-20-regular',
- description:
- 'Combine multiple audio files into a single audio file by concatenating them in sequence.',
- shortDescription: 'Merge multiple audio files into one (MP3, AAC, WAV).',
+
keywords: [
'merge',
'audio',
@@ -20,8 +25,5 @@ export const tool = defineTool('audio', {
'audio editing',
'multiple files'
],
- longDescription:
- 'This tool allows you to merge multiple audio files into a single audio file. You can combine audio files end-to-end (concatenation) or overlay them (mixing). Supports various audio formats including MP3, AAC, and WAV. Perfect for creating playlists, combining podcast segments, or mixing audio tracks.',
- userTypes: ['General Users', 'Students', 'Developers'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/audio/trim/index.tsx b/src/pages/tools/audio/trim/index.tsx
index 07fed95..1a3efe7 100644
--- a/src/pages/tools/audio/trim/index.tsx
+++ b/src/pages/tools/audio/trim/index.tsx
@@ -1,5 +1,6 @@
import { Box, FormControlLabel, Radio, RadioGroup } from '@mui/material';
import React, { useState } from 'react';
+import { useTranslation } from 'react-i18next';
import ToolContent from '@components/ToolContent';
import { ToolComponentProps } from '@tools/defineTool';
import { GetGroupsType } from '@components/options/ToolOptions';
@@ -22,6 +23,7 @@ const formatOptions = [
];
export default function Trim({ title, longDescription }: ToolComponentProps) {
+ const { t } = useTranslation('audio');
const [input, setInput] = useState(null);
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
@@ -48,28 +50,28 @@ export default function Trim({ title, longDescription }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Time Settings',
+ title: t('trim.timeSettings'),
component: (
updateField('startTime', val)}
- description="Start time in format HH:MM:SS (e.g., 00:00:30)"
- label="Start Time"
+ description={t('trim.startTimeDescription')}
+ label={t('trim.startTime')}
/>
updateField('endTime', val)}
- description="End time in format HH:MM:SS (e.g., 00:01:30)"
- label="End Time"
+ description={t('trim.endTimeDescription')}
+ label={t('trim.endTime')}
/>
)
},
{
- title: 'Output Format',
+ title: t('trim.outputFormat'),
component: (
}
resultComponent={
loading ? (
-
+
) : (
@@ -122,7 +128,10 @@ export default function Trim({ title, longDescription }: ToolComponentProps) {
getGroups={getGroups}
setInput={setInput}
compute={compute}
- toolInfo={{ title: `What is ${title}?`, description: longDescription }}
+ toolInfo={{
+ title: t('trim.toolInfo.title', { title }),
+ description: longDescription
+ }}
/>
);
}
diff --git a/src/pages/tools/audio/trim/meta.ts b/src/pages/tools/audio/trim/meta.ts
index b88cb14..7665a04 100644
--- a/src/pages/tools/audio/trim/meta.ts
+++ b/src/pages/tools/audio/trim/meta.ts
@@ -2,13 +2,17 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('audio', {
- name: 'Trim Audio',
+ i18n: {
+ name: 'audio:trim.title',
+ description: 'audio:trim.description',
+ shortDescription: 'audio:trim.shortDescription',
+ longDescription: 'audio:trim.longDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ },
+
path: 'trim',
icon: 'mdi:scissors-cutting',
- description:
- 'Cut and trim audio files to extract specific segments by specifying start and end times.',
- shortDescription:
- 'Trim audio files to extract specific time segments (MP3, AAC, WAV).',
+
keywords: [
'trim',
'audio',
@@ -21,8 +25,5 @@ export const tool = defineTool('audio', {
'audio editing',
'time'
],
- longDescription:
- 'This tool allows you to trim audio files by specifying start and end times. You can extract specific segments from longer audio files, remove unwanted parts, or create shorter clips. Supports various audio formats including MP3, AAC, and WAV. Perfect for podcast editing, music production, or any audio editing needs.',
- userTypes: ['General Users', 'Students', 'Developers'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/csv/change-csv-separator/meta.ts b/src/pages/tools/csv/change-csv-separator/meta.ts
index ec2e993..5c7fb08 100644
--- a/src/pages/tools/csv/change-csv-separator/meta.ts
+++ b/src/pages/tools/csv/change-csv-separator/meta.ts
@@ -2,13 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('csv', {
- name: 'Change CSV separator',
path: 'change-csv-separator',
- icon: 'material-symbols:split-scene-rounded',
- description:
- 'Just upload your CSV file in the form below and it will automatically get a new column delimiter character. In the tool options, you can specify which delimiter and quote characters are used in the source CSV file and customize the desired delimiter and quote characters for the output CSV. You can also filter the input CSV before the conversion process and skip blank lines and comment lines.',
- shortDescription: 'Quickly change the CSV column delimiter to a new symbol.',
- keywords: ['change', 'csv', 'separator'],
- userTypes: ['Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:code',
+
+ keywords: ['csv', 'separator', 'delimiter', 'change'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'csv:changeCsvSeparator.title',
+ description: 'csv:changeCsvSeparator.description',
+ shortDescription: 'csv:changeCsvSeparator.shortDescription'
+ }
});
diff --git a/src/pages/tools/csv/csv-rows-to-columns/meta.ts b/src/pages/tools/csv/csv-rows-to-columns/meta.ts
index 53d56ae..482b0e3 100644
--- a/src/pages/tools/csv/csv-rows-to-columns/meta.ts
+++ b/src/pages/tools/csv/csv-rows-to-columns/meta.ts
@@ -2,14 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('csv', {
- name: 'Convert CSV Rows to Columns',
+ i18n: {
+ name: 'csv:csvRowsToColumns.title',
+ description: 'csv:csvRowsToColumns.description',
+ shortDescription: 'csv:csvRowsToColumns.shortDescription',
+ longDescription: 'csv:csvRowsToColumns.longDescription'
+ },
path: 'csv-rows-to-columns',
icon: 'fluent:text-arrow-down-right-column-24-filled',
- description:
- 'This tool converts rows of a CSV (Comma Separated Values) file into columns. It extracts the horizontal lines from the input CSV one by one, rotates them 90 degrees, and outputs them as vertical columns one after another, separated by commas.',
- longDescription:
- 'This tool converts rows of a CSV (Comma Separated Values) file into columns. For example, if the input CSV data has 6 rows, then the output will have 6 columns and the elements of the rows will be arranged from the top to bottom. In a well-formed CSV, the number of values in each row is the same. However, in cases when rows are missing fields, the program can fix them and you can choose from the available options: fill missing data with empty elements or replace missing data with custom elements, such as "missing", "?", or "x". During the conversion process, the tool also cleans the CSV file from unnecessary information, such as empty lines (these are lines without visible information) and comments. To help the tool correctly identify comments, in the options, you can specify the symbol at the beginning of a line that starts a comment. This symbol is typically a hash "#" or double slash "//". Csv-abulous!.',
- shortDescription: 'Convert CSV rows to columns.',
keywords: ['csv', 'rows', 'columns', 'transpose'],
userTypes: ['Developers'],
component: lazy(() => import('./index'))
diff --git a/src/pages/tools/csv/csv-to-json/index.tsx b/src/pages/tools/csv/csv-to-json/index.tsx
index fea2037..33e0fe6 100644
--- a/src/pages/tools/csv/csv-to-json/index.tsx
+++ b/src/pages/tools/csv/csv-to-json/index.tsx
@@ -6,10 +6,9 @@ import { convertCsvToJson } from './service';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
import { Box } from '@mui/material';
-import RadioWithTextField from '@components/options/RadioWithTextField';
-import SimpleRadio from '@components/options/SimpleRadio';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
+import { useTranslation } from 'react-i18next';
type InitialValuesType = {
delimiter: string;
@@ -114,6 +113,7 @@ id,name,active
];
export default function CsvToJson({ title }: ToolComponentProps) {
+ const { t } = useTranslation('csv');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -131,8 +131,10 @@ export default function CsvToJson({ title }: ToolComponentProps) {
setResult(jsonResult);
} catch (error) {
setResult(
- `Error: ${
- error instanceof Error ? error.message : 'Invalid CSV format'
+ `${t('csvToJson.error')}: ${
+ error instanceof Error
+ ? error.message
+ : t('csvToJson.invalidCsvFormat')
}`
);
}
@@ -148,28 +150,36 @@ export default function CsvToJson({ title }: ToolComponentProps) {
compute={compute}
exampleCards={exampleCards}
inputComponent={
-
+
}
resultComponent={
-
+
}
getGroups={({ values, updateField }) => [
{
- title: 'Input CSV Format',
+ title: t('csvToJson.inputCsvFormat'),
component: (
updateField('delimiter', val)}
/>
updateField('quote', val)}
value={values.quote}
/>
updateField('comment', val)}
/>
@@ -177,35 +187,34 @@ export default function CsvToJson({ title }: ToolComponentProps) {
)
},
{
- title: 'Conversion Options',
+ title: t('csvToJson.conversionOptions'),
component: (
updateField('useHeaders', value)}
- title="Use Headers"
- description="First row is treated as column headers"
+ title={t('csvToJson.useHeaders')}
+ description={t('csvToJson.useHeadersDescription')}
/>
updateField('skipEmptyLines', value)}
- title="Skip Empty Lines"
- description="Don't process empty lines in the CSV"
+ title={t('csvToJson.skipEmptyLines')}
+ description={t('csvToJson.skipEmptyLinesDescription')}
/>
updateField('dynamicTypes', value)}
- title="Dynamic Types"
- description="Convert numbers and booleans to their proper types"
+ title={t('csvToJson.dynamicTypes')}
+ description={t('csvToJson.dynamicTypesDescription')}
/>
)
}
]}
toolInfo={{
- title: 'What Is a CSV to JSON Converter?',
- description:
- 'This tool transforms Comma Separated Values (CSV) files to JavaScript Object Notation (JSON) data structures. It supports various CSV formats with customizable delimiters, quote characters, and comment symbols. The converter can treat the first row as headers, skip empty lines, and automatically detect data types like numbers and booleans. The resulting JSON can be used for data migration, backups, or as input for other applications.'
+ title: t('csvToJson.toolInfo.title'),
+ description: t('csvToJson.toolInfo.description')
}}
/>
);
diff --git a/src/pages/tools/csv/csv-to-json/meta.ts b/src/pages/tools/csv/csv-to-json/meta.ts
index 93b2800..1f20fc5 100644
--- a/src/pages/tools/csv/csv-to-json/meta.ts
+++ b/src/pages/tools/csv/csv-to-json/meta.ts
@@ -2,12 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('csv', {
- name: 'Convert CSV to JSON',
+ i18n: {
+ name: 'csv:csvToJson.title',
+ description: 'csv:csvToJson.description',
+ shortDescription: 'csv:csvToJson.shortDescription'
+ },
+
path: 'csv-to-json',
icon: 'lets-icons:json-light',
- description:
- 'Convert CSV files to JSON format with customizable options for delimiters, quotes, and output formatting. Support for headers, comments, and dynamic type conversion.',
- shortDescription: 'Convert CSV data to JSON format.',
+
keywords: ['csv', 'json', 'convert', 'transform', 'parse'],
userTypes: ['Developers'],
component: lazy(() => import('./index'))
diff --git a/src/pages/tools/csv/csv-to-tsv/meta.ts b/src/pages/tools/csv/csv-to-tsv/meta.ts
index 7ff60e2..31e6b15 100644
--- a/src/pages/tools/csv/csv-to-tsv/meta.ts
+++ b/src/pages/tools/csv/csv-to-tsv/meta.ts
@@ -2,14 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('csv', {
- name: 'Convert CSV to TSV',
+ i18n: {
+ name: 'csv:csvToTsv.title',
+ description: 'csv:csvToTsv.description',
+ shortDescription: 'csv:csvToTsv.shortDescription',
+ longDescription: 'csv:csvToTsv.longDescription'
+ },
+
path: 'csv-to-tsv',
icon: 'codicon:keyboard-tab',
- description:
- 'Upload your CSV file in the form below and it will automatically get converted to a TSV file. In the tool options, you can customize the input CSV format โ specify the field delimiter, quotation character, and comment symbol, as well as skip empty CSV lines, and choose whether to preserve CSV column headers.',
- shortDescription: 'Convert CSV data to TSV format.',
- longDescription:
- 'This tool transforms Comma Separated Values (CSV) data to Tab Separated Values (TSV) data. Both CSV and TSV are popular file formats for storing tabular data but they use different delimiters to separate values โ CSV uses commas (","), while TSV uses tabs ("\t"). If we compare CSV files to TSV files, then CSV files are much harder to parse than TSV files because the values themselves may contain commas, so it is not always obvious where one field starts and ends without complicated parsing rules. TSV, on the other hand, uses just a tab symbol, which does not usually appear in data, so separating fields in TSV is as simple as splitting the input by the tab character. To convert CSV to TSV, simply input the CSV data in the input of this tool. In rare cases when a CSV file has a delimiter other than a comma, you can specify the current delimiter in the options of the tool. You can also specify the current quote character and the comment start character. Additionally, empty CSV lines can be skipped by activating the "Ignore Lines with No Data" option. If this option is off, then empty lines in the CSV are converted to empty TSV lines. The "Preserve Headers" option allows you to choose whether to process column headers of a CSV file. If the option is selected, then the resulting TSV file will include the first row of the input CSV file, which contains the column names. Alternatively, if the headers option is not selected, the first row will be skipped during the data conversion process. For the reverse conversion from TSV to CSV, you can use our Convert TSV to CSV tool. Csv-abulous!',
keywords: ['csv', 'tsv', 'convert', 'transform', 'parse'],
userTypes: ['Developers'],
component: lazy(() => import('./index'))
diff --git a/src/pages/tools/csv/csv-to-xml/meta.ts b/src/pages/tools/csv/csv-to-xml/meta.ts
index 95c702c..3911f58 100644
--- a/src/pages/tools/csv/csv-to-xml/meta.ts
+++ b/src/pages/tools/csv/csv-to-xml/meta.ts
@@ -2,11 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('csv', {
- name: 'Convert CSV to XML',
+ i18n: {
+ name: 'csv:csvToXml.title',
+ description: 'csv:csvToXml.description',
+ shortDescription: 'csv:csvToXml.shortDescription'
+ },
+
path: 'csv-to-xml',
icon: 'mdi-light:xml',
- description: 'Convert CSV files to XML format with customizable options.',
- shortDescription: 'Convert CSV data to XML format.',
+
keywords: ['csv', 'xml', 'convert', 'transform', 'parse'],
userTypes: ['Developers'],
component: lazy(() => import('./index'))
diff --git a/src/pages/tools/csv/csv-to-yaml/meta.ts b/src/pages/tools/csv/csv-to-yaml/meta.ts
index ef0f21e..b7d5011 100644
--- a/src/pages/tools/csv/csv-to-yaml/meta.ts
+++ b/src/pages/tools/csv/csv-to-yaml/meta.ts
@@ -2,15 +2,16 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('csv', {
- name: 'Convert CSV to YAML',
+ i18n: {
+ name: 'csv:csvToYaml.title',
+ description: 'csv:csvToYaml.description',
+ shortDescription: 'csv:csvToYaml.shortDescription',
+ longDescription: 'csv:csvToYaml.longDescription',
+ userTypes: ['Developers']
+ },
+
path: 'csv-to-yaml',
icon: 'nonicons:yaml-16',
- description:
- 'Just upload your CSV file in the form below and it will automatically get converted to a YAML file. In the tool options, you can specify the field delimiter character, field quote character, and comment character to adapt the tool to custom CSV formats. Additionally, you can select the output YAML format: one that preserves CSV headers or one that excludes CSV headers.',
- shortDescription: 'Quickly convert a CSV file to a YAML file.',
keywords: ['csv', 'to', 'yaml'],
- longDescription:
- 'This tool transforms CSV (Comma Separated Values) data into the YAML (Yet Another Markup Language) data. CSV is a simple, tabular format that is used to represent matrix-like data types consisting of rows and columns. YAML, on the other hand, is a more advanced format (actually a superset of JSON), which creates more human-readable data for serialization, and it supports lists, dictionaries, and nested objects. This program supports various input CSV formats โ the input data can be comma-separated (default), semicolon-separated, pipe-separated, or use another completely different delimiter. You can specify the exact delimiter your data uses in the options. Similarly, in the options, you can specify the quote character that is used to wrap CSV fields (by default a double-quote symbol). You can also skip lines that start with comments by specifying the comment symbols in the options. This allows you to keep your data clean by skipping unnecessary lines. There are two ways to convert CSV to YAML. The first method converts each CSV row into a YAML list. The second method extracts headers from the first CSV row and creates YAML objects with keys based on these headers. You can also customize the output YAML format by specifying the number of spaces for indenting YAML structures. If you need to perform the reverse conversion, that is, transform YAML into CSV, you can use our Convert YAML to CSV tool. Csv-abulous!',
- userTypes: ['Developers'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/csv/find-incomplete-csv-records/index.tsx b/src/pages/tools/csv/find-incomplete-csv-records/index.tsx
index 1831451..fec3e23 100644
--- a/src/pages/tools/csv/find-incomplete-csv-records/index.tsx
+++ b/src/pages/tools/csv/find-incomplete-csv-records/index.tsx
@@ -10,6 +10,7 @@ import { findIncompleteCsvRecords } from './service';
import { InitialValuesType } from './types';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
+import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
csvSeparator: ',',
@@ -103,6 +104,7 @@ export default function FindIncompleteCsvRecords({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('csv');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -115,55 +117,57 @@ export default function FindIncompleteCsvRecords({
updateField
}) => [
{
- title: 'Csv input Options',
+ title: t('findIncompleteCsvRecords.csvInputOptions'),
component: (
updateField('csvSeparator', val)}
- description={
- 'Enter the character used to delimit columns in the CSV input file.'
- }
+ description={t('findIncompleteCsvRecords.csvSeparatorDescription')}
/>
updateField('quoteCharacter', val)}
- description={
- 'Enter the quote character used to quote the CSV input fields.'
- }
+ description={t(
+ 'findIncompleteCsvRecords.quoteCharacterDescription'
+ )}
/>
updateField('commentCharacter', val)}
- description={
- 'Enter the character indicating the start of a comment line. Lines starting with this symbol will be skipped.'
- }
+ description={t(
+ 'findIncompleteCsvRecords.commentCharacterDescription'
+ )}
/>
)
},
{
- title: 'Checking Options',
+ title: t('findIncompleteCsvRecords.checkingOptions'),
component: (
updateField('emptyLines', value)}
- title="Delete Lines with No Data"
- description="Remove empty lines from CSV input file."
+ title={t('findIncompleteCsvRecords.deleteLinesWithNoData')}
+ description={t(
+ 'findIncompleteCsvRecords.deleteLinesWithNoDataDescription'
+ )}
/>
updateField('emptyValues', value)}
- title="Find Empty Values"
- description="Display a message about CSV fields that are empty (These are not missing fields but fields that contain nothing)."
+ title={t('findIncompleteCsvRecords.findEmptyValues')}
+ description={t(
+ 'findIncompleteCsvRecords.findEmptyValuesDescription'
+ )}
/>
updateField('messageLimit', value)}
- title="Limit number of messages"
+ title={t('findIncompleteCsvRecords.limitNumberOfMessages')}
/>
{values.messageLimit && (
@@ -172,7 +176,9 @@ export default function FindIncompleteCsvRecords({
onOwnChange={(val) => updateField('messageNumber', Number(val))}
type="number"
inputProps={{ min: 1 }}
- description={'Set the limit of number of messages in the output.'}
+ description={t(
+ 'findIncompleteCsvRecords.messageLimitDescription'
+ )}
/>
)}
@@ -184,15 +190,27 @@ export default function FindIncompleteCsvRecords({
title={title}
input={input}
inputComponent={
-
+
+ }
+ resultComponent={
+
}
- resultComponent={ }
initialValues={initialValues}
exampleCards={exampleCards}
getGroups={getGroups}
setInput={setInput}
compute={compute}
- toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
+ toolInfo={{
+ title: t('findIncompleteCsvRecords.toolInfo.title', { title }),
+ description: longDescription
+ }}
/>
);
}
diff --git a/src/pages/tools/csv/find-incomplete-csv-records/meta.ts b/src/pages/tools/csv/find-incomplete-csv-records/meta.ts
index 8def95c..85b68a8 100644
--- a/src/pages/tools/csv/find-incomplete-csv-records/meta.ts
+++ b/src/pages/tools/csv/find-incomplete-csv-records/meta.ts
@@ -2,16 +2,16 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('csv', {
- name: 'Find incomplete CSV records',
path: 'find-incomplete-csv-records',
icon: 'tdesign:search-error',
- description:
- 'Just upload your CSV file in the form below and this tool will automatically check if none of the rows or columns are missing values. In the tool options, you can adjust the input file format (specify the delimiter, quote character, and comment character). Additionally, you can enable checking for empty values, skip empty lines, and set a limit on the number of error messages in the output.',
- shortDescription:
- 'Quickly find rows and columns in CSV that are missing values.',
+
keywords: ['find', 'incomplete', 'csv', 'records'],
- longDescription:
- 'This tool analyzes CSV files to identify incomplete records where data is missing. It checks both rows and columns for missing values and provides detailed reports on data quality issues. Useful for data validation and quality assurance.',
- userTypes: ['Developers'],
- component: lazy(() => import('./index'))
+
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'csv:findIncompleteCsvRecords.title',
+ description: 'csv:findIncompleteCsvRecords.description',
+ shortDescription: 'csv:findIncompleteCsvRecords.shortDescription',
+ userTypes: ['Developers']
+ }
});
diff --git a/src/pages/tools/csv/insert-csv-columns/index.tsx b/src/pages/tools/csv/insert-csv-columns/index.tsx
index db45420..055c13c 100644
--- a/src/pages/tools/csv/insert-csv-columns/index.tsx
+++ b/src/pages/tools/csv/insert-csv-columns/index.tsx
@@ -1,16 +1,17 @@
import { Box } from '@mui/material';
import React, { useState } from 'react';
import ToolContent from '@components/ToolContent';
-import { ToolComponentProps } from '@tools/defineTool';
import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
-import { GetGroupsType } from '@components/options/ToolOptions';
-import { CardExampleType } from '@components/examples/ToolExamples';
import { main } from './service';
-import { getCsvHeaders } from '@utils/csv';
import { InitialValuesType } from './types';
+import { GetGroupsType } from '@components/options/ToolOptions';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import SelectWithDesc from '@components/options/SelectWithDesc';
+import { CardExampleType } from '@components/examples/ToolExamples';
+import { ToolComponentProps } from '@tools/defineTool';
+import { getCsvHeaders } from '@utils/csv';
+import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
csvToInsert: '',
@@ -27,15 +28,19 @@ const initialValues: InitialValuesType = {
const exampleCards: CardExampleType[] = [
{
- title: 'Add One Column to a CSV File',
+ title: 'Insert a single column by position',
description:
- 'In this example, we insert a column with the title "city" into a CSV file that already contains two other columns with titles "name" and "age". The new column consists of three values: "city", "dallas", and "houston", corresponding to the height of the input CSV data. The value "city" is the header value (appearing on the first row) and values "dallas" and "houston" are data values (appearing on rows two and three). We specify the position of the new column by an ordinal number and set it to 1 in the options. This value indicates that the new "city" column should be placed after the first column.',
- sampleText: `name,age
-john,25
-emma,22`,
- sampleResult: `name,city,age
-john,dallas,25
-emma,houston,22`,
+ 'In this example, we insert a single column "city" at position 1 in the CSV data. The input CSV has data about cars, including the "Brand" and "Model" of the car. We now add a "city" column at position 1. To do this, we enter the city data in the comma-separated format in the "New Column" option, and to quickly add the new column at position 1, then we specify the position number.',
+ sampleText: `Brand,Model
+Toyota,Camry
+Ford,Mustang
+Honda,Accord
+Chevrolet,Malibu`,
+ sampleResult: `city,Brand,Model
+dallas,Toyota,Camry
+houston,Ford,Mustang
+dallas,Honda,Accord
+houston,Chevrolet,Malibu`,
sampleOptions: {
csvToInsert: `city
dallas
@@ -118,6 +123,7 @@ export default function InsertCsvColumns({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('csv');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -139,7 +145,7 @@ export default function InsertCsvColumns({
updateField
}) => [
{
- title: 'CSV to insert',
+ title: t('insertCsvColumns.csvToInsert'),
component: (
updateField('csvToInsert', val)}
- title="CSV separator"
- description={`Enter one or more columns you want to insert into the CSV.
- the character used to delimit columns has to be the same with the one in the CSV input file.
- Ps: Blank lines will be ignored`}
+ title={t('insertCsvColumns.csvSeparator')}
+ description={t('insertCsvColumns.csvToInsertDescription')}
/>
)
},
{
- title: 'CSV Options',
+ title: t('insertCsvColumns.csvOptions'),
component: (
updateField('separator', val)}
- description={
- 'Enter the character used to delimit columns in the CSV input file.'
- }
+ description={t('insertCsvColumns.separatorDescription')}
/>
updateField('quoteChar', val)}
- description={
- 'Enter the quote character used to quote the CSV input fields.'
- }
+ description={t('insertCsvColumns.quoteCharDescription')}
/>
updateField('commentCharacter', val)}
- description={
- 'Enter the character indicating the start of a comment line. Lines starting with this symbol will be skipped.'
- }
+ description={t('insertCsvColumns.commentCharacterDescription')}
/>
{
updateField('customFill', value);
@@ -192,48 +196,59 @@ export default function InsertCsvColumns({
updateField('customFillValue', ''); // Reset custom fill value
}
}}
- description={
- 'If the input CSV file is incomplete (missing values), then add empty fields or custom symbols to records to make a well-formed CSV?'
- }
+ description={t('insertCsvColumns.customFillDescription')}
/>
{values.customFill && (
updateField('customFillValue', val)}
- description={
- 'Use this custom value to fill in missing fields. (Works only with "Custom Values" mode above.)'
- }
+ description={t('insertCsvColumns.customFillValueDescription')}
/>
)}
)
},
{
- title: 'Position Options',
+ title: t('insertCsvColumns.positionOptions'),
component: (
updateField('insertingPosition', value)}
- description={'Specify where to insert the columns in the CSV file.'}
+ description={t('insertCsvColumns.insertingPositionDescription')}
/>
{values.insertingPosition === 'custom' && (
updateField('customPostionOptions', value)}
- description={
- 'Select the method to insert the columns in the CSV file.'
- }
+ description={t(
+ 'insertCsvColumns.customPositionOptionsDescription'
+ )}
/>
)}
@@ -243,42 +258,53 @@ export default function InsertCsvColumns({
selected={values.headerName}
options={headerOptions}
onChange={(value) => updateField('headerName', value)}
- description={
- 'Header of the column you want to insert columns after.'
- }
+ description={t('insertCsvColumns.headerNameDescription')}
/>
)}
{values.insertingPosition === 'custom' &&
values.customPostionOptions === 'rowNumber' && (
updateField('rowNumber', Number(val))}
- inputProps={{ min: 1, max: headers.length }}
- type="number"
- description={
- 'Number of the column you want to insert columns after.'
+ value={values.rowNumber.toString()}
+ onOwnChange={(val) =>
+ updateField('rowNumber', parseInt(val) || 0)
}
+ description={t('insertCsvColumns.rowNumberDescription')}
+ type="number"
/>
)}
)
}
];
+
return (
+
+ }
+ resultComponent={
+
}
- resultComponent={ }
initialValues={initialValues}
- exampleCards={exampleCards}
getGroups={getGroups}
- setInput={setInput}
compute={compute}
- toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
+ input={input}
+ setInput={setInput}
+ toolInfo={{
+ title: t('insertCsvColumns.toolInfo.title'),
+ description: t('insertCsvColumns.toolInfo.description')
+ }}
+ exampleCards={exampleCards}
/>
);
}
diff --git a/src/pages/tools/csv/insert-csv-columns/meta.ts b/src/pages/tools/csv/insert-csv-columns/meta.ts
index 71673e7..b7e18da 100644
--- a/src/pages/tools/csv/insert-csv-columns/meta.ts
+++ b/src/pages/tools/csv/insert-csv-columns/meta.ts
@@ -2,14 +2,16 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('csv', {
- name: 'Insert CSV columns',
+ i18n: {
+ name: 'csv:insertCsvColumns.title',
+ description: 'csv:insertCsvColumns.description',
+ shortDescription: 'csv:insertCsvColumns.shortDescription',
+ userTypes: ['Developers']
+ },
+
path: 'insert-csv-columns',
icon: 'hugeicons:column-insert',
- description:
- 'Just upload your CSV file in the form below, paste the new column in the options, and it will automatically get inserted in your CSV. In the tool options, you can also specify more than one column to insert, set the insertion position, and optionally skip the empty and comment lines.',
- shortDescription:
- 'Quickly insert one or more new columns anywhere in a CSV file.',
+
keywords: ['insert', 'csv', 'columns', 'append', 'prepend'],
- userTypes: ['Developers'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/csv/swap-csv-columns/meta.ts b/src/pages/tools/csv/swap-csv-columns/meta.ts
index 73eb88a..493f37c 100644
--- a/src/pages/tools/csv/swap-csv-columns/meta.ts
+++ b/src/pages/tools/csv/swap-csv-columns/meta.ts
@@ -2,14 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('csv', {
- name: 'Swap CSV Columns',
+ i18n: {
+ name: 'csv:swapCsvColumns.title',
+ description: 'csv:swapCsvColumns.description',
+ shortDescription: 'csv:swapCsvColumns.shortDescription',
+ longDescription: 'csv:swapCsvColumns.longDescription'
+ },
+
path: 'swap-csv-columns',
icon: 'eva:swap-outline',
- description:
- 'Just upload your CSV file in the form below, specify the columns to swap, and the tool will automatically change the positions of the specified columns in the output file. In the tool options, you can specify the column positions or names that you want to swap, as well as fix incomplete data and optionally remove empty records and records that have been commented out.',
- shortDescription: 'Reorder CSV columns.',
- longDescription:
- 'This tool reorganizes CSV data by swapping the positions of its columns. Swapping columns can enhance the readability of a CSV file by placing frequently used data together or in the front for easier data comparison and editing. For example, you can swap the first column with the last or swap the second column with the third. To swap columns based on their positions, select the "Set Column Position" mode and enter the numbers of the "from" and "to" columns to be swapped in the first and second blocks of options. For example, if you have a CSV file with four columns "1, 2, 3, 4" and swap columns with positions "2" and "4", the output CSV will have columns in the order: "1, 4, 3, 2".As an alternative to positions, you can swap columns by specifying their headers (column names on the first row of data). If you enable this mode in the options, then you can enter the column names like "location" and "city", and the program will swap these two columns. If any of the specified columns have incomplete data (some fields are missing), you can choose to skip such data or fill the missing fields with empty values or custom values (specified in the options). Additionally, you can specify the symbol used for comments in the CSV data, such as "#" or "//". If you do not need the commented lines in the output, you can remove them by using the "Delete Comments" checkbox. You can also activate the checkbox "Delete Empty Lines" to get rid of empty lines that contain no visible information. Csv-abulous!',
keywords: ['csv', 'swap', 'columns'],
userTypes: ['Developers'],
component: lazy(() => import('./index'))
diff --git a/src/pages/tools/csv/transpose-csv/meta.ts b/src/pages/tools/csv/transpose-csv/meta.ts
index ec023dc..c363516 100644
--- a/src/pages/tools/csv/transpose-csv/meta.ts
+++ b/src/pages/tools/csv/transpose-csv/meta.ts
@@ -2,15 +2,17 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('csv', {
- name: 'Transpose CSV',
+ i18n: {
+ name: 'csv:transposeCsv.title',
+ description: 'csv:transposeCsv.description',
+ shortDescription: 'csv:transposeCsv.shortDescription',
+ longDescription: 'csv:transposeCsv.longDescription',
+ userTypes: ['Developers']
+ },
+
path: 'transpose-csv',
icon: 'carbon:transpose',
- description:
- 'Just upload your CSV file in the form below, and this tool will automatically transpose your CSV. In the tool options, you can specify the character that starts the comment lines in the CSV to remove them. Additionally, if the CSV is incomplete (missing values), you can replace missing values with the empty character or a custom character.',
- shortDescription: 'Quickly transpose a CSV file.',
+
keywords: ['transpose', 'csv'],
- longDescription:
- 'This tool transposes Comma Separated Values (CSV). It treats the CSV as a matrix of data and flips all elements across the main diagonal. The output contains the same CSV data as the input, but now all the rows have become columns, and all the columns have become rows. After transposition, the CSV file will have opposite dimensions. For example, if the input file has 4 columns and 3 rows, the output file will have 3 columns and 4 rows. During conversion, the program also cleans the data from unnecessary lines and corrects incomplete data. Specifically, the tool automatically deletes all empty records and comments that begin with a specific character, which you can set in the option. Additionally, in cases where the CSV data is corrupted or lost, the utility completes the file with empty fields or custom fields that can be specified in the options. Csv-abulous!',
- userTypes: ['Developers'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/image/generic/change-colors/meta.ts b/src/pages/tools/image/generic/change-colors/meta.ts
index 287a327..6594fcc 100644
--- a/src/pages/tools/image/generic/change-colors/meta.ts
+++ b/src/pages/tools/image/generic/change-colors/meta.ts
@@ -2,12 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Change colors in image',
+ i18n: {
+ name: 'image:changeColors.title',
+ description: 'image:changeColors.description',
+ shortDescription: 'image:changeColors.shortDescription'
+ },
+
path: 'change-colors',
icon: 'cil:color-fill',
- description:
- "World's simplest online Image color changer. Just import your image (JPG, PNG, SVG) in the editor on the left, select which colors to change, and you'll instantly get a new image with the new colors on the right. Free, quick, and very powerful. Import an image โ replace its colors.",
- shortDescription: 'Quickly swap colors in a image',
+
keywords: ['change', 'colors', 'in', 'png', 'image', 'jpg'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/image/generic/change-opacity/meta.ts b/src/pages/tools/image/generic/change-opacity/meta.ts
index 81ef77f..a30cd99 100644
--- a/src/pages/tools/image/generic/change-opacity/meta.ts
+++ b/src/pages/tools/image/generic/change-opacity/meta.ts
@@ -2,12 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Change image Opacity',
+ i18n: {
+ name: 'image:changeOpacity.title',
+ description: 'image:changeOpacity.description',
+ shortDescription: 'image:changeOpacity.shortDescription'
+ },
+
path: 'change-opacity',
icon: 'material-symbols:opacity',
- description:
- 'Easily adjust the transparency of your images. Simply upload your image, use the slider to set the desired opacity level between 0 (fully transparent) and 1 (fully opaque), and download the modified image.',
- shortDescription: 'Adjust transparency of images',
+
keywords: ['opacity', 'transparency', 'png', 'alpha', 'jpg', 'jpeg', 'image'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/image/generic/compress/index.tsx b/src/pages/tools/image/generic/compress/index.tsx
index 1fa537c..fe9f9b0 100644
--- a/src/pages/tools/image/generic/compress/index.tsx
+++ b/src/pages/tools/image/generic/compress/index.tsx
@@ -1,4 +1,5 @@
import React, { useContext, useState } from 'react';
+import { useTranslation } from 'react-i18next';
import { InitialValuesType } from './types';
import { compressImage } from './service';
import ToolContent from '@components/ToolContent';
@@ -17,6 +18,7 @@ const initialValues: InitialValuesType = {
};
export default function CompressImage({ title }: ToolComponentProps) {
+ const { t } = useTranslation('image');
const [input, setInput] = useState(null);
const [result, setResult] = useState(null);
const [isProcessing, setIsProcessing] = useState(false);
@@ -37,7 +39,7 @@ export default function CompressImage({ title }: ToolComponentProps) {
setResult(compressed);
setCompressedSize(compressed.size);
} else {
- showSnackBar('Failed to compress image. Please try again.', 'error');
+ showSnackBar(t('compress.failedToCompress'), 'error');
}
} catch (err) {
console.error('Error in compression:', err);
@@ -55,12 +57,12 @@ export default function CompressImage({ title }: ToolComponentProps) {
value={input}
onChange={setInput}
accept={['image/*']}
- title={'Input image'}
+ title={t('compress.inputTitle')}
/>
}
resultComponent={
@@ -68,14 +70,14 @@ export default function CompressImage({ title }: ToolComponentProps) {
initialValues={initialValues}
getGroups={({ values, updateField }) => [
{
- title: 'Compression options',
+ title: t('compress.compressionOptions'),
component: (
updateNumberField(value, 'maxFileSizeInMB', updateField)
}
@@ -85,7 +87,7 @@ export default function CompressImage({ title }: ToolComponentProps) {
name="quality"
type="number"
inputProps={{ min: 10, max: 100, step: 1 }}
- description="Image quality percentage (lower means smaller file size)"
+ description={t('compress.qualityDescription')}
onOwnChange={(value) =>
updateNumberField(value, 'quality', updateField)
}
@@ -95,18 +97,20 @@ export default function CompressImage({ title }: ToolComponentProps) {
)
},
{
- title: 'File sizes',
+ title: t('compress.fileSizes'),
component: (
{originalSize !== null && (
- Original Size: {(originalSize / 1024).toFixed(2)} KB
+ {t('compress.originalSize')}:{' '}
+ {(originalSize / 1024).toFixed(2)} KB
)}
{compressedSize !== null && (
- Compressed Size: {(compressedSize / 1024).toFixed(2)} KB
+ {t('compress.compressedSize')}:{' '}
+ {(compressedSize / 1024).toFixed(2)} KB
)}
diff --git a/src/pages/tools/image/generic/compress/meta.ts b/src/pages/tools/image/generic/compress/meta.ts
index 7072153..29ace07 100644
--- a/src/pages/tools/image/generic/compress/meta.ts
+++ b/src/pages/tools/image/generic/compress/meta.ts
@@ -2,13 +2,16 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Compress Image',
+ i18n: {
+ name: 'image:compress.title',
+ description: 'image:compress.description',
+ shortDescription: 'image:compress.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ },
+
path: 'compress',
icon: 'material-symbols-light:compress-rounded',
- description:
- 'Reduce image file size while maintaining quality. Compress images for easier sharing, uploading, or storage.',
- shortDescription: 'Compress images to reduce file size',
- keywords: ['compress', 'image', 'reduce', 'size', 'optimize'],
- userTypes: ['General Users', 'Students', 'Developers'],
+
+ keywords: ['image', 'compress', 'reduce', 'quality'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/image/generic/convert-to-jpg/meta.ts b/src/pages/tools/image/generic/convert-to-jpg/meta.ts
index 7f4c548..05c76c4 100644
--- a/src/pages/tools/image/generic/convert-to-jpg/meta.ts
+++ b/src/pages/tools/image/generic/convert-to-jpg/meta.ts
@@ -2,12 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Convert Images to JPG',
+ i18n: {
+ name: 'image:convertToJpg.title',
+ description: 'image:convertToJpg.description',
+ shortDescription: 'image:convertToJpg.shortDescription'
+ },
+
path: 'convert-to-jpg',
icon: 'ph:file-jpg-thin',
- description:
- 'Convert various image formats (PNG, GIF, TIF, PSD, SVG, WEBP, HEIC, RAW) to JPG with customizable quality and background color settings.',
- shortDescription: 'Convert images to JPG with quality control',
+
keywords: [
'convert',
'jpg',
diff --git a/src/pages/tools/image/generic/create-transparent/meta.ts b/src/pages/tools/image/generic/create-transparent/meta.ts
index d606dfb..50fe18a 100644
--- a/src/pages/tools/image/generic/create-transparent/meta.ts
+++ b/src/pages/tools/image/generic/create-transparent/meta.ts
@@ -2,12 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Create transparent PNG',
+ i18n: {
+ name: 'image:createTransparent.title',
+ description: 'image:createTransparent.description',
+ shortDescription: 'image:createTransparent.shortDescription'
+ },
+
path: 'create-transparent',
icon: 'mdi:circle-transparent',
- shortDescription: 'Quickly make an image transparent',
- description:
- "World's simplest online Portable Network Graphics transparency maker. Just import your image in the editor on the left and you will instantly get a transparent PNG on the right. Free, quick, and very powerful. Import an image โ get a transparent PNG.",
+
keywords: ['create', 'transparent'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/image/generic/crop/meta.ts b/src/pages/tools/image/generic/crop/meta.ts
index 897eeeb..8f93b1d 100644
--- a/src/pages/tools/image/generic/crop/meta.ts
+++ b/src/pages/tools/image/generic/crop/meta.ts
@@ -2,11 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Crop',
+ i18n: {
+ name: 'image:crop.title',
+ description: 'image:crop.description',
+ shortDescription: 'image:crop.shortDescription'
+ },
+
path: 'crop',
icon: 'mdi:crop', // Iconify icon as a string
- description: 'A tool to crop images with precision and ease.',
- shortDescription: 'Crop images quickly.',
+
keywords: ['crop', 'image', 'edit', 'resize', 'trim'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/image/generic/editor/meta.ts b/src/pages/tools/image/generic/editor/meta.ts
index 2771325..b9e25d9 100644
--- a/src/pages/tools/image/generic/editor/meta.ts
+++ b/src/pages/tools/image/generic/editor/meta.ts
@@ -2,12 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Image Editor',
+ i18n: {
+ name: 'image:editor.title',
+ description: 'image:editor.description',
+ shortDescription: 'image:editor.shortDescription'
+ },
+
path: 'editor',
icon: 'mdi:image-edit',
- description:
- 'Advanced image editor with tools for cropping, rotating, annotating, adjusting colors, and adding watermarks. Edit your images with professional-grade tools directly in your browser.',
- shortDescription: 'Edit images with advanced tools and features',
+
keywords: [
'image',
'editor',
diff --git a/src/pages/tools/image/generic/image-to-text/meta.ts b/src/pages/tools/image/generic/image-to-text/meta.ts
index d35c89d..501023a 100644
--- a/src/pages/tools/image/generic/image-to-text/meta.ts
+++ b/src/pages/tools/image/generic/image-to-text/meta.ts
@@ -2,12 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Image to Text (OCR)',
+ i18n: {
+ name: 'image:imageToText.title',
+ description: 'image:imageToText.description',
+ shortDescription: 'image:imageToText.shortDescription'
+ },
+
path: 'image-to-text',
icon: 'mdi:text-recognition', // Iconify icon as a string
- description:
- 'Extract text from images (JPG, PNG) using optical character recognition (OCR).',
- shortDescription: 'Extract text from images using OCR.',
+
keywords: [
'ocr',
'optical character recognition',
diff --git a/src/pages/tools/image/generic/qr-code/meta.ts b/src/pages/tools/image/generic/qr-code/meta.ts
index 302e526..ee3ab35 100644
--- a/src/pages/tools/image/generic/qr-code/meta.ts
+++ b/src/pages/tools/image/generic/qr-code/meta.ts
@@ -2,12 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'QR Code Generator',
+ i18n: {
+ name: 'image:qrCode.title',
+ description: 'image:qrCode.description',
+ shortDescription: 'image:qrCode.shortDescription'
+ },
+
path: 'qr-code',
icon: 'mdi:qrcode', // Iconify icon as a string
- description:
- 'Generate QR codes for different data types: URL, Text, Email, Phone, SMS, WiFi, vCard, and more.',
- shortDescription: 'Create customized QR codes for various data formats.',
keywords: [
'qr code',
'qrcode',
diff --git a/src/pages/tools/image/generic/remove-background/meta.ts b/src/pages/tools/image/generic/remove-background/meta.ts
index fe13bbd..8bf12d0 100644
--- a/src/pages/tools/image/generic/remove-background/meta.ts
+++ b/src/pages/tools/image/generic/remove-background/meta.ts
@@ -2,12 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Remove Background from Image',
+ i18n: {
+ name: 'image:removeBackground.title',
+ description: 'image:removeBackground.description',
+ shortDescription: 'image:removeBackground.shortDescription'
+ },
+
path: 'remove-background',
icon: 'mdi:image-remove',
- description:
- "World's simplest online tool to remove backgrounds from images. Just upload your image and our AI-powered tool will automatically remove the background, giving you a transparent PNG. Perfect for product photos, profile pictures, and design assets.",
- shortDescription: 'Automatically remove backgrounds from images',
+
keywords: [
'remove',
'background',
diff --git a/src/pages/tools/image/generic/resize/index.tsx b/src/pages/tools/image/generic/resize/index.tsx
index f3df9f5..1e7d592 100644
--- a/src/pages/tools/image/generic/resize/index.tsx
+++ b/src/pages/tools/image/generic/resize/index.tsx
@@ -11,6 +11,7 @@ import SimpleRadio from '@components/options/SimpleRadio';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import { processImage } from './service';
import { InitialValuesType } from './types';
+import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
resizeMethod: 'pixels' as 'pixels' | 'percentage',
@@ -45,6 +46,7 @@ const validationSchema = Yup.object({
});
export default function ResizeImage({ title }: ToolComponentProps) {
+ const { t } = useTranslation('image');
const [input, setInput] = useState(null);
const [result, setResult] = useState(null);
@@ -58,22 +60,20 @@ export default function ResizeImage({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Resize Method',
+ title: t('resize.resizeMethod'),
component: (
updateField('resizeMethod', 'pixels')}
checked={values.resizeMethod === 'pixels'}
- description={'Resize by specifying dimensions in pixels.'}
- title={'Resize by Pixels'}
+ description={t('resize.resizeByPixelsDescription')}
+ title={t('resize.resizeByPixels')}
/>
updateField('resizeMethod', 'percentage')}
checked={values.resizeMethod === 'percentage'}
- description={
- 'Resize by specifying a percentage of the original size.'
- }
- title={'Resize by Percentage'}
+ description={t('resize.resizeByPercentageDescription')}
+ title={t('resize.resizeByPercentage')}
/>
)
@@ -81,7 +81,7 @@ export default function ResizeImage({ title }: ToolComponentProps) {
...(values.resizeMethod === 'pixels'
? [
{
- title: 'Dimension Type',
+ title: t('resize.dimensionType'),
component: (
updateField('maintainAspectRatio', value)
}
- description={
- 'Maintain the original aspect ratio of the image.'
- }
- title={'Maintain Aspect Ratio'}
+ description={t('resize.maintainAspectRatioDescription')}
+ title={t('resize.maintainAspectRatio')}
/>
{values.maintainAspectRatio && (
updateField('dimensionType', 'width')}
checked={values.dimensionType === 'width'}
- description={
- 'Specify the width in pixels and calculate height based on aspect ratio.'
- }
- title={'Set Width'}
+ description={t('resize.setWidthDescription')}
+ title={t('resize.setWidth')}
/>
updateField('dimensionType', 'height')}
checked={values.dimensionType === 'height'}
- description={
- 'Specify the height in pixels and calculate width based on aspect ratio.'
- }
- title={'Set Height'}
+ description={t('resize.setHeightDescription')}
+ title={t('resize.setHeight')}
/>
)}
updateField('width', val)}
- description={'Width (in pixels)'}
+ description={t('resize.widthDescription')}
disabled={
values.maintainAspectRatio &&
values.dimensionType === 'height'
@@ -131,7 +125,7 @@ export default function ResizeImage({ title }: ToolComponentProps) {
updateField('height', val)}
- description={'Height (in pixels)'}
+ description={t('resize.heightDescription')}
disabled={
values.maintainAspectRatio &&
values.dimensionType === 'width'
@@ -148,15 +142,13 @@ export default function ResizeImage({ title }: ToolComponentProps) {
]
: [
{
- title: 'Percentage',
+ title: t('resize.percentage'),
component: (
updateField('percentage', val)}
- description={
- 'Percentage of original size (e.g., 50 for half size, 200 for double size)'
- }
+ description={t('resize.percentageDescription')}
inputProps={{
'data-testid': 'percentage-input',
type: 'number',
@@ -183,20 +175,19 @@ export default function ResizeImage({ title }: ToolComponentProps) {
value={input}
onChange={setInput}
accept={['image/jpeg', 'image/png', 'image/svg+xml', 'image/gif']}
- title={'Input Image'}
+ title={t('resize.inputTitle')}
/>
}
resultComponent={
}
toolInfo={{
- title: 'Resize Image',
- description:
- 'This tool allows you to resize JPG, PNG, SVG, or GIF images. You can resize by specifying dimensions in pixels or by percentage, with options to maintain the original aspect ratio.'
+ title: t('resize.toolInfo.title'),
+ description: t('resize.toolInfo.description')
}}
/>
);
diff --git a/src/pages/tools/image/generic/resize/meta.ts b/src/pages/tools/image/generic/resize/meta.ts
index eccadf7..e7de178 100644
--- a/src/pages/tools/image/generic/resize/meta.ts
+++ b/src/pages/tools/image/generic/resize/meta.ts
@@ -2,13 +2,25 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Resize Image',
+ i18n: {
+ name: 'image:resize.title',
+ description: 'image:resize.description',
+ shortDescription: 'image:resize.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ },
+
path: 'resize',
- icon: 'mdi:resize',
- description:
- 'Resize images to different dimensions while maintaining aspect ratio or custom sizes.',
- shortDescription: 'Resize images to different dimensions',
- keywords: ['resize', 'image', 'dimensions', 'scale', 'aspect ratio'],
- userTypes: ['General Users', 'Students', 'Developers'],
+ icon: 'mdi:resize', // Iconify icon as a string
+
+ keywords: [
+ 'resize',
+ 'image',
+ 'scale',
+ 'jpg',
+ 'png',
+ 'svg',
+ 'gif',
+ 'dimensions'
+ ],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/image/generic/rotate/meta.ts b/src/pages/tools/image/generic/rotate/meta.ts
index bd1e7af..80e7d67 100644
--- a/src/pages/tools/image/generic/rotate/meta.ts
+++ b/src/pages/tools/image/generic/rotate/meta.ts
@@ -2,11 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('image-generic', {
- name: 'Rotate Image',
+ i18n: {
+ name: 'image:rotate.title',
+ description: 'image:rotate.description',
+ shortDescription: 'image:rotate.shortDescription'
+ },
+
path: 'rotate',
icon: 'mdi:rotate-clockwise',
- description: 'Rotate an image by a specified angle.',
- shortDescription: 'Rotate an image easily.',
+
keywords: ['rotate', 'image', 'angle', 'jpg', 'png'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/image/png/compress-png/meta.ts b/src/pages/tools/image/png/compress-png/meta.ts
index 4ed8009..224d20e 100644
--- a/src/pages/tools/image/png/compress-png/meta.ts
+++ b/src/pages/tools/image/png/compress-png/meta.ts
@@ -3,12 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('png', {
- name: 'Compress png',
+ i18n: {
+ name: 'image:compressPng.title',
+ description: 'image:compressPng.description',
+ shortDescription: 'image:compressPng.shortDescription'
+ },
+
path: 'compress-png',
icon: 'material-symbols-light:compress',
- description:
- 'This is a program that compresses PNG pictures. As soon as you paste your PNG picture in the input area, the program will compress it and show the result in the output area. In the options, you can adjust the compression level, as well as find the old and new picture file sizes.',
- shortDescription: 'Quickly compress a PNG',
+
keywords: ['compress', 'png'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/image/png/convert-jgp-to-png/meta.ts b/src/pages/tools/image/png/convert-jgp-to-png/meta.ts
index b7c8da7..8fe2fc4 100644
--- a/src/pages/tools/image/png/convert-jgp-to-png/meta.ts
+++ b/src/pages/tools/image/png/convert-jgp-to-png/meta.ts
@@ -2,12 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('png', {
- name: 'Convert JPG to PNG',
+ i18n: {
+ name: 'image:convertJgpToPng.title',
+ description: 'image:convertJgpToPng.description',
+ shortDescription: 'image:convertJgpToPng.shortDescription'
+ },
+
path: 'convert-jgp-to-png',
icon: 'ph:file-jpg-thin',
- description:
- 'Quickly convert your JPG images to PNG. Just import your PNG image in the editor on the left',
- shortDescription: 'Quickly convert your JPG images to PNG',
+
keywords: ['convert', 'jgp', 'png'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/json/escape-json/meta.ts b/src/pages/tools/json/escape-json/meta.ts
index 8059276..b527d6b 100644
--- a/src/pages/tools/json/escape-json/meta.ts
+++ b/src/pages/tools/json/escape-json/meta.ts
@@ -2,14 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('json', {
- name: 'Escape JSON',
path: 'escape-json',
- icon: 'lets-icons:json-light',
- description:
- 'Free online JSON escaper. Just load your JSON in the input field and it will automatically get escaped. In the tool options, you can optionally enable wrapping the escaped JSON in double quotes to get an escaped JSON string.',
- shortDescription: 'Quickly escape special JSON characters.',
- longDescription: `This tool converts special characters in JSON files and data structures into their escaped versions. Such special characters are, for example, double quotes, newline characters, backslashes, tabs, and many others. If these characters aren't escaped and appear in a raw JSON string without escaping, they can lead to errors in data parsing. The program turns them into safe versions by adding a backslash (\\) before the character, changing its interpretation. Additionally, you can enable the "Wrap Output in Quotes" checkbox in the options, which adds double quotes around the resulting escaped JSON data. This is useful when the escaped JSON data needs to be used as a string in other data structures or the JavaScript programming language. Json-abulous!`,
- keywords: ['escape', 'json'],
- userTypes: ['Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:code',
+
+ keywords: ['json', 'escape', 'characters', 'format'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'json:escapeJson.title',
+ description: 'json:escapeJson.description',
+ shortDescription: 'json:escapeJson.shortDescription',
+ userTypes: ['Developers']
+ }
});
diff --git a/src/pages/tools/json/index.ts b/src/pages/tools/json/index.ts
index 04a7940..9aba4f8 100644
--- a/src/pages/tools/json/index.ts
+++ b/src/pages/tools/json/index.ts
@@ -5,6 +5,7 @@ import { tool as validateJson } from './validateJson/meta';
import { tool as jsonToXml } from './json-to-xml/meta';
import { tool as escapeJson } from './escape-json/meta';
import { tool as tsvToJson } from './tsv-to-json/meta';
+import { tool as jsonComparison } from './json-comparison/meta';
export const jsonTools = [
validateJson,
@@ -13,5 +14,6 @@ export const jsonTools = [
jsonStringify,
jsonToXml,
escapeJson,
- tsvToJson
+ tsvToJson,
+ jsonComparison
];
diff --git a/src/pages/tools/json/json-comparison/index.tsx b/src/pages/tools/json/json-comparison/index.tsx
new file mode 100644
index 0000000..28a78ea
--- /dev/null
+++ b/src/pages/tools/json/json-comparison/index.tsx
@@ -0,0 +1,89 @@
+import { useEffect, useState } from 'react';
+import ToolContent from '@components/ToolContent';
+import ToolCodeInput from '@components/input/ToolCodeInput';
+import ToolTextResult from '@components/result/ToolTextResult';
+import { compareJson } from './service';
+import { ToolComponentProps } from '@tools/defineTool';
+import { Grid } from '@mui/material';
+
+type InitialValuesType = {};
+
+const initialValues: InitialValuesType = {};
+
+export default function JsonComparison({ title }: ToolComponentProps) {
+ const [input1, setInput1] = useState('');
+ const [input2, setInput2] = useState('');
+ const [result, setResult] = useState('');
+
+ useEffect(() => {
+ const compareInputs = () => {
+ try {
+ // Only compare if at least one input has content
+ if (input1.trim() || input2.trim()) {
+ const differences = compareJson(
+ input1 || '{}',
+ input2 || '{}',
+ 'text'
+ );
+ setResult(differences);
+ } else {
+ setResult('');
+ }
+ } catch (error) {
+ setResult(
+ `Error: ${
+ error instanceof Error ? error.message : 'Invalid JSON format'
+ }`
+ );
+ }
+ };
+
+ compareInputs();
+ }, [input1, input2]);
+
+ const handleInput1Change = (value: string | undefined) => {
+ setInput1(value ?? '');
+ };
+
+ const handleInput2Change = (value: string) => {
+ setInput2(value);
+ };
+
+ return (
+ {}}
+ inputComponent={
+
+
+
+
+
+
+
+
+
+
+
+ }
+ />
+ );
+}
diff --git a/src/pages/tools/json/json-comparison/meta.ts b/src/pages/tools/json/json-comparison/meta.ts
new file mode 100644
index 0000000..6172c31
--- /dev/null
+++ b/src/pages/tools/json/json-comparison/meta.ts
@@ -0,0 +1,15 @@
+import { defineTool } from '@tools/defineTool';
+import { lazy } from 'react';
+
+export const tool = defineTool('json', {
+ path: 'json-comparison',
+ icon: 'fluent:branch-compare-24-regular',
+ keywords: ['json', 'compare', 'diff', 'differences', 'match', 'validation'],
+ component: lazy(() => import('./index')),
+
+ i18n: {
+ name: 'json:comparison.title',
+ description: 'json:comparison.description',
+ shortDescription: 'json:comparison.shortDescription'
+ }
+});
diff --git a/src/pages/tools/json/json-comparison/service.test.ts b/src/pages/tools/json/json-comparison/service.test.ts
new file mode 100644
index 0000000..1e673ca
--- /dev/null
+++ b/src/pages/tools/json/json-comparison/service.test.ts
@@ -0,0 +1,64 @@
+import { compareJson } from './service';
+
+describe('compareJson', () => {
+ it('should identify missing properties', () => {
+ const json1 = '{"name": "John", "age": 30}';
+ const json2 = '{"name": "John"}';
+
+ expect(compareJson(json1, json2, 'text')).toContain(
+ 'age: Missing in second JSON'
+ );
+ });
+
+ it('should identify value mismatches', () => {
+ const json1 = '{"name": "John", "age": 30}';
+ const json2 = '{"name": "John", "age": 25}';
+
+ expect(compareJson(json1, json2, 'text')).toContain(
+ 'age: Mismatch: 30 != 25'
+ );
+ });
+
+ it('should handle nested objects', () => {
+ const json1 = '{"person": {"name": "John", "age": 30}}';
+ const json2 = '{"person": {"name": "Jane", "age": 30}}';
+
+ expect(compareJson(json1, json2, 'text')).toContain(
+ 'person.name: Mismatch: John != Jane'
+ );
+ });
+
+ it('should return JSON format when specified', () => {
+ const json1 = '{"name": "John", "age": 30}';
+ const json2 = '{"name": "Jane", "age": 25}';
+
+ const result = compareJson(json1, json2, 'json');
+ const parsed = JSON.parse(result);
+
+ expect(parsed).toHaveProperty('name');
+ expect(parsed).toHaveProperty('age');
+ });
+
+ it('should handle arrays', () => {
+ const json1 = '{"numbers": [1, 2, 3]}';
+ const json2 = '{"numbers": [1, 2, 4]}';
+
+ expect(compareJson(json1, json2, 'text')).toContain(
+ 'numbers.2: Mismatch: 3 != 4'
+ );
+ });
+
+ it('should return "No differences found" for identical JSONs', () => {
+ const json1 = '{"name": "John", "age": 30}';
+ const json2 = '{"name": "John", "age": 30}';
+
+ expect(compareJson(json1, json2, 'text')).toBe('No differences found');
+ });
+
+ it('should throw error for invalid JSON', () => {
+ const json1 = '{"name": "John"';
+ const json2 = '{"name": "John"}';
+
+ expect(() => compareJson(json1, json2, 'text')).toThrow();
+ });
+});
diff --git a/src/pages/tools/json/json-comparison/service.ts b/src/pages/tools/json/json-comparison/service.ts
new file mode 100644
index 0000000..6141971
--- /dev/null
+++ b/src/pages/tools/json/json-comparison/service.ts
@@ -0,0 +1,139 @@
+const fixTrailingCommas = (json: string): string => {
+ // Replace trailing commas in objects and arrays with proper JSON syntax
+ return json
+ .replace(/,\s*([}\]])/g, '$1') // Remove trailing commas in objects and arrays
+ .replace(/,\s*\n\s*([}\]])/g, '\n$1'); // Also handle when the closing bracket is on a new line
+};
+
+const tryParseJSON = (
+ json: string
+): { valid: boolean; data?: any; error?: string } => {
+ if (!json.trim()) {
+ return { valid: true, data: {} };
+ }
+
+ try {
+ // Try to parse after fixing trailing commas
+ const fixedJson = fixTrailingCommas(json);
+ const data = JSON.parse(fixedJson);
+ return { valid: true, data };
+ } catch (error) {
+ const errorMessage =
+ error instanceof SyntaxError ? error.message : 'Invalid JSON format';
+ // Extract line and column info from the error message if available
+ const match = errorMessage.match(/at line (\d+) column (\d+)/);
+ if (match) {
+ const [, line, column] = match;
+ return {
+ valid: false,
+ error: `${errorMessage}\nLocation: Line ${line}, Column ${column}`
+ };
+ }
+ return {
+ valid: false,
+ error: errorMessage
+ };
+ }
+};
+
+export const compareJson = (
+ json1: string,
+ json2: string,
+ format: 'text' | 'json'
+): string => {
+ // Handle empty inputs
+ if (!json1.trim() && !json2.trim()) return '';
+
+ // Parse both JSON inputs
+ const parsed1 = tryParseJSON(json1);
+ const parsed2 = tryParseJSON(json2);
+
+ // Handle parsing errors
+ if (!parsed1.valid || !parsed2.valid) {
+ const errors = [];
+ if (!parsed1.valid) {
+ errors.push(`First JSON: ${parsed1.error}`);
+ }
+ if (!parsed2.valid) {
+ errors.push(`Second JSON: ${parsed2.error}`);
+ }
+ throw new Error(errors.join('\n\n'));
+ }
+
+ // Compare the valid JSON objects
+ if (format === 'json') {
+ const diffs = findDifferencesJSON(parsed1.data, parsed2.data);
+ return JSON.stringify(diffs);
+ } else {
+ const differences = findDifferencesText(parsed1.data, parsed2.data);
+ if (differences.length === 0) {
+ return 'No differences found';
+ }
+ return differences.join('\n');
+ }
+};
+
+const findDifferencesText = (
+ obj1: any,
+ obj2: any,
+ path: string[] = []
+): string[] => {
+ const differences: string[] = [];
+ const processPath = (p: string[]): string =>
+ p.length ? p.join('.') : 'root';
+
+ // Compare all keys in obj1
+ for (const key in obj1) {
+ const currentPath = [...path, key];
+
+ if (!(key in obj2)) {
+ differences.push(`${processPath(currentPath)}: Missing in second JSON`);
+ continue;
+ }
+
+ const value1 = obj1[key];
+ const value2 = obj2[key];
+
+ if (
+ typeof value1 === 'object' &&
+ value1 !== null &&
+ typeof value2 === 'object' &&
+ value2 !== null
+ ) {
+ differences.push(...findDifferencesText(value1, value2, currentPath));
+ } else if (value1 !== value2) {
+ differences.push(
+ `${processPath(currentPath)}: Mismatch: ${value1} != ${value2}`
+ );
+ }
+ }
+
+ // Check for keys in obj2 that don't exist in obj1
+ for (const key in obj2) {
+ if (!(key in obj1)) {
+ const currentPath = [...path, key];
+ differences.push(`${processPath(currentPath)}: Missing in first JSON`);
+ }
+ }
+
+ return differences;
+};
+
+const findDifferencesJSON = (obj1: any, obj2: any): Record => {
+ const result: Record = {};
+
+ // Compare all properties
+ const allKeys = new Set([...Object.keys(obj1), ...Object.keys(obj2)]);
+
+ for (const key of allKeys) {
+ if (!(key in obj1)) {
+ result[key] = 'Missing in first JSON';
+ } else if (!(key in obj2)) {
+ result[key] = 'Missing in second JSON';
+ } else if (obj1[key] !== obj2[key]) {
+ result[key] = `Mismatch: ${obj1[key]} != ${obj2[key]}`;
+ }
+ }
+
+ return result;
+};
diff --git a/src/pages/tools/json/json-to-xml/meta.ts b/src/pages/tools/json/json-to-xml/meta.ts
index 7c94b74..eceecda 100644
--- a/src/pages/tools/json/json-to-xml/meta.ts
+++ b/src/pages/tools/json/json-to-xml/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('json', {
- name: 'Convert JSON to XML',
path: 'json-to-xml',
- icon: 'mdi-light:xml',
- description:
- 'Convert JSON data structures to XML format with customizable options for element naming, attributes, and output formatting.',
- shortDescription: 'Convert JSON data to XML format.',
- keywords: ['json', 'xml', 'convert', 'transform', 'parse'],
- userTypes: ['Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:code',
+
+ keywords: ['json', 'xml', 'convert', 'transform'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'json:jsonToXml.title',
+ description: 'json:jsonToXml.description',
+ shortDescription: 'json:jsonToXml.shortDescription',
+ userTypes: ['Developers']
+ }
});
diff --git a/src/pages/tools/json/minify/index.tsx b/src/pages/tools/json/minify/index.tsx
index bbe05e2..69c0646 100644
--- a/src/pages/tools/json/minify/index.tsx
+++ b/src/pages/tools/json/minify/index.tsx
@@ -5,6 +5,7 @@ import ToolTextResult from '@components/result/ToolTextResult';
import { minifyJson } from './service';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
+import { useTranslation } from 'react-i18next';
type InitialValuesType = Record;
@@ -47,6 +48,7 @@ const exampleCards: CardExampleType[] = [
];
export default function MinifyJson({ title }: ToolComponentProps) {
+ const { t } = useTranslation('json');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -58,11 +60,15 @@ export default function MinifyJson({ title }: ToolComponentProps) {
+
}
resultComponent={
@@ -70,9 +76,8 @@ export default function MinifyJson({ title }: ToolComponentProps) {
initialValues={initialValues}
getGroups={null}
toolInfo={{
- title: 'What Is JSON Minification?',
- description:
- "JSON minification is the process of removing all unnecessary whitespace characters from JSON data while maintaining its validity. This includes removing spaces, newlines, and indentation that aren't required for the JSON to be parsed correctly. Minification reduces the size of JSON data, making it more efficient for storage and transmission while keeping the exact same data structure and values."
+ title: t('minify.toolInfo.title'),
+ description: t('minify.toolInfo.description')
}}
exampleCards={exampleCards}
input={input}
diff --git a/src/pages/tools/json/minify/meta.ts b/src/pages/tools/json/minify/meta.ts
index c328e64..a4e5835 100644
--- a/src/pages/tools/json/minify/meta.ts
+++ b/src/pages/tools/json/minify/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('json', {
- name: 'Minify JSON',
path: 'minify',
- icon: 'lets-icons:json-light',
- description:
- 'Minify your JSON by removing all unnecessary whitespace and formatting. This tool compresses JSON data to its smallest possible size while maintaining valid JSON structure.',
- shortDescription: 'Quickly compress JSON file.',
- keywords: ['minify', 'compress', 'minimize', 'json', 'compact'],
- userTypes: ['Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:code',
+
+ keywords: ['json', 'minify', 'compress', 'whitespace'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'json:minify.title',
+ description: 'json:minify.description',
+ shortDescription: 'json:minify.shortDescription',
+ userTypes: ['Developers']
+ }
});
diff --git a/src/pages/tools/json/prettify/index.tsx b/src/pages/tools/json/prettify/index.tsx
index a85c973..c24b825 100644
--- a/src/pages/tools/json/prettify/index.tsx
+++ b/src/pages/tools/json/prettify/index.tsx
@@ -14,6 +14,7 @@ import RadioWithTextField from '@components/options/RadioWithTextField';
import SimpleRadio from '@components/options/SimpleRadio';
import { isNumber, updateNumberField } from '../../../../utils/string';
import ToolContent from '@components/ToolContent';
+import { useTranslation } from 'react-i18next';
type InitialValuesType = {
indentationType: 'tab' | 'space';
@@ -115,6 +116,7 @@ const exampleCards: CardExampleType[] = [
];
export default function PrettifyJson({ title }: ToolComponentProps) {
+ const { t } = useTranslation('json');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -128,11 +130,15 @@ export default function PrettifyJson({ title }: ToolComponentProps) {
title={title}
input={input}
inputComponent={
-
+
}
resultComponent={
@@ -140,14 +146,14 @@ export default function PrettifyJson({ title }: ToolComponentProps) {
initialValues={initialValues}
getGroups={({ values, updateField }) => [
{
- title: 'Indentation',
+ title: t('prettify.indentation'),
component: (
updateField('indentationType', 'space')}
onTextChange={(val) =>
@@ -157,8 +163,8 @@ export default function PrettifyJson({ title }: ToolComponentProps) {
updateField('indentationType', 'tab')}
checked={values.indentationType === 'tab'}
- description={'Indent output with tabs.'}
- title={'Use Tabs'}
+ description={t('prettify.useTabsDescription')}
+ title={t('prettify.useTabs')}
/>
)
@@ -168,9 +174,8 @@ export default function PrettifyJson({ title }: ToolComponentProps) {
setInput={setInput}
exampleCards={exampleCards}
toolInfo={{
- title: 'What Is a JSON Prettifier?',
- description:
- 'This tool adds consistent formatting to the data in JavaScript Object Notation (JSON) format. This transformation makes the JSON code more readable, making it easier to understand and edit. The program parses the JSON data structure into tokens and then reformats them by adding indentation and line breaks. If the data is hierarchial, then it adds indentation at the beginning of lines to visually show the depth of the JSON and adds newlines to break long single-line JSON arrays into multiple shorter, more readable ones. Additionally, this utility can remove unnecessary spaces and tabs from your JSON code (especially leading and trailing whitespaces), making it more compact. You can choose the line indentation method in the options: indent with spaces or indent with tabs. When using spaces, you can also specify how many spaces to use for each indentation level (usually 2 or 4 spaces). '
+ title: t('prettify.toolInfo.title'),
+ description: t('prettify.toolInfo.description')
}}
/>
);
diff --git a/src/pages/tools/json/prettify/meta.ts b/src/pages/tools/json/prettify/meta.ts
index 62ddd2d..d41b07d 100644
--- a/src/pages/tools/json/prettify/meta.ts
+++ b/src/pages/tools/json/prettify/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('json', {
- name: 'Prettify JSON',
path: 'prettify',
- icon: 'lets-icons:json-light',
- description:
- "Just load your JSON in the input field and it will automatically get prettified. In the tool options, you can choose whether to use spaces or tabs for indentation and if you're using spaces, you can specify the number of spaces to add per indentation level.",
- shortDescription: 'Quickly beautify a JSON data structure.',
- keywords: ['prettify'],
- userTypes: ['Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:code',
+
+ keywords: ['json', 'prettify', 'format', 'beautify'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'json:prettify.title',
+ description: 'json:prettify.description',
+ shortDescription: 'json:prettify.shortDescription',
+ userTypes: ['Developers']
+ }
});
diff --git a/src/pages/tools/json/stringify/meta.ts b/src/pages/tools/json/stringify/meta.ts
index 75d77ae..4d2c105 100644
--- a/src/pages/tools/json/stringify/meta.ts
+++ b/src/pages/tools/json/stringify/meta.ts
@@ -2,21 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('json', {
- name: 'Stringify JSON',
path: 'stringify',
- icon: 'ant-design:field-string-outlined',
- description:
- 'Convert JavaScript objects and arrays into their JSON string representation. Options include custom indentation and HTML character escaping for web-safe JSON strings.',
- shortDescription: 'Convert JavaScript objects to JSON strings',
- keywords: [
- 'stringify',
- 'serialize',
- 'convert',
- 'object',
- 'array',
- 'json',
- 'string'
- ],
- userTypes: ['Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:code',
+
+ keywords: ['json', 'stringify', 'serialize', 'convert'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'json:stringify.title',
+ description: 'json:stringify.description',
+ shortDescription: 'json:stringify.shortDescription',
+ userTypes: ['Developers']
+ }
});
diff --git a/src/pages/tools/json/tsv-to-json/meta.ts b/src/pages/tools/json/tsv-to-json/meta.ts
index e009c8a..415ed73 100644
--- a/src/pages/tools/json/tsv-to-json/meta.ts
+++ b/src/pages/tools/json/tsv-to-json/meta.ts
@@ -2,15 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('json', {
- name: 'Convert TSV to JSON',
path: 'tsv-to-json',
- icon: 'material-symbols:tsv-rounded',
- description:
- 'Convert TSV files to JSON format with customizable options for delimiters, quotes, and output formatting. Support for headers, comments, and dynamic type conversion.',
- shortDescription: 'Convert TSV data to JSON format.',
- longDescription:
- 'This tool allows you to convert TSV (Tab-Separated Values) files into JSON format. You can customize the conversion process by specifying delimiters, quote characters, and whether to use headers. It also supports dynamic type conversion for values, handling comments, and skipping empty lines. The output can be formatted with indentation or minified as needed.',
- keywords: ['tsv', 'json', 'convert', 'transform', 'parse'],
- userTypes: ['Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:code',
+
+ keywords: ['tsv', 'json', 'convert', 'tabular'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'json:tsvToJson.title',
+ description: 'json:tsvToJson.description',
+ shortDescription: 'json:tsvToJson.shortDescription',
+ userTypes: ['Developers']
+ }
});
diff --git a/src/pages/tools/json/validateJson/index.tsx b/src/pages/tools/json/validateJson/index.tsx
index 39333af..7642b59 100644
--- a/src/pages/tools/json/validateJson/index.tsx
+++ b/src/pages/tools/json/validateJson/index.tsx
@@ -5,6 +5,7 @@ import { CardExampleType } from '@components/examples/ToolExamples';
import { validateJson } from './service';
import { ToolComponentProps } from '@tools/defineTool';
import ToolContent from '@components/ToolContent';
+import { useTranslation } from 'react-i18next';
const exampleCards: CardExampleType<{}>[] = [
{
@@ -46,6 +47,7 @@ const exampleCards: CardExampleType<{}>[] = [
];
export default function ValidateJson({ title }: ToolComponentProps) {
+ const { t } = useTranslation('json');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -53,9 +55,9 @@ export default function ValidateJson({ title }: ToolComponentProps) {
const { valid, error } = validateJson(input);
if (valid) {
- setResult('โ
Valid JSON');
+ setResult(t('validateJson.validJson'));
} else {
- setResult(`โ ${error}`);
+ setResult(t('validateJson.invalidJson', { error }));
}
};
@@ -63,25 +65,20 @@ export default function ValidateJson({ title }: ToolComponentProps) {
+
}
resultComponent={
-
+
}
initialValues={{}}
getGroups={null}
toolInfo={{
- title: 'What is JSON Validation?',
- description: `
- JSON (JavaScript Object Notation) is a lightweight data-interchange format.
- JSON validation ensures that the structure of the data conforms to the JSON standard.
- A valid JSON object must have:
- - Property names enclosed in double quotes.
- - Properly balanced curly braces {}.
- - No trailing commas after the last key-value pair.
- - Proper nesting of objects and arrays.
- This tool checks the input JSON and provides feedback to help identify and fix common errors.
- `
+ title: t('validateJson.toolInfo.title'),
+ description: t('validateJson.toolInfo.description')
}}
exampleCards={exampleCards}
input={input}
diff --git a/src/pages/tools/json/validateJson/meta.ts b/src/pages/tools/json/validateJson/meta.ts
index 2eb0816..c103755 100644
--- a/src/pages/tools/json/validateJson/meta.ts
+++ b/src/pages/tools/json/validateJson/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('json', {
- name: 'Validate JSON',
path: 'validateJson',
- icon: 'lets-icons:json-light',
- description:
- 'Validate JSON data for syntax errors and structural correctness. This tool helps ensure your JSON is properly formatted and valid.',
- shortDescription: 'Validate JSON syntax and structure',
- keywords: ['validate', 'json', 'syntax', 'check', 'verify'],
- userTypes: ['Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:check-circle',
+
+ keywords: ['json', 'validate', 'check', 'syntax', 'errors'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'json:validateJson.title',
+ description: 'json:validateJson.description',
+ shortDescription: 'json:validateJson.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/list/duplicate/index.tsx b/src/pages/tools/list/duplicate/index.tsx
index 9e4f50c..d12b372 100644
--- a/src/pages/tools/list/duplicate/index.tsx
+++ b/src/pages/tools/list/duplicate/index.tsx
@@ -11,6 +11,7 @@ import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import SimpleRadio from '@components/options/SimpleRadio';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import * as Yup from 'yup';
+import { useTranslation } from 'react-i18next';
interface InitialValuesType {
splitOperatorType: SplitOperatorType;
@@ -101,6 +102,7 @@ const exampleCards: CardExampleType[] = [
];
export default function Duplicate({ title }: ToolComponentProps) {
+ const { t } = useTranslation('list');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -121,9 +123,9 @@ export default function Duplicate({ title }: ToolComponentProps) {
);
} catch (error) {
if (error instanceof Error) {
- setResult(`Error: ${error.message}`);
+ setResult(`${t('duplicate.error')}: ${error.message}`);
} else {
- setResult('An unknown error occurred');
+ setResult(t('duplicate.unknownError'));
}
}
}
@@ -134,55 +136,53 @@ export default function Duplicate({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Split Options',
+ title: t('duplicate.splitOptions'),
component: (
updateField('splitOperatorType', 'symbol')}
checked={values.splitOperatorType === 'symbol'}
- title={'Split by Symbol'}
+ title={t('duplicate.splitBySymbol')}
/>
updateField('splitOperatorType', 'regex')}
checked={values.splitOperatorType === 'regex'}
- title={'Split by Regular Expression'}
+ title={t('duplicate.splitByRegex')}
/>
updateField('splitSeparator', val)}
- description={'Separator to split the list'}
+ description={t('duplicate.splitSeparatorDescription')}
/>
updateField('joinSeparator', val)}
- description={'Separator to join the duplicated list'}
+ description={t('duplicate.joinSeparatorDescription')}
/>
)
},
{
- title: 'Duplication Options',
+ title: t('duplicate.duplicationOptions'),
component: (
updateField('copy', val)}
- description={'Number of copies (can be fractional)'}
+ description={t('duplicate.copyDescription')}
type="number"
/>
updateField('concatenate', checked)}
- description={
- 'Concatenate copies (if unchecked, items will be interweaved)'
- }
+ description={t('duplicate.concatenateDescription')}
/>
updateField('reverse', checked)}
- description={'Reverse the duplicated items'}
+ description={t('duplicate.reverseDescription')}
/>
)
@@ -193,18 +193,21 @@ export default function Duplicate({ title }: ToolComponentProps) {
+
}
resultComponent={
-
+
}
initialValues={initialValues}
getGroups={getGroups}
validationSchema={validationSchema}
toolInfo={{
- title: 'List Duplication',
- description:
- "This tool allows you to duplicate items in a list. You can specify the number of copies (including fractional values), control whether items are concatenated or interweaved, and even reverse the duplicated items. It's useful for creating repeated patterns, generating test data, or expanding lists with predictable content."
+ title: t('duplicate.toolInfo.title'),
+ description: t('duplicate.toolInfo.description')
}}
exampleCards={exampleCards}
input={input}
diff --git a/src/pages/tools/list/duplicate/meta.ts b/src/pages/tools/list/duplicate/meta.ts
index 1aaee4c..5a5a6d7 100644
--- a/src/pages/tools/list/duplicate/meta.ts
+++ b/src/pages/tools/list/duplicate/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('list', {
- name: 'Duplicate',
path: 'duplicate',
- icon: 'mdi:content-duplicate',
- description:
- 'A tool to duplicate each item in a list a specified number of times. Perfect for creating repeated patterns, test data, or expanding datasets.',
- shortDescription: 'Repeat items in a list multiple times.',
+ icon: 'material-symbols-light:content-copy',
+
keywords: ['duplicate'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'list:duplicate.title',
+ description: 'list:duplicate.description',
+ shortDescription: 'list:duplicate.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/list/find-most-popular/index.tsx b/src/pages/tools/list/find-most-popular/index.tsx
index 7e2f597..47b447f 100644
--- a/src/pages/tools/list/find-most-popular/index.tsx
+++ b/src/pages/tools/list/find-most-popular/index.tsx
@@ -1,5 +1,6 @@
import { Box } from '@mui/material';
import React, { useState } from 'react';
+import { useTranslation } from 'react-i18next';
import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
import {
@@ -14,6 +15,7 @@ import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import SelectWithDesc from '@components/options/SelectWithDesc';
import ToolContent from '@components/ToolContent';
import { ToolComponentProps } from '@tools/defineTool';
+import { ParseKeys } from 'i18next';
const initialValues = {
splitSeparatorType: 'symbol' as SplitOperatorType,
@@ -25,23 +27,24 @@ const initialValues = {
trimItems: false
};
const splitOperators: {
- title: string;
- description: string;
+ title: ParseKeys<'list'>;
+ description: ParseKeys<'list'>;
type: SplitOperatorType;
}[] = [
{
- title: 'Use a Symbol for Splitting',
- description: 'Delimit input list items with a character.',
+ title: 'findMostPopular.splitOperators.symbol.title',
+ description: 'findMostPopular.splitOperators.symbol.description',
type: 'symbol'
},
{
- title: 'Use a Regex for Splitting',
+ title: 'findMostPopular.splitOperators.regex.title',
type: 'regex',
- description: 'Delimit input list items with a regular expression.'
+ description: 'findMostPopular.splitOperators.regex.description'
}
];
export default function FindMostPopular({ title }: ToolComponentProps) {
+ const { t } = useTranslation('list');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
const compute = (optionsValues: typeof initialValues, input: any) => {
@@ -74,28 +77,35 @@ export default function FindMostPopular({ title }: ToolComponentProps) {
title={title}
input={input}
inputComponent={
-
+
}
resultComponent={
-
+
}
initialValues={initialValues}
getGroups={({ values, updateField }) => [
{
- title: 'How to Extract List Items?',
+ title: t('findMostPopular.extractListItems'),
component: (
{splitOperators.map(({ title, description, type }) => (
updateField('splitSeparatorType', type)}
- title={title}
- description={description}
+ title={t(title)}
+ description={t(description)}
checked={values.splitSeparatorType === type}
/>
))}
updateField('splitSeparator', val)}
/>
@@ -103,26 +113,24 @@ export default function FindMostPopular({ title }: ToolComponentProps) {
)
},
{
- title: 'Item comparison',
+ title: t('findMostPopular.itemComparison'),
component: (
updateField('deleteEmptyItems', value)}
/>
updateField('trimItems', value)}
/>
updateField('ignoreItemCase', value)}
/>
@@ -130,27 +138,42 @@ export default function FindMostPopular({ title }: ToolComponentProps) {
)
},
{
- title: 'Top item output format',
+ title: t('findMostPopular.outputFormat'),
component: (
updateField('displayFormat', value)}
- description={'How to display the most popular list items?'}
+ description={t('findMostPopular.displayFormatDescription')}
/>
updateField('sortingMethod', value)}
- description={'Select a sorting method.'}
+ description={t('findMostPopular.sortingMethodDescription')}
/>
)
diff --git a/src/pages/tools/list/find-most-popular/meta.ts b/src/pages/tools/list/find-most-popular/meta.ts
index bf6a1f4..59cc36b 100644
--- a/src/pages/tools/list/find-most-popular/meta.ts
+++ b/src/pages/tools/list/find-most-popular/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('list', {
- name: 'Find most popular',
path: 'find-most-popular',
- icon: 'material-symbols-light:query-stats',
- description:
- 'A tool to identify and count the most frequently occurring items in a list. Useful for data analysis, finding trends, or identifying common elements.',
- shortDescription: 'Find most common items in a list.',
+ icon: 'material-symbols-light:trending-up',
+
keywords: ['find', 'most', 'popular'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'list:findMostPopular.title',
+ description: 'list:findMostPopular.description',
+ shortDescription: 'list:findMostPopular.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/list/find-unique/index.tsx b/src/pages/tools/list/find-unique/index.tsx
index b5ef4b9..89af8da 100644
--- a/src/pages/tools/list/find-unique/index.tsx
+++ b/src/pages/tools/list/find-unique/index.tsx
@@ -7,6 +7,7 @@ import { findUniqueCompute, SplitOperatorType } from './service';
import SimpleRadio from '@components/options/SimpleRadio';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
+import { useTranslation } from 'react-i18next';
const initialValues = {
splitOperatorType: 'symbol' as SplitOperatorType,
@@ -35,6 +36,7 @@ const splitOperators: {
];
export default function FindUnique() {
+ const { t } = useTranslation('list');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
const compute = (optionsValues: typeof initialValues, input: any) => {
@@ -64,18 +66,24 @@ export default function FindUnique() {
return (
+
+ }
+ resultComponent={
+
}
- resultComponent={ }
getGroups={({ values, updateField }) => [
{
- title: 'Input List Delimiter',
+ title: t('findUnique.inputListDelimiter'),
component: (
{splitOperators.map(({ title, description, type }) => (
@@ -88,7 +96,7 @@ export default function FindUnique() {
/>
))}
updateField('splitSeparator', val)}
/>
@@ -96,7 +104,7 @@ export default function FindUnique() {
)
},
{
- title: 'Output List Delimiter',
+ title: t('findUnique.outputListDelimiter'),
component: (
updateField('joinSeparator', value)}
/>
updateField('trimItems', value)}
/>
updateField('deleteEmptyItems', value)}
/>
@@ -123,22 +127,20 @@ export default function FindUnique() {
)
},
{
- title: 'Unique Item Options',
+ title: t('findUnique.uniqueItemOptions'),
component: (
updateField('absolutelyUnique', value)}
/>
updateField('caseSensitive', value)}
/>
diff --git a/src/pages/tools/list/find-unique/meta.ts b/src/pages/tools/list/find-unique/meta.ts
index ce1c3ce..05826a4 100644
--- a/src/pages/tools/list/find-unique/meta.ts
+++ b/src/pages/tools/list/find-unique/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('list', {
- name: 'Find unique',
path: 'find-unique',
- icon: 'mynaui:one',
- description:
- "World's simplest browser-based utility for finding unique items in a list. Just input your list with any separator, and it will automatically identify and extract unique items. Perfect for removing duplicates, finding distinct values, or analyzing data uniqueness. You can customize the input/output separators and choose whether to preserve the original order.",
- shortDescription: 'Find unique items in a list',
+ icon: 'material-symbols-light:search',
+
keywords: ['find', 'unique'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'list:findUnique.title',
+ description: 'list:findUnique.description',
+ shortDescription: 'list:findUnique.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/list/group/index.tsx b/src/pages/tools/list/group/index.tsx
index e7f70e6..84377be 100644
--- a/src/pages/tools/list/group/index.tsx
+++ b/src/pages/tools/list/group/index.tsx
@@ -9,6 +9,7 @@ import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import { formatNumber } from '../../../../utils/number';
import ToolContent from '@components/ToolContent';
import { ToolComponentProps } from '@tools/defineTool';
+import { useTranslation } from 'react-i18next';
const initialValues = {
splitOperatorType: 'symbol' as SplitOperatorType,
@@ -40,6 +41,7 @@ const splitOperators: {
];
export default function FindUnique({ title }: ToolComponentProps) {
+ const { t } = useTranslation('list');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
const compute = (optionsValues: typeof initialValues, input: any) => {
@@ -78,28 +80,32 @@ export default function FindUnique({ title }: ToolComponentProps) {
title={title}
input={input}
inputComponent={
-
+
}
resultComponent={
-
+
}
initialValues={initialValues}
getGroups={({ values, updateField }) => [
{
- title: 'Input Item Separator',
+ title: t('group.inputItemSeparator'),
component: (
{splitOperators.map(({ title, description, type }) => (
updateField('splitOperatorType', type)}
- title={title}
- description={description}
+ title={t(`group.splitOperators.${type}.title`)}
+ description={t(`group.splitOperators.${type}.description`)}
checked={values.splitOperatorType === type}
/>
))}
updateField('splitSeparator', val)}
/>
@@ -107,12 +113,12 @@ export default function FindUnique({ title }: ToolComponentProps) {
)
},
{
- title: 'Group Size and Separators',
+ title: t('group.groupSizeAndSeparators'),
component: (
updateField('groupNumber', formatNumber(value, 1))
@@ -120,52 +126,46 @@ export default function FindUnique({ title }: ToolComponentProps) {
/>
updateField('itemSeparator', value)}
/>
updateField('groupSeparator', value)}
/>
updateField('leftWrap', value)}
/>
updateField('rightWrap', value)}
/>
)
},
{
- title: 'Empty Items and Padding',
+ title: t('group.emptyItemsAndPadding'),
component: (
updateField('deleteEmptyItems', value)}
/>
updateField('padNonFullGroup', value)}
/>
updateField('paddingChar', value)}
/>
diff --git a/src/pages/tools/list/group/meta.ts b/src/pages/tools/list/group/meta.ts
index 0228088..9ea4cf4 100644
--- a/src/pages/tools/list/group/meta.ts
+++ b/src/pages/tools/list/group/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('list', {
- name: 'Group Items',
path: 'group',
icon: 'pajamas:group',
- description:
- "World's simplest browser-based utility for grouping list items. Input your list and specify grouping criteria to organize items into logical groups. Perfect for categorizing data, organizing information, or creating structured lists. Supports custom separators and various grouping options.",
- shortDescription: 'Group list items by common properties',
+
keywords: ['group'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'list:group.title',
+ description: 'list:group.description',
+ shortDescription: 'list:group.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/list/reverse/index.tsx b/src/pages/tools/list/reverse/index.tsx
index 9de94f8..0a6e5f9 100644
--- a/src/pages/tools/list/reverse/index.tsx
+++ b/src/pages/tools/list/reverse/index.tsx
@@ -9,6 +9,7 @@ import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
import ToolContent from '@components/ToolContent';
+import { useTranslation } from 'react-i18next';
const initialValues = {
splitOperatorType: 'symbol' as SplitOperatorType,
@@ -111,6 +112,7 @@ argument`,
];
export default function Reverse({ title }: ToolComponentProps) {
+ const { t } = useTranslation('list');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -119,15 +121,15 @@ export default function Reverse({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Splitter Mode',
+ title: t('reverse.splitterMode'),
component: (
{splitOperators.map(({ title, description, type }) => (
updateField('splitOperatorType', type)}
- title={title}
- description={description}
+ title={t(`reverse.splitOperators.${type}.title`)}
+ description={t(`reverse.splitOperators.${type}.description`)}
checked={values.splitOperatorType === type}
/>
))}
@@ -135,11 +137,11 @@ export default function Reverse({ title }: ToolComponentProps) {
)
},
{
- title: 'Item Separator',
+ title: t('reverse.itemSeparator'),
component: (
updateField('splitSeparator', val)}
/>
@@ -147,11 +149,11 @@ export default function Reverse({ title }: ToolComponentProps) {
)
},
{
- title: 'Output List Options',
+ title: t('reverse.outputListOptions'),
component: (
updateField('joinSeparator', val)}
/>
@@ -176,15 +178,18 @@ export default function Reverse({ title }: ToolComponentProps) {
input={input}
setInput={setInput}
inputComponent={
-
+
}
resultComponent={
-
+
}
toolInfo={{
- title: 'What Is a List Reverser?',
- description:
- 'With this utility, you can reverse the order of items in a list. The utility first splits the input list into individual items and then iterates through them from the last item to the first item, printing each item to the output during the iteration. The input list may contain anything that can be represented as textual data, which includes digits, numbers, strings, words, sentences, etc. The input item separator can also be a regular expression. For example, the regex /[;,]/ will allow you to use items that are either comma- or semicolon-separated. The input and output list items delimiters can be customized in the options. By default, both input and output lists are comma-separated. Listabulous!'
+ title: t('reverse.toolInfo.title'),
+ description: t('reverse.toolInfo.description')
}}
exampleCards={exampleCards}
/>
diff --git a/src/pages/tools/list/reverse/meta.ts b/src/pages/tools/list/reverse/meta.ts
index 76c8bd3..45d519b 100644
--- a/src/pages/tools/list/reverse/meta.ts
+++ b/src/pages/tools/list/reverse/meta.ts
@@ -3,13 +3,14 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('list', {
- name: 'Reverse list',
path: 'reverse',
icon: 'proicons:reverse',
- description:
- 'This is a super simple browser-based application prints all list items in reverse. The input items can be separated by any symbol and you can also change the separator of the reversed list items.',
- shortDescription: 'Quickly reverse a list',
keywords: ['reverse'],
- userTypes: ['General Users', 'Students'],
+ i18n: {
+ name: 'list:reverse.title',
+ description: 'list:reverse.description',
+ shortDescription: 'list:reverse.shortDescription',
+ userTypes: ['General Users', 'Students']
+ },
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/list/rotate/meta.ts b/src/pages/tools/list/rotate/meta.ts
index 8ba1bc9..6fe6579 100644
--- a/src/pages/tools/list/rotate/meta.ts
+++ b/src/pages/tools/list/rotate/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('list', {
- name: 'Rotate list',
path: 'rotate',
icon: 'material-symbols-light:rotate-right',
- description:
- 'A tool to rotate items in a list by a specified number of positions. Shift elements left or right while maintaining their relative order.',
- shortDescription: 'Shift list items by position.',
+
keywords: ['rotate'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'list:rotate.title',
+ description: 'list:rotate.description',
+ shortDescription: 'list:rotate.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/list/shuffle/index.tsx b/src/pages/tools/list/shuffle/index.tsx
index 47f0d7e..34e110c 100644
--- a/src/pages/tools/list/shuffle/index.tsx
+++ b/src/pages/tools/list/shuffle/index.tsx
@@ -7,6 +7,7 @@ import { shuffleList, SplitOperatorType } from './service';
import SimpleRadio from '@components/options/SimpleRadio';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import { isNumber } from '@utils/string';
+import { useTranslation } from 'react-i18next';
const initialValues = {
splitOperatorType: 'symbol' as SplitOperatorType,
@@ -32,6 +33,7 @@ const splitOperators: {
];
export default function Shuffle() {
+ const { t } = useTranslation('list');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
const compute = (optionsValues: typeof initialValues, input: any) => {
@@ -51,20 +53,24 @@ export default function Shuffle() {
return (
+
}
resultComponent={
-
+
}
getGroups={({ values, updateField }) => [
{
- title: 'Input list separator',
+ title: t('shuffle.inputListSeparator'),
component: (
{splitOperators.map(({ title, description, type }) => (
@@ -77,7 +83,7 @@ export default function Shuffle() {
/>
))}
updateField('splitSeparator', val)}
/>
@@ -85,11 +91,11 @@ export default function Shuffle() {
)
},
{
- title: 'Shuffled List Length',
+ title: t('shuffle.shuffledListLength'),
component: (
updateField('length', val)}
/>
@@ -97,13 +103,13 @@ export default function Shuffle() {
)
},
{
- title: 'Shuffled List Separator',
+ title: t('shuffle.shuffledListSeparator'),
component: (
updateField('joinSeparator', value)}
- description={'Use this separator in the randomized list.'}
+ description={t('shuffle.joinSeparatorDescription')}
/>
)
diff --git a/src/pages/tools/list/shuffle/meta.ts b/src/pages/tools/list/shuffle/meta.ts
index 6359860..579c88c 100644
--- a/src/pages/tools/list/shuffle/meta.ts
+++ b/src/pages/tools/list/shuffle/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('list', {
- name: 'Shuffle list',
path: 'shuffle',
icon: 'material-symbols-light:shuffle',
- description:
- 'A tool to randomly reorder items in a list. Perfect for randomizing data, creating random selections, or generating random sequences.',
- shortDescription: 'Randomly reorder list items.',
+
keywords: ['shuffle'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'list:shuffle.title',
+ description: 'list:shuffle.description',
+ shortDescription: 'list:shuffle.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/list/sort/index.tsx b/src/pages/tools/list/sort/index.tsx
index 81e4414..1567e81 100644
--- a/src/pages/tools/list/sort/index.tsx
+++ b/src/pages/tools/list/sort/index.tsx
@@ -9,6 +9,7 @@ import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import SelectWithDesc from '@components/options/SelectWithDesc';
import ToolContent from '@components/ToolContent';
import { ToolComponentProps } from '@tools/defineTool';
+import { useTranslation } from 'react-i18next';
const initialValues = {
splitSeparatorType: 'symbol' as SplitOperatorType,
@@ -36,7 +37,8 @@ const splitOperators: {
}
];
-export default function SplitText({ title }: ToolComponentProps) {
+export default function SortList({ title }: ToolComponentProps) {
+ const { t } = useTranslation('list');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
const compute = (optionsValues: typeof initialValues, input: any) => {
@@ -69,26 +71,32 @@ export default function SplitText({ title }: ToolComponentProps) {
title={title}
input={input}
inputComponent={
-
+
+ }
+ resultComponent={
+
}
- resultComponent={ }
initialValues={initialValues}
getGroups={({ values, updateField }) => [
{
- title: 'Input item separator',
+ title: t('sort.inputItemSeparator'),
component: (
{splitOperators.map(({ title, description, type }) => (
updateField('splitSeparatorType', type)}
- title={title}
- description={description}
+ title={t(`sort.splitOperators.${type}.title`)}
+ description={t(`sort.splitOperators.${type}.description`)}
checked={values.splitSeparatorType === type}
/>
))}
updateField('splitSeparator', val)}
/>
@@ -96,35 +104,45 @@ export default function SplitText({ title }: ToolComponentProps) {
)
},
{
- title: 'Sort method',
+ title: t('sort.sortMethod'),
component: (
updateField('sortingMethod', value)}
- description={'Select a sorting method.'}
+ description={t('sort.sortMethodDescription')}
/>
{
updateField('increasing', value);
}}
- description={'Select a sorting order.'}
+ description={t('sort.orderDescription')}
/>
updateField('caseSensitive', val)}
/>
@@ -132,19 +150,17 @@ export default function SplitText({ title }: ToolComponentProps) {
)
},
{
- title: 'Sorted item properties',
+ title: t('sort.sortedItemProperties'),
component: (
updateField('joinSeparator', val)}
/>
updateField('removeDuplicated', val)}
/>
diff --git a/src/pages/tools/list/sort/meta.ts b/src/pages/tools/list/sort/meta.ts
index e2fddd3..36525c5 100644
--- a/src/pages/tools/list/sort/meta.ts
+++ b/src/pages/tools/list/sort/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('list', {
- name: 'Sort list',
path: 'sort',
- icon: 'basil:sort-outline',
- description:
- 'This is a super simple browser-based application that sorts items in a list and arranges them in increasing or decreasing order. You can sort the items alphabetically, numerically, or by their length. You can also remove duplicate and empty items, as well as trim individual items that have whitespace around them. You can use any separator character to separate the input list items or alternatively use a regular expression to separate them. Additionally, you can create a new delimiter for the sorted output list.',
- shortDescription: 'Quickly sort a list',
+ icon: 'material-symbols-light:sort',
+
keywords: ['sort'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'list:sort.title',
+ description: 'list:sort.description',
+ shortDescription: 'list:sort.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/list/truncate/meta.ts b/src/pages/tools/list/truncate/meta.ts
index bc01537..103c9fe 100644
--- a/src/pages/tools/list/truncate/meta.ts
+++ b/src/pages/tools/list/truncate/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('list', {
- name: 'Truncate list',
path: 'truncate',
- shortDescription: 'Truncate a list to a specified number of items',
- icon: 'material-symbols-light:short-text',
- description:
- 'Truncate a list to keep only the first N items or remove items beyond a certain limit.',
- keywords: ['truncate', 'list', 'limit', 'cut'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols-light:content-cut',
+
+ keywords: ['truncate'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'list:truncate.title',
+ description: 'list:truncate.description',
+ shortDescription: 'list:truncate.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/list/unwrap/meta.ts b/src/pages/tools/list/unwrap/meta.ts
index edbf0cf..f9d543c 100644
--- a/src/pages/tools/list/unwrap/meta.ts
+++ b/src/pages/tools/list/unwrap/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('list', {
- name: 'Unwrap items',
path: 'unwrap',
- shortDescription: 'Remove wrapping text from items in a list',
- icon: 'material-symbols-light:format-clear',
- description:
- 'Remove custom wrapping text from items in a list, such as quotes, brackets, or any other prefix and suffix.',
- keywords: ['unwrap', 'list', 'remove', 'format'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols-light:unfold-more',
+
+ keywords: ['unwrap'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'list:unwrap.title',
+ description: 'list:unwrap.description',
+ shortDescription: 'list:unwrap.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/list/wrap/index.tsx b/src/pages/tools/list/wrap/index.tsx
index dec2ae7..e616b20 100644
--- a/src/pages/tools/list/wrap/index.tsx
+++ b/src/pages/tools/list/wrap/index.tsx
@@ -11,6 +11,7 @@ import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import SimpleRadio from '@components/options/SimpleRadio';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import * as Yup from 'yup';
+import { useTranslation } from 'react-i18next';
interface InitialValuesType {
splitOperatorType: SplitOperatorType;
@@ -85,6 +86,7 @@ const exampleCards: CardExampleType[] = [
];
export default function Wrap({ title }: ToolComponentProps) {
+ const { t } = useTranslation('list');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -117,50 +119,50 @@ export default function Wrap({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Split Options',
+ title: t('wrap.splitOptions'),
component: (
updateField('splitOperatorType', 'symbol')}
checked={values.splitOperatorType === 'symbol'}
- title={'Split by Symbol'}
+ title={t('wrap.splitBySymbol')}
/>
updateField('splitOperatorType', 'regex')}
checked={values.splitOperatorType === 'regex'}
- title={'Split by Regular Expression'}
+ title={t('wrap.splitByRegex')}
/>
updateField('splitSeparator', val)}
- description={'Separator to split the list'}
+ description={t('wrap.splitSeparatorDescription')}
/>
updateField('joinSeparator', val)}
- description={'Separator to join the wrapped list'}
+ description={t('wrap.joinSeparatorDescription')}
/>
updateField('deleteEmptyItems', checked)}
- title={'Remove empty items'}
+ title={t('wrap.removeEmptyItems')}
/>
)
},
{
- title: 'Wrap Options',
+ title: t('wrap.wrapOptions'),
component: (
updateField('left', val)}
- description={'Text to add before each item'}
+ description={t('wrap.leftTextDescription')}
/>
updateField('right', val)}
- description={'Text to add after each item'}
+ description={t('wrap.rightTextDescription')}
/>
)
@@ -171,16 +173,21 @@ export default function Wrap({ title }: ToolComponentProps) {
+
+ }
+ resultComponent={
+
}
- resultComponent={ }
initialValues={initialValues}
getGroups={getGroups}
validationSchema={validationSchema}
toolInfo={{
- title: 'List Wrapping',
- description:
- "This tool allows you to add text before and after each item in a list. You can specify different text for the left and right sides, and control how the list is processed. It's useful for adding quotes, brackets, or other formatting to list items, preparing data for different formats, or creating structured text."
+ title: t('wrap.toolInfo.title'),
+ description: t('wrap.toolInfo.description')
}}
exampleCards={exampleCards}
input={input}
diff --git a/src/pages/tools/list/wrap/meta.ts b/src/pages/tools/list/wrap/meta.ts
index 9e7705f..485a8b7 100644
--- a/src/pages/tools/list/wrap/meta.ts
+++ b/src/pages/tools/list/wrap/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('list', {
- name: 'Wrap items',
path: 'wrap',
- shortDescription: 'Wrap items in a list with custom text',
- icon: 'material-symbols-light:format-quote',
- description:
- 'Wrap each item in a list with custom text, such as quotes, brackets, or any other prefix and suffix.',
- keywords: ['wrap', 'list', 'format', 'text'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols-light:wrap-text',
+
+ keywords: ['wrap'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'list:wrap.title',
+ description: 'list:wrap.description',
+ shortDescription: 'list:wrap.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/number/arithmetic-sequence/index.tsx b/src/pages/tools/number/arithmetic-sequence/index.tsx
index 6835d99..498528d 100644
--- a/src/pages/tools/number/arithmetic-sequence/index.tsx
+++ b/src/pages/tools/number/arithmetic-sequence/index.tsx
@@ -7,6 +7,7 @@ import { generateArithmeticSequence } from './service';
import * as Yup from 'yup';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
+import { useTranslation } from 'react-i18next';
type InitialValuesType = {
firstTerm: string;
@@ -70,6 +71,7 @@ const exampleCards: CardExampleType[] = [
];
export default function ArithmeticSequence({ title }: ToolComponentProps) {
+ const { t } = useTranslation('number');
const [result, setResult] = useState('');
return (
@@ -77,35 +79,39 @@ export default function ArithmeticSequence({ title }: ToolComponentProps) {
title={title}
inputComponent={null}
resultComponent={
-
+
}
initialValues={initialValues}
validationSchema={validationSchema}
exampleCards={exampleCards}
toolInfo={{
- title: 'What is an Arithmetic Sequence?',
- description:
- 'An arithmetic sequence is a sequence of numbers where the difference between each consecutive term is constant. This constant difference is called the common difference. Given the first term (aโ) and the common difference (d), each term can be found by adding the common difference to the previous term.'
+ title: t('arithmeticSequence.toolInfo.title'),
+ description: t('arithmeticSequence.toolInfo.description')
}}
getGroups={({ values, updateField }) => [
{
- title: 'Sequence Parameters',
+ title: t('arithmeticSequence.sequenceParameters'),
component: (
updateField('firstTerm', val)}
type="number"
/>
updateField('commonDifference', val)}
type="number"
/>
updateField('numberOfTerms', val)}
type="number"
@@ -114,10 +120,10 @@ export default function ArithmeticSequence({ title }: ToolComponentProps) {
)
},
{
- title: 'Output Format',
+ title: t('arithmeticSequence.outputFormat'),
component: (
updateField('separator', val)}
/>
diff --git a/src/pages/tools/number/arithmetic-sequence/meta.ts b/src/pages/tools/number/arithmetic-sequence/meta.ts
index 50e3a6d..18a4f9c 100644
--- a/src/pages/tools/number/arithmetic-sequence/meta.ts
+++ b/src/pages/tools/number/arithmetic-sequence/meta.ts
@@ -2,14 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('number', {
- name: 'Generate Arithmetic Sequence',
path: 'arithmetic-sequence',
- icon: 'ic:sharp-plus',
- description:
- 'Generate an arithmetic sequence by specifying the first term (aโ), common difference (d), and number of terms (n). The tool creates a sequence where each number differs from the previous by a constant difference.',
- shortDescription:
- 'Generate a sequence where each term differs by a constant value.',
- keywords: ['arithmetic', 'sequence', 'generate'],
- userTypes: ['Students'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:functions',
+
+ keywords: ['arithmetic', 'sequence', 'math', 'progression'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'number:arithmeticSequence.title',
+ description: 'number:arithmeticSequence.description',
+ shortDescription: 'number:arithmeticSequence.shortDescription',
+ userTypes: ['Students']
+ }
});
diff --git a/src/pages/tools/number/generate/index.tsx b/src/pages/tools/number/generate/index.tsx
index 7f99d62..44158d0 100644
--- a/src/pages/tools/number/generate/index.tsx
+++ b/src/pages/tools/number/generate/index.tsx
@@ -5,6 +5,7 @@ import { listOfIntegers } from './service';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import ToolContent from '@components/ToolContent';
import { ToolComponentProps } from '@tools/defineTool';
+import { useTranslation } from 'react-i18next';
const initialValues = {
firstValue: '1',
@@ -14,6 +15,7 @@ const initialValues = {
};
export default function GenerateNumbers({ title }: ToolComponentProps) {
+ const { t } = useTranslation('number');
const [result, setResult] = useState('');
const compute = (optionsValues: typeof initialValues) => {
@@ -34,23 +36,23 @@ export default function GenerateNumbers({ title }: ToolComponentProps) {
initialValues={initialValues}
getGroups={({ values, updateField }) => [
{
- title: 'Arithmetic sequence option',
+ title: t('generate.arithmeticSequenceOption'),
component: (
updateField('firstValue', val)}
type={'number'}
/>
updateField('step', val)}
type={'number'}
/>
updateField('numberOfNumbers', val)}
type={'number'}
@@ -59,12 +61,10 @@ export default function GenerateNumbers({ title }: ToolComponentProps) {
)
},
{
- title: 'Separator',
+ title: t('generate.separator'),
component: (
updateField('separator', val)}
/>
@@ -73,7 +73,7 @@ export default function GenerateNumbers({ title }: ToolComponentProps) {
]}
compute={compute}
resultComponent={
-
+
}
/>
);
diff --git a/src/pages/tools/number/generate/meta.ts b/src/pages/tools/number/generate/meta.ts
index a58e227..3ef2739 100644
--- a/src/pages/tools/number/generate/meta.ts
+++ b/src/pages/tools/number/generate/meta.ts
@@ -3,12 +3,14 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('number', {
- name: 'Generate numbers',
path: 'generate',
- shortDescription: 'Quickly calculate a list of integers in your browser',
- icon: 'lsicon:number-filled',
- description:
- 'Quickly calculate a list of integers in your browser. To get your list, just specify the first integer, change value and total count in the options below, and this utility will generate that many integers',
- keywords: ['generate'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:add-circle',
+
+ keywords: ['generate', 'random', 'numbers'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'number:generate.title',
+ description: 'number:generate.description',
+ shortDescription: 'number:generate.shortDescription'
+ }
});
diff --git a/src/pages/tools/number/generic-calc/data/ohmsLaw.ts b/src/pages/tools/number/generic-calc/data/ohmsLaw.ts
index 237c71d..87ed54b 100644
--- a/src/pages/tools/number/generic-calc/data/ohmsLaw.ts
+++ b/src/pages/tools/number/generic-calc/data/ohmsLaw.ts
@@ -13,14 +13,14 @@ const ohmsLawCalc: GenericCalcType = {
'power',
'V=IR'
],
- shortDescription:
- "Calculate voltage, current, or resistance in electrical circuits using Ohm's Law",
- name: "Ohm's Law",
path: 'ohms-law',
- description: 'Calculates voltage, current and resistance',
- longDescription:
- "This calculator applies Ohm's Law (V = I ร R) to determine any of the three electrical parameters when the other two are known. Ohm's Law is a fundamental principle in electrical engineering that describes the relationship between voltage (V), current (I), and resistance (R). This tool is essential for electronics hobbyists, electrical engineers, and students working with circuits to quickly solve for unknown values in their electrical designs.",
formula: 'V = I * R',
+ i18n: {
+ name: 'number:ohmsLaw.title',
+ description: 'number:ohmsLaw.description',
+ shortDescription: 'number:ohmsLaw.shortDescription',
+ longDescription: 'number:ohmsLaw.longDescription'
+ },
presets: [],
variables: [
{
diff --git a/src/pages/tools/number/generic-calc/data/slackline.ts b/src/pages/tools/number/generic-calc/data/slackline.ts
index 843a110..0d1c7b2 100644
--- a/src/pages/tools/number/generic-calc/data/slackline.ts
+++ b/src/pages/tools/number/generic-calc/data/slackline.ts
@@ -11,14 +11,15 @@ const slackline: GenericCalcType = {
'tension',
'clothesline'
],
- shortDescription:
- 'Calculate the approximate tension of a slackline or clothesline. Do not rely on this for safety.',
- name: 'Slackline Tension',
path: 'slackline-tension',
- description: 'Calculates tension in a slackline',
- longDescription: 'This calculator assumes a load in the center of the rope',
formula: 'T = (W * sqrt((S**2) + ((L/2)**2)) )/ (2S)',
presets: [],
+ i18n: {
+ name: 'number:slackline.title',
+ description: 'number:slackline.description',
+ shortDescription: 'number:slackline.shortDescription',
+ longDescription: 'number:slackline.longDescription'
+ },
variables: [
{
name: 'L',
diff --git a/src/pages/tools/number/generic-calc/data/sphereArea.ts b/src/pages/tools/number/generic-calc/data/sphereArea.ts
index 15a8d13..029a4a6 100644
--- a/src/pages/tools/number/generic-calc/data/sphereArea.ts
+++ b/src/pages/tools/number/generic-calc/data/sphereArea.ts
@@ -13,15 +13,15 @@ const areaSphere: GenericCalcType = {
'3D',
'shape'
],
- shortDescription:
- 'Calculate the surface area of a sphere based on its radius',
- name: 'Area of a Sphere',
path: 'area-sphere',
- description: 'Area of a Sphere',
- longDescription:
- 'This calculator determines the surface area of a sphere using the formula A = 4ฯrยฒ. You can either input the radius to find the surface area or enter the surface area to calculate the required radius. This tool is useful for students studying geometry, engineers working with spherical objects, and anyone needing to perform calculations involving spherical surfaces.',
formula: 'A = 4 * pi * r**2',
presets: [],
+ i18n: {
+ name: 'number:sphereArea.title',
+ description: 'number:sphereArea.description',
+ shortDescription: 'number:sphereArea.shortDescription',
+ longDescription: 'number:sphereArea.longDescription'
+ },
variables: [
{
name: 'A',
diff --git a/src/pages/tools/number/generic-calc/data/sphereVolume.ts b/src/pages/tools/number/generic-calc/data/sphereVolume.ts
index b6132bc..07c629f 100644
--- a/src/pages/tools/number/generic-calc/data/sphereVolume.ts
+++ b/src/pages/tools/number/generic-calc/data/sphereVolume.ts
@@ -14,12 +14,13 @@ const volumeSphere: GenericCalcType = {
'shape',
'capacity'
],
- shortDescription: 'Calculate the volume of a sphere using radius or diameter',
- name: 'Volume of a Sphere',
+ i18n: {
+ name: 'number:sphereVolume.title',
+ description: 'number:sphereVolume.description',
+ shortDescription: 'number:sphereVolume.shortDescription',
+ longDescription: 'number:sphereVolume.longDescription'
+ },
path: 'volume-sphere',
- description: 'Volume of a Sphere',
- longDescription:
- 'This calculator computes the volume of a sphere using the formula V = (4/3)ฯrยณ. You can input either the radius or diameter to find the volume, or enter the volume to determine the required radius. The tool is valuable for students, engineers, and professionals working with spherical objects in fields such as physics, engineering, and manufacturing.',
formula: 'v = (4/3) * pi * r**3',
presets: [],
variables: [
diff --git a/src/pages/tools/number/generic-calc/data/voltageDropInWire.ts b/src/pages/tools/number/generic-calc/data/voltageDropInWire.ts
index 1fc8c72..3bae1a3 100644
--- a/src/pages/tools/number/generic-calc/data/voltageDropInWire.ts
+++ b/src/pages/tools/number/generic-calc/data/voltageDropInWire.ts
@@ -16,15 +16,14 @@ const voltageDropInWire: GenericCalcType = {
'AWG',
'gauge'
],
- shortDescription:
- 'Calculate voltage drop and power loss in electrical cables based on length, material, and current',
- name: 'Round trip voltage drop in cable',
path: 'cable-voltage-drop',
formula: 'x = (((p * L) / (A/10**6) ) *2) * I',
- description:
- 'Calculates round trip voltage and power loss in a 2 conductor cable',
- longDescription:
- 'This calculator helps determine the voltage drop and power loss in a two-conductor electrical cable. It takes into account the cable length, wire gauge (cross-sectional area), material resistivity, and current flow. The tool calculates the round-trip voltage drop, total resistance of the cable, and the power dissipated as heat. This is particularly useful for electrical engineers, electricians, and hobbyists when designing electrical systems to ensure voltage levels remain within acceptable limits at the load.',
+ i18n: {
+ name: 'number:voltageDropInWire.title',
+ description: 'number:voltageDropInWire.description',
+ shortDescription: 'number:voltageDropInWire.shortDescription',
+ longDescription: 'number:voltageDropInWire.longDescription'
+ },
presets: [
{
title: 'Material',
diff --git a/src/pages/tools/number/generic-calc/index.tsx b/src/pages/tools/number/generic-calc/index.tsx
index 99ba5a2..c87e090 100644
--- a/src/pages/tools/number/generic-calc/index.tsx
+++ b/src/pages/tools/number/generic-calc/index.tsx
@@ -26,6 +26,8 @@ import { CustomSnackBarContext } from 'contexts/CustomSnackBarContext';
import Typography from '@mui/material/Typography';
import Grid from '@mui/material/Grid';
import useMediaQuery from '@mui/material/useMediaQuery';
+import { useTranslation } from 'react-i18next';
+import { validNamespaces } from '../../../../i18n';
function numericSolveEquationFor(
equation: string,
@@ -61,6 +63,7 @@ export default async function makeTool(
return function GenericCalc({ title }: ToolComponentProps) {
const { showSnackBar } = useContext(CustomSnackBarContext);
+ const { t } = useTranslation(validNamespaces);
const theme = useTheme();
const lessThanSmall = useMediaQuery(theme.breakpoints.down('sm'));
@@ -236,8 +239,10 @@ export default async function makeTool(
inputComponent={null}
initialValues={initialValues}
toolInfo={{
- title: calcData.name,
- description: calcData.longDescription
+ title: t(calcData.i18n.name),
+ description: calcData.i18n.longDescription
+ ? t(calcData.i18n.longDescription)
+ : undefined
}}
verticalGroups
// @ts-ignore
diff --git a/src/pages/tools/number/sum/index.tsx b/src/pages/tools/number/sum/index.tsx
index 1b150ba..d649f99 100644
--- a/src/pages/tools/number/sum/index.tsx
+++ b/src/pages/tools/number/sum/index.tsx
@@ -9,6 +9,7 @@ import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
import ToolContent from '@components/ToolContent';
+import { useTranslation } from 'react-i18next';
const initialValues = {
extractionType: 'smart' as NumberExtractionType,
@@ -118,6 +119,7 @@ const exampleCards: CardExampleType[] = [
];
export default function SumNumbers({ title }: ToolComponentProps) {
+ const { t } = useTranslation('number');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -126,16 +128,16 @@ export default function SumNumbers({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Number extraction',
+ title: t('sum.numberExtraction'),
component: extractionTypes.map(
({ title, description, type, withTextField, textValueAccessor }) =>
withTextField ? (
updateField('extractionType', type)}
checked={values.extractionType === type}
- description={description}
- title={title}
+ description={t(`sum.extractionTypes.${type}.description`)}
+ title={t(`sum.extractionTypes.${type}.title`)}
/>
)
)
},
{
- title: 'Running Sum',
+ title: t('sum.runningSum'),
component: (
updateField('printRunningSum', value)}
/>
@@ -171,8 +173,16 @@ export default function SumNumbers({ title }: ToolComponentProps) {
}
- resultComponent={ }
+ inputComponent={
+
+ }
+ resultComponent={
+
+ }
initialValues={initialValues}
getGroups={getGroups}
compute={(optionsValues, input) => {
@@ -181,9 +191,8 @@ export default function SumNumbers({ title }: ToolComponentProps) {
}}
setInput={setInput}
toolInfo={{
- title: 'What Is a Number Sum Calculator?',
- description:
- 'This is an online browser-based utility for calculating the sum of a bunch of numbers. You can enter the numbers separated by a comma, space, or any other character, including the line break. You can also simply paste a fragment of textual data that contains numerical values that you want to sum up and the utility will extract them and find their sum.'
+ title: t('sum.toolInfo.title'),
+ description: t('sum.toolInfo.description')
}}
exampleCards={exampleCards}
/>
diff --git a/src/pages/tools/number/sum/meta.ts b/src/pages/tools/number/sum/meta.ts
index 4c7f8a9..8cb226d 100644
--- a/src/pages/tools/number/sum/meta.ts
+++ b/src/pages/tools/number/sum/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('number', {
- name: 'Number Sum Calculator',
path: 'sum',
- icon: 'fluent:autosum-20-regular',
- description:
- 'Quickly calculate the sum of numbers in your browser. To get your sum, just enter your list of numbers in the input field, adjust the separator between the numbers in the options below, and this utility will add up all these numbers.',
- shortDescription: 'Quickly sum numbers',
- keywords: ['sum'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:add',
+
+ keywords: ['sum', 'add', 'calculate', 'total'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'number:sum.title',
+ description: 'number:sum.description',
+ shortDescription: 'number:sum.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/pdf/compress-pdf/index.tsx b/src/pages/tools/pdf/compress-pdf/index.tsx
index c5a8b2c..53f2731 100644
--- a/src/pages/tools/pdf/compress-pdf/index.tsx
+++ b/src/pages/tools/pdf/compress-pdf/index.tsx
@@ -1,24 +1,26 @@
import { Box, Typography } from '@mui/material';
-import React, { useContext, useEffect, useState } from 'react';
+import React, { useState, useEffect, useContext } from 'react';
import ToolContent from '@components/ToolContent';
import { ToolComponentProps } from '@tools/defineTool';
+import { compressPdf } from './service';
+import { InitialValuesType, CompressionLevel } from './types';
import ToolPdfInput from '@components/input/ToolPdfInput';
+import { GetGroupsType } from '@components/options/ToolOptions';
import ToolFileResult from '@components/result/ToolFileResult';
+import SimpleRadio from '@components/options/SimpleRadio';
import { CardExampleType } from '@components/examples/ToolExamples';
import { PDFDocument } from 'pdf-lib';
-import { CompressionLevel, InitialValuesType } from './types';
-import { compressPdf } from './service';
-import SimpleRadio from '@components/options/SimpleRadio';
import { CustomSnackBarContext } from '../../../../contexts/CustomSnackBarContext';
+import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
- compressionLevel: 'medium'
+ compressionLevel: 'low'
};
const exampleCards: CardExampleType[] = [
{
title: 'Low Compression',
- description: 'Slightly reduce file size with minimal quality loss',
+ description: 'Minimal quality loss with slight file size reduction',
sampleText: '',
sampleResult: '',
sampleOptions: {
@@ -49,6 +51,7 @@ export default function CompressPdf({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('pdf');
const [input, setInput] = useState(null);
const [result, setResult] = useState(null);
const [resultSize, setResultSize] = useState('');
@@ -77,10 +80,7 @@ export default function CompressPdf({
} catch (error) {
console.error('Error getting PDF info:', error);
setFileInfo(null);
- showSnackBar(
- 'Error reading PDF file. Please make sure it is a valid PDF.',
- 'error'
- );
+ showSnackBar(t('compressPdf.errorReadingPdf'), 'error');
}
};
@@ -112,9 +112,9 @@ export default function CompressPdf({
} catch (error) {
console.error('Error compressing PDF:', error);
showSnackBar(
- `Failed to compress PDF: ${
- error instanceof Error ? error.message : String(error)
- }`,
+ t('compressPdf.errorCompressingPdf', {
+ error: error instanceof Error ? error.message : String(error)
+ }),
'error'
);
setResult(null);
@@ -130,18 +130,18 @@ export default function CompressPdf({
}[] = [
{
value: 'low',
- label: 'Low Compression',
- description: 'Slightly reduce file size with minimal quality loss'
+ label: t('compressPdf.lowCompression'),
+ description: t('compressPdf.lowCompressionDescription')
},
{
value: 'medium',
- label: 'Medium Compression',
- description: 'Balance between file size and quality'
+ label: t('compressPdf.mediumCompression'),
+ description: t('compressPdf.mediumCompressionDescription')
},
{
value: 'high',
- label: 'High Compression',
- description: 'Maximum file size reduction with some quality loss'
+ label: t('compressPdf.highCompression'),
+ description: t('compressPdf.highCompressionDescription')
}
];
@@ -157,26 +157,26 @@ export default function CompressPdf({
value={input}
onChange={setInput}
accept={['application/pdf']}
- title={'Input PDF'}
+ title={t('compressPdf.inputTitle')}
/>
}
resultComponent={
}
getGroups={({ values, updateField }) => [
{
- title: 'Compression Settings',
+ title: t('compressPdf.compressionSettings'),
component: (
- Compression Level
+ {t('compressPdf.compressionLevel')}
{compressionOptions.map((option) => (
@@ -201,14 +201,16 @@ export default function CompressPdf({
}}
>
- File size: {fileInfo.size}
+ {t('compressPdf.fileSize')}:{' '}
+ {fileInfo.size}
- Pages: {fileInfo.pages}
+ {t('compressPdf.pages')}: {fileInfo.pages}
{resultSize && (
- Compressed file size: {resultSize}
+ {t('compressPdf.compressedFileSize')}:{' '}
+ {resultSize}
)}
diff --git a/src/pages/tools/pdf/compress-pdf/meta.ts b/src/pages/tools/pdf/compress-pdf/meta.ts
index eb054da..4ff8e56 100644
--- a/src/pages/tools/pdf/compress-pdf/meta.ts
+++ b/src/pages/tools/pdf/compress-pdf/meta.ts
@@ -2,12 +2,9 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('pdf', {
- name: 'Compress PDF',
path: 'compress-pdf',
icon: 'material-symbols:compress',
- description:
- 'Reduce PDF file size while maintaining quality using Ghostscript',
- shortDescription: 'Compress PDF files securely in your browser',
+
keywords: [
'pdf',
'compress',
@@ -22,8 +19,11 @@ export const tool = defineTool('pdf', {
'browser',
'webassembly'
],
- longDescription:
- 'Compress PDF files securely in your browser using Ghostscript. Your files never leave your device, ensuring complete privacy while reducing file sizes for email sharing, uploading to websites, or saving storage space. Powered by WebAssembly technology.',
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'pdf:compressPdf.title',
+ description: 'pdf:compressPdf.description',
+ shortDescription: 'pdf:compressPdf.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/pdf/editor/meta.ts b/src/pages/tools/pdf/editor/meta.ts
index 8fdcf60..de58d1d 100644
--- a/src/pages/tools/pdf/editor/meta.ts
+++ b/src/pages/tools/pdf/editor/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('pdf', {
- name: 'PDF Editor',
+ i18n: {
+ name: 'pdf:editor.title',
+ description: 'pdf:editor.description',
+ shortDescription: 'pdf:editor.shortDescription'
+ },
+
path: 'editor',
icon: 'mdi:file-document-edit',
- description:
- 'Advanced PDF editor with annotation, form-fill, highlight, and export capabilities. Edit your PDFs directly in the browser with professional-grade tools including text insertion, drawing, highlighting, signing and form filling.',
- shortDescription:
- 'Edit PDFs with advanced annotation, signing and editing tools',
+
keywords: [
'pdf',
'editor',
diff --git a/src/pages/tools/pdf/merge-pdf/index.tsx b/src/pages/tools/pdf/merge-pdf/index.tsx
index 789da77..9510209 100644
--- a/src/pages/tools/pdf/merge-pdf/index.tsx
+++ b/src/pages/tools/pdf/merge-pdf/index.tsx
@@ -6,8 +6,10 @@ import { mergePdf } from './service';
import ToolMultiPdfInput, {
MultiPdfInput
} from '@components/input/ToolMultiplePdfInput';
+import { useTranslation } from 'react-i18next';
export default function MergePdf({ title }: ToolComponentProps) {
+ const { t } = useTranslation('pdf');
const [input, setInput] = useState([]);
const [result, setResult] = useState(null);
const [isProcessing, setIsProcessing] = useState(false);
@@ -42,24 +44,23 @@ export default function MergePdf({ title }: ToolComponentProps) {
setInput(pdfInputs);
}}
accept={['application/pdf']}
- title={'Input PDF'}
+ title={t('merge.inputTitle')}
type="pdf"
/>
}
getGroups={null}
resultComponent={
}
toolInfo={{
- title: 'How to Use the Merge PDF Tool?',
- description: `This tool allows you to merge multiple PDF files into a single document.
- To use the tool, simply upload the PDF files you want to merge. The tool will then combine all pages from the input files into a single PDF document.`
+ title: t('merge.toolInfo.title'),
+ description: t('merge.toolInfo.description')
}}
/>
);
diff --git a/src/pages/tools/pdf/merge-pdf/meta.ts b/src/pages/tools/pdf/merge-pdf/meta.ts
index 5e80689..9bb42fe 100644
--- a/src/pages/tools/pdf/merge-pdf/meta.ts
+++ b/src/pages/tools/pdf/merge-pdf/meta.ts
@@ -2,12 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const meta = defineTool('pdf', {
- name: 'Merge PDF',
- shortDescription: 'Merge multiple PDF files into a single document',
- description: 'Combine multiple PDF files into a single document.',
icon: 'material-symbols-light:merge',
component: lazy(() => import('./index')),
keywords: ['pdf', 'merge', 'extract', 'pages', 'combine', 'document'],
path: 'merge-pdf',
- userTypes: ['General Users', 'Students', 'Developers']
+ i18n: {
+ name: 'pdf:mergePdf.title',
+ description: 'pdf:mergePdf.description',
+ shortDescription: 'pdf:mergePdf.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/pdf/pdf-to-epub/meta.ts b/src/pages/tools/pdf/pdf-to-epub/meta.ts
index 000c6e0..0eb21e7 100644
--- a/src/pages/tools/pdf/pdf-to-epub/meta.ts
+++ b/src/pages/tools/pdf/pdf-to-epub/meta.ts
@@ -2,13 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const meta = defineTool('pdf', {
- name: 'PDF to EPUB',
- shortDescription: 'Convert PDF files to EPUB format',
- description:
- 'Transform PDF documents into EPUB files for better e-reader compatibility.',
icon: 'material-symbols:import-contacts',
component: lazy(() => import('./index')),
keywords: ['pdf', 'epub', 'convert', 'ebook'],
path: 'pdf-to-epub',
- userTypes: ['General Users', 'Students', 'Developers']
+ i18n: {
+ name: 'pdf:pdfToEpub.title',
+ description: 'pdf:pdfToEpub.description',
+ shortDescription: 'pdf:pdfToEpub.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/pdf/pdf-to-png/meta.ts b/src/pages/tools/pdf/pdf-to-png/meta.ts
index 830d31f..1ce36d5 100644
--- a/src/pages/tools/pdf/pdf-to-png/meta.ts
+++ b/src/pages/tools/pdf/pdf-to-png/meta.ts
@@ -2,14 +2,17 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('pdf', {
- name: 'PDF to PNG',
+ i18n: {
+ name: 'pdf:pdfToPng.title',
+ description: 'pdf:pdfToPng.description',
+ shortDescription: 'pdf:pdfToPng.shortDescription',
+ longDescription: 'pdf:pdfToPng.longDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ },
+
path: 'pdf-to-png',
icon: 'mdi:image-multiple', // Iconify icon ID
- description: 'Transform PDF documents into PNG panels.',
- shortDescription: 'Convert PDF into PNG images',
+
keywords: ['pdf', 'png', 'convert', 'image', 'extract', 'pages'],
- longDescription:
- 'Upload a PDF and convert each page into a high-quality PNG image directly in your browser. This tool is ideal for extracting visual content or sharing individual pages. No data is uploaded โ everything runs locally.',
- userTypes: ['General Users', 'Students', 'Developers'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/pdf/protect-pdf/meta.ts b/src/pages/tools/pdf/protect-pdf/meta.ts
index 2b7504a..140d38f 100644
--- a/src/pages/tools/pdf/protect-pdf/meta.ts
+++ b/src/pages/tools/pdf/protect-pdf/meta.ts
@@ -2,12 +2,9 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('pdf', {
- name: 'Protect PDF',
path: 'protect-pdf',
icon: 'material-symbols:lock',
- description:
- 'Add password protection to your PDF files securely in your browser',
- shortDescription: 'Password protect PDF files securely',
+
keywords: [
'pdf',
'protect',
@@ -21,8 +18,11 @@ export const tool = defineTool('pdf', {
'browser',
'encryption'
],
- longDescription:
- 'Add password protection to your PDF files securely in your browser. Your files never leave your device, ensuring complete privacy while securing your documents with password encryption. Perfect for protecting sensitive information, confidential documents, or personal data.',
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'pdf:protectPdf.title',
+ description: 'pdf:protectPdf.description',
+ shortDescription: 'pdf:protectPdf.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/pdf/rotate-pdf/index.tsx b/src/pages/tools/pdf/rotate-pdf/index.tsx
index 2e41f2a..a262805 100644
--- a/src/pages/tools/pdf/rotate-pdf/index.tsx
+++ b/src/pages/tools/pdf/rotate-pdf/index.tsx
@@ -1,16 +1,16 @@
-import { Box, FormControlLabel, Switch, Typography } from '@mui/material';
-import React, { useEffect, useState } from 'react';
+import { Box, Typography, FormControlLabel, Switch } from '@mui/material';
+import { useEffect, useState } from 'react';
+import ToolFileResult from '@components/result/ToolFileResult';
+import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import ToolContent from '@components/ToolContent';
import { ToolComponentProps } from '@tools/defineTool';
-import ToolPdfInput from '@components/input/ToolPdfInput';
-import ToolFileResult from '@components/result/ToolFileResult';
+import { parsePageRanges, rotatePdf } from './service';
import { CardExampleType } from '@components/examples/ToolExamples';
import { PDFDocument } from 'pdf-lib';
-import { InitialValuesType, RotationAngle } from './types';
-import { parsePageRanges, rotatePdf } from './service';
+import ToolPdfInput from '@components/input/ToolPdfInput';
import SimpleRadio from '@components/options/SimpleRadio';
-import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
-import { isArray } from 'lodash';
+import { InitialValuesType, RotationAngle } from './types';
+import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
rotationAngle: 90,
@@ -21,7 +21,7 @@ const initialValues: InitialValuesType = {
const exampleCards: CardExampleType[] = [
{
title: 'Rotate All Pages 90ยฐ',
- description: 'Rotate all pages in the document 90 degrees clockwise',
+ description: 'Rotate all pages in the PDF by 90 degrees clockwise',
sampleText: '',
sampleResult: '',
sampleOptions: {
@@ -32,7 +32,7 @@ const exampleCards: CardExampleType[] = [
},
{
title: 'Rotate Specific Pages 180ยฐ',
- description: 'Rotate only pages 1 and 3 by 180 degrees',
+ description: 'Rotate pages 1 and 3 by 180 degrees',
sampleText: '',
sampleResult: '',
sampleOptions: {
@@ -58,6 +58,7 @@ export default function RotatePdf({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('pdf');
const [input, setInput] = useState(null);
const [result, setResult] = useState(null);
const [isProcessing, setIsProcessing] = useState(false);
@@ -90,7 +91,9 @@ export default function RotatePdf({
if (applyToAllPages) {
setPageRangePreview(
- totalPages > 0 ? `All ${totalPages} pages will be rotated` : ''
+ totalPages > 0
+ ? t('rotatePdf.allPagesWillBeRotated', { count: totalPages })
+ : ''
);
return;
}
@@ -102,9 +105,7 @@ export default function RotatePdf({
try {
const count = parsePageRanges(pageRanges, totalPages).length;
- setPageRangePreview(
- `${count} page${count !== 1 ? 's' : ''} will be rotated`
- );
+ setPageRangePreview(t('rotatePdf.pagesWillBeRotated', { count }));
} catch (error) {
setPageRangePreview('');
}
@@ -124,9 +125,9 @@ export default function RotatePdf({
}
};
const angleOptions: { value: RotationAngle; label: string }[] = [
- { value: 90, label: '90ยฐ Clockwise' },
- { value: 180, label: '180ยฐ (Upside down)' },
- { value: 270, label: '270ยฐ (90ยฐ Counter-clockwise)' }
+ { value: 90, label: t('rotatePdf.angleOptions.clockwise90') },
+ { value: 180, label: t('rotatePdf.angleOptions.upsideDown180') },
+ { value: 270, label: t('rotatePdf.angleOptions.counterClockwise270') }
];
return (
}
resultComponent={
}
getGroups={({ values, updateField }) => [
{
- title: 'Rotation Settings',
+ title: t('rotatePdf.rotationSettings'),
component: (
- Rotation Angle
+ {t('rotatePdf.rotationAngle')}
{angleOptions.map((angleOption) => (
}
- label="Apply to all pages"
+ label={t('rotatePdf.applyToAllPages')}
/>
@@ -190,7 +191,7 @@ export default function RotatePdf({
{totalPages > 0 && (
- PDF has {totalPages} page{totalPages !== 1 ? 's' : ''}
+ {t('rotatePdf.pdfPageCount', { count: totalPages })}
)}
{
updateField('pageRanges', val);
}}
- description={
- 'Enter page numbers or ranges separated by commas (e.g., 1,3,5-7)'
- }
- placeholder={'e.g., 1,5-8'}
+ description={t('rotatePdf.pageRangesDescription')}
+ placeholder={t('rotatePdf.pageRangesPlaceholder')}
/>
{pageRangePreview && (
);
diff --git a/src/pages/tools/pdf/rotate-pdf/meta.ts b/src/pages/tools/pdf/rotate-pdf/meta.ts
index df521fb..4160d6f 100644
--- a/src/pages/tools/pdf/rotate-pdf/meta.ts
+++ b/src/pages/tools/pdf/rotate-pdf/meta.ts
@@ -2,14 +2,17 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('pdf', {
- name: 'Rotate PDF',
+ i18n: {
+ name: 'pdf:rotatePdf.title',
+ description: 'pdf:rotatePdf.description',
+ shortDescription: 'pdf:rotatePdf.shortDescription',
+ longDescription: 'pdf:rotatePdf.longDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ },
+
path: 'rotate-pdf',
icon: 'carbon:rotate',
- description: 'Rotate PDF pages by 90, 180, or 270 degrees',
- shortDescription: 'Rotate pages in a PDF document',
+
keywords: ['pdf', 'rotate', 'rotation', 'document', 'pages', 'orientation'],
- longDescription:
- 'Change the orientation of PDF pages by rotating them 90, 180, or 270 degrees. Useful for fixing incorrectly scanned documents or preparing PDFs for printing.',
- userTypes: ['General Users', 'Students', 'Developers'],
component: lazy(() => import('./index'))
});
diff --git a/src/pages/tools/pdf/split-pdf/index.tsx b/src/pages/tools/pdf/split-pdf/index.tsx
index 3ceacbd..85beed0 100644
--- a/src/pages/tools/pdf/split-pdf/index.tsx
+++ b/src/pages/tools/pdf/split-pdf/index.tsx
@@ -8,6 +8,7 @@ import { parsePageRanges, splitPdf } from './service';
import { CardExampleType } from '@components/examples/ToolExamples';
import { PDFDocument } from 'pdf-lib';
import ToolPdfInput from '@components/input/ToolPdfInput';
+import { useTranslation } from 'react-i18next';
type InitialValuesType = {
pageRanges: string;
@@ -48,6 +49,7 @@ const exampleCards: CardExampleType[] = [
];
export default function SplitPdf({ title }: ToolComponentProps) {
+ const { t } = useTranslation('pdf');
const [input, setInput] = useState(null);
const [result, setResult] = useState(null);
const [isProcessing, setIsProcessing] = useState(false);
@@ -83,9 +85,7 @@ export default function SplitPdf({ title }: ToolComponentProps) {
}
try {
const count = parsePageRanges(pageRanges, totalPages).length;
- setPageRangePreview(
- `${count} page${count !== 1 ? 's' : ''} will be extracted`
- );
+ setPageRangePreview(t('splitPdf.pageExtractionPreview', { count }));
} catch (error) {
setPageRangePreview('');
}
@@ -118,26 +118,26 @@ export default function SplitPdf({ title }: ToolComponentProps) {
value={input}
onChange={setInput}
accept={['application/pdf']}
- title={'Input PDF'}
+ title={t('splitPdf.inputTitle')}
/>
}
resultComponent={
}
getGroups={({ values, updateField }) => [
{
- title: 'Page Selection',
+ title: t('splitPdf.pageSelection'),
component: (
{totalPages > 0 && (
- PDF has {totalPages} page{totalPages !== 1 ? 's' : ''}
+ {t('splitPdf.pdfPageCount', { count: totalPages })}
)}
{
updateField('pageRanges', val);
}}
- description={
- 'Enter page numbers or ranges separated by commas (e.g., 1,3,5-7)'
- }
- placeholder={'e.g., 1,5-8'}
+ description={t('splitPdf.pageRangesDescription')}
+ placeholder={t('splitPdf.pageRangesPlaceholder')}
/>
{pageRangePreview && (
);
diff --git a/src/pages/tools/pdf/split-pdf/meta.ts b/src/pages/tools/pdf/split-pdf/meta.ts
index 33a5f74..94fc007 100644
--- a/src/pages/tools/pdf/split-pdf/meta.ts
+++ b/src/pages/tools/pdf/split-pdf/meta.ts
@@ -2,13 +2,14 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const meta = defineTool('pdf', {
- name: 'Split PDF',
- shortDescription: 'Extract specific pages from a PDF file',
- description:
- 'Extract specific pages from a PDF file using page numbers or ranges (e.g., 1,5-8)',
icon: 'material-symbols-light:call-split-rounded',
component: lazy(() => import('./index')),
keywords: ['pdf', 'split', 'extract', 'pages', 'range', 'document'],
path: 'split-pdf',
- userTypes: ['General Users', 'Students', 'Developers']
+ i18n: {
+ name: 'pdf:splitPdf.title',
+ description: 'pdf:splitPdf.description',
+ shortDescription: 'pdf:splitPdf.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/base64/index.tsx b/src/pages/tools/string/base64/index.tsx
index 6176367..1a6d208 100644
--- a/src/pages/tools/string/base64/index.tsx
+++ b/src/pages/tools/string/base64/index.tsx
@@ -9,6 +9,7 @@ import { GetGroupsType } from '@components/options/ToolOptions';
import { Box } from '@mui/material';
import SimpleRadio from '@components/options/SimpleRadio';
import { InitialValuesType } from './types';
+import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
mode: 'encode'
@@ -33,6 +34,7 @@ const exampleCards: CardExampleType[] = [
];
export default function Base64({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -45,18 +47,18 @@ export default function Base64({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Base64 Options',
+ title: t('base64.optionsTitle'),
component: (
updateField('mode', 'encode')}
checked={values.mode === 'encode'}
- title={'Base64 Encode'}
+ title={t('base64.encode')}
/>
updateField('mode', 'decode')}
checked={values.mode === 'decode'}
- title={'Base64 Decode'}
+ title={t('base64.decode')}
/>
)
@@ -67,15 +69,20 @@ export default function Base64({ title }: ToolComponentProps) {
+
+ }
+ resultComponent={
+
}
- resultComponent={ }
initialValues={initialValues}
getGroups={getGroups}
toolInfo={{
- title: 'What is Base64?',
- description:
- 'Base64 is an encoding scheme that represents data in an ASCII string format by translating it into a radix-64 representation. Although it can be used to encode strings, it is commonly used to encode binary data for transmission over media that are designed to deal with textual data.'
+ title: t('base64.toolInfo.title'),
+ description: t('base64.toolInfo.description')
}}
exampleCards={exampleCards}
input={input}
diff --git a/src/pages/tools/string/base64/meta.ts b/src/pages/tools/string/base64/meta.ts
index 7c3d98f..f778e7c 100644
--- a/src/pages/tools/string/base64/meta.ts
+++ b/src/pages/tools/string/base64/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('string', {
- name: 'Base64',
path: 'base64',
icon: 'tabler:number-64-small',
- description:
- 'A simple tool to encode or decode data using Base64, which is commonly used in web applications.',
- shortDescription: 'Encode or decode data using Base64.',
+
keywords: ['base64'],
- userTypes: ['Developers', 'CyberSec'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:base64.title',
+ description: 'string:base64.description',
+ shortDescription: 'string:base64.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/censor/meta.ts b/src/pages/tools/string/censor/meta.ts
index 372816a..49400fd 100644
--- a/src/pages/tools/string/censor/meta.ts
+++ b/src/pages/tools/string/censor/meta.ts
@@ -2,16 +2,16 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('string', {
- name: 'Text Censor',
path: 'censor',
- shortDescription:
- 'Quickly mask bad words or replace them with alternative words.',
+
icon: 'hugeicons:text-footnote',
- description:
- "utility for censoring words in text. Load your text in the input form on the left, specify all the bad words in the options, and you'll instantly get censored text in the output area.",
- longDescription:
- 'With this online tool, you can censor certain words in any text. You can specify a list of unwanted words (such as swear words or secret words) and the program will replace them with alternative words and create a safe-to-read text. The words can be specified in a multi-line text field in the options by entering one word per line.',
+
keywords: ['text', 'censor', 'words', 'characters'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:censor.title',
+ description: 'string:censor.description',
+ shortDescription: 'string:censor.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/string/create-palindrome/meta.ts b/src/pages/tools/string/create-palindrome/meta.ts
index a056e73..5d47f27 100644
--- a/src/pages/tools/string/create-palindrome/meta.ts
+++ b/src/pages/tools/string/create-palindrome/meta.ts
@@ -3,15 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('string', {
- name: 'Create palindrome',
path: 'create-palindrome',
icon: 'material-symbols-light:repeat',
- description:
- "World's simplest browser-based utility for creating palindromes from any text. Input text and instantly transform it into a palindrome that reads the same forward and backward. Perfect for word games, creating symmetrical text patterns, or exploring linguistic curiosities.",
- shortDescription: 'Create text that reads the same forward and backward',
- longDescription:
- 'This tool creates a palindrome from the given string. It does it by generating a copy of the string, reversing it, and appending it at the end of the original string. This method creates a palindrome with the last character duplicated twice. There is also another way to do it, which deletes the first letter of the reversed copy. In this case, when the string and the copy are joined together, you also get a palindrome but without the repeating last character. You can compare the two types of palindromes by switching between them in the options. You can also enable the multi-line mode that will create palindromes of every string on every line. Stringabulous!',
+
keywords: ['create', 'palindrome'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:createPalindrome.title',
+ description: 'string:createPalindrome.description',
+ shortDescription: 'string:createPalindrome.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/string/extract-substring/meta.ts b/src/pages/tools/string/extract-substring/meta.ts
index f68148f..d9f6097 100644
--- a/src/pages/tools/string/extract-substring/meta.ts
+++ b/src/pages/tools/string/extract-substring/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('string', {
- name: 'Extract substring',
path: 'extract-substring',
icon: 'material-symbols-light:content-cut',
- description:
- "World's simplest browser-based utility for extracting substrings from text. Easily extract specific portions of text by specifying start position and length. Perfect for parsing data, isolating specific parts of text, or data extraction tasks. Supports multi-line text processing and character-level precision.",
- shortDescription: 'Extract specific portions of text by position and length',
+
keywords: ['extract', 'substring'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:extractSubstring.title',
+ description: 'string:extractSubstring.description',
+ shortDescription: 'string:extractSubstring.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/index.ts b/src/pages/tools/string/index.ts
index e4979fc..0ded96d 100644
--- a/src/pages/tools/string/index.ts
+++ b/src/pages/tools/string/index.ts
@@ -17,6 +17,7 @@ import { tool as stringTruncate } from './truncate/meta';
import { tool as stringBase64 } from './base64/meta';
import { tool as stringStatistic } from './statistic/meta';
import { tool as stringCensor } from './censor/meta';
+import { tool as stringPasswordGenerator } from './password-generator/meta';
export const stringTools = [
stringSplit,
@@ -37,5 +38,6 @@ export const stringTools = [
stringRot13,
stringBase64,
stringStatistic,
- stringCensor
+ stringCensor,
+ stringPasswordGenerator
];
diff --git a/src/pages/tools/string/join/index.tsx b/src/pages/tools/string/join/index.tsx
index eb0105a..da69a33 100644
--- a/src/pages/tools/string/join/index.tsx
+++ b/src/pages/tools/string/join/index.tsx
@@ -9,6 +9,7 @@ import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
+import { useTranslation } from 'react-i18next';
const initialValues = {
joinCharacter: '',
@@ -32,7 +33,7 @@ const mergeOptions = {
const blankTrailingOptions: {
title: string;
description: string;
- accessor: keyof InitialValuesType;
+ accessor: keyof Omit;
}[] = [
{
title: 'Delete Blank Lines',
@@ -107,6 +108,7 @@ s
];
export default function JoinText({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
const compute = (optionsValues: InitialValuesType, input: any) => {
@@ -119,25 +121,25 @@ export default function JoinText({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Text Merged Options',
+ title: t('join.textMergedOptions'),
component: (
updateField(mergeOptions.accessor, value)}
- description={mergeOptions.description}
+ description={t('join.joinCharacterDescription')}
/>
)
},
{
- title: 'Blank Lines and Trailing Spaces',
+ title: t('join.blankLinesAndTrailingSpaces'),
component: blankTrailingOptions.map((option) => (
updateField(option.accessor, value)}
- description={option.description}
+ description={t(`join.${option.accessor}Description`)}
/>
))
}
@@ -151,17 +153,18 @@ export default function JoinText({ title }: ToolComponentProps) {
setInput={setInput}
inputComponent={
}
- resultComponent={ }
+ resultComponent={
+
+ }
getGroups={getGroups}
toolInfo={{
- title: 'What Is a Text Joiner?',
- description:
- 'With this tool you can join parts of the text together. It takes a list of text values, separated by newlines, and merges them together. You can set the character that will be placed between the parts of the combined text. Also, you can ignore all empty lines and remove spaces and tabs at the end of all lines. Textabulous!'
+ title: t('join.toolInfo.title'),
+ description: t('join.toolInfo.description')
}}
exampleCards={exampleCards}
/>
diff --git a/src/pages/tools/string/join/meta.ts b/src/pages/tools/string/join/meta.ts
index 0091eee..b8ac5f7 100644
--- a/src/pages/tools/string/join/meta.ts
+++ b/src/pages/tools/string/join/meta.ts
@@ -3,12 +3,15 @@ import { lazy } from 'react';
export const tool = defineTool('string', {
path: 'join',
- name: 'Text Joiner',
- icon: 'tabler:arrows-join',
- description:
- "World's Simplest Text Tool World's simplest browser-based utility for joining text. Load your text in the input form on the left and you'll automatically get merged text on the right. Powerful, free, and fast. Load text โ get joined lines",
- shortDescription: 'Quickly merge texts',
+
+ icon: 'material-symbols-light:join',
+
keywords: ['text', 'join'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:join.title',
+ description: 'string:join.description',
+ shortDescription: 'string:join.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/string/palindrome/meta.ts b/src/pages/tools/string/palindrome/meta.ts
index dee13a6..9d289a6 100644
--- a/src/pages/tools/string/palindrome/meta.ts
+++ b/src/pages/tools/string/palindrome/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('string', {
- name: 'Palindrome',
path: 'palindrome',
icon: 'material-symbols-light:search',
- description:
- "World's simplest browser-based utility for checking if text is a palindrome. Instantly verify if your text reads the same forward and backward. Perfect for word puzzles, linguistic analysis, or validating symmetrical text patterns. Supports various delimiters and multi-word palindrome detection.",
- shortDescription: 'Check if text reads the same forward and backward',
+
keywords: ['palindrome'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:palindrome.title',
+ description: 'string:palindrome.description',
+ shortDescription: 'string:palindrome.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/string/password-generator/index.tsx b/src/pages/tools/string/password-generator/index.tsx
new file mode 100644
index 0000000..9d7f62d
--- /dev/null
+++ b/src/pages/tools/string/password-generator/index.tsx
@@ -0,0 +1,165 @@
+import React, { useState } from 'react';
+import { Box, Checkbox, FormControlLabel, FormGroup } from '@mui/material';
+import { generatePassword } from './service';
+import { initialValues, InitialValuesType } from './initialValues';
+import ToolContent from '@components/ToolContent';
+import ToolTextResult from '@components/result/ToolTextResult';
+import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
+import { ToolComponentProps } from '@tools/defineTool';
+import { GetGroupsType } from '@components/options/ToolOptions';
+import { CardExampleType } from '@components/examples/ToolExamples';
+import { useTranslation } from 'react-i18next';
+
+const exampleCards: CardExampleType[] = [
+ {
+ title: 'Strong Password (12 characters)',
+ description:
+ 'Generate a secure password with all character types including symbols.',
+ sampleText: '',
+ sampleResult: 'A7#mK9$pL2@x',
+ sampleOptions: {
+ length: '12',
+ includeLowercase: true,
+ includeUppercase: true,
+ includeNumbers: true,
+ includeSymbols: true,
+ avoidAmbiguous: false
+ }
+ },
+ {
+ title: 'Simple Password (8 characters)',
+ description: 'Generate a basic password with letters and numbers only.',
+ sampleText: '',
+ sampleResult: 'Ab3mK9pL',
+ sampleOptions: {
+ length: '8',
+ includeLowercase: true,
+ includeUppercase: true,
+ includeNumbers: true,
+ includeSymbols: false,
+ avoidAmbiguous: false
+ }
+ },
+ {
+ title: 'Clear Password (No ambiguous)',
+ description:
+ 'Generate a password without ambiguous characters (i, I, l, 0, O).',
+ sampleText: '',
+ sampleResult: 'A7#mK9$pL2@x',
+ sampleOptions: {
+ length: '12',
+ includeLowercase: true,
+ includeUppercase: true,
+ includeNumbers: true,
+ includeSymbols: true,
+ avoidAmbiguous: true
+ }
+ }
+];
+
+export default function PasswordGenerator({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
+ const [result, setResult] = useState('');
+
+ function compute(values: InitialValuesType) {
+ setResult(generatePassword(values));
+ }
+
+ const getGroups: GetGroupsType = ({
+ values,
+ updateField
+ }) => [
+ {
+ title: t('passwordGenerator.optionsTitle'),
+ component: (
+
+ updateField('length', val)}
+ type="number"
+ />
+
+
+
+ updateField('includeLowercase', e.target.checked)
+ }
+ />
+ }
+ label={t('passwordGenerator.includeLowercase')}
+ />
+
+ updateField('includeUppercase', e.target.checked)
+ }
+ />
+ }
+ label={t('passwordGenerator.includeUppercase')}
+ />
+
+ updateField('includeNumbers', e.target.checked)
+ }
+ />
+ }
+ label={t('passwordGenerator.includeNumbers')}
+ />
+
+ updateField('includeSymbols', e.target.checked)
+ }
+ />
+ }
+ label={t('passwordGenerator.includeSymbols')}
+ />
+
+ updateField('avoidAmbiguous', e.target.checked)
+ }
+ />
+ }
+ label={t('passwordGenerator.avoidAmbiguous')}
+ />
+
+
+ )
+ }
+ ];
+
+ return (
+
+ }
+ toolInfo={{
+ title: t('passwordGenerator.toolInfo.title'),
+ description: t('passwordGenerator.toolInfo.description')
+ }}
+ exampleCards={exampleCards}
+ />
+ );
+}
diff --git a/src/pages/tools/string/password-generator/initialValues.ts b/src/pages/tools/string/password-generator/initialValues.ts
new file mode 100644
index 0000000..a96cc1b
--- /dev/null
+++ b/src/pages/tools/string/password-generator/initialValues.ts
@@ -0,0 +1,17 @@
+export type InitialValuesType = {
+ length: string; // user enters a number here
+ includeLowercase: boolean;
+ includeUppercase: boolean;
+ includeNumbers: boolean;
+ includeSymbols: boolean;
+ avoidAmbiguous: boolean;
+};
+
+export const initialValues: InitialValuesType = {
+ length: '12',
+ includeLowercase: true,
+ includeUppercase: true,
+ includeNumbers: true,
+ includeSymbols: true,
+ avoidAmbiguous: false
+};
diff --git a/src/pages/tools/string/password-generator/meta.ts b/src/pages/tools/string/password-generator/meta.ts
new file mode 100644
index 0000000..f24ffc2
--- /dev/null
+++ b/src/pages/tools/string/password-generator/meta.ts
@@ -0,0 +1,14 @@
+import { defineTool } from '@tools/defineTool';
+import { lazy } from 'react';
+
+export const tool = defineTool('string', {
+ path: 'password-generator',
+ icon: 'material-symbols:key',
+ keywords: ['password', 'generator', 'random', 'secure'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:passwordGenerator.title',
+ description: 'string:passwordGenerator.description',
+ shortDescription: 'string:passwordGenerator.shortDescription'
+ }
+});
diff --git a/src/pages/tools/string/password-generator/password-generator.service.test.ts b/src/pages/tools/string/password-generator/password-generator.service.test.ts
new file mode 100644
index 0000000..e6bb634
--- /dev/null
+++ b/src/pages/tools/string/password-generator/password-generator.service.test.ts
@@ -0,0 +1,143 @@
+import { describe, expect, it } from 'vitest';
+import { generatePassword } from './service';
+import { initialValues } from './initialValues';
+
+describe('generatePassword', () => {
+ it('should generate a password with the specified length', () => {
+ const options = { ...initialValues, length: '10' };
+ const result = generatePassword(options);
+ expect(result).toHaveLength(10);
+ });
+
+ it('should return empty string for invalid length', () => {
+ const options = { ...initialValues, length: '0' };
+ const result = generatePassword(options);
+ expect(result).toBe('');
+ });
+
+ it('should return empty string for non-numeric length', () => {
+ const options = { ...initialValues, length: 'abc' };
+ const result = generatePassword(options);
+ expect(result).toBe('');
+ });
+
+ it('should return empty string when no character types are selected', () => {
+ const options = {
+ ...initialValues,
+ includeLowercase: false,
+ includeUppercase: false,
+ includeNumbers: false,
+ includeSymbols: false
+ };
+ const result = generatePassword(options);
+ expect(result).toBe('');
+ });
+
+ it('should only include lowercase letters when only lowercase is selected', () => {
+ const options = {
+ ...initialValues,
+ length: '20',
+ includeLowercase: true,
+ includeUppercase: false,
+ includeNumbers: false,
+ includeSymbols: false
+ };
+ const result = generatePassword(options);
+ expect(result).toMatch(/^[a-z]+$/);
+ expect(result).toHaveLength(20);
+ });
+
+ it('should only include uppercase letters when only uppercase is selected', () => {
+ const options = {
+ ...initialValues,
+ length: '15',
+ includeLowercase: false,
+ includeUppercase: true,
+ includeNumbers: false,
+ includeSymbols: false
+ };
+ const result = generatePassword(options);
+ expect(result).toMatch(/^[A-Z]+$/);
+ expect(result).toHaveLength(15);
+ });
+
+ it('should only include numbers when only numbers is selected', () => {
+ const options = {
+ ...initialValues,
+ length: '8',
+ includeLowercase: false,
+ includeUppercase: false,
+ includeNumbers: true,
+ includeSymbols: false
+ };
+ const result = generatePassword(options);
+ expect(result).toMatch(/^[0-9]+$/);
+ expect(result).toHaveLength(8);
+ });
+
+ it('should include mixed character types when multiple are selected', () => {
+ const options = {
+ ...initialValues,
+ length: '100', // larger sample for better testing
+ includeLowercase: true,
+ includeUppercase: true,
+ includeNumbers: true,
+ includeSymbols: false
+ };
+ const result = generatePassword(options);
+ expect(result).toMatch(/^[a-zA-Z0-9]+$/);
+ expect(result).toHaveLength(100);
+ });
+
+ it('should exclude ambiguous characters when avoidAmbiguous is true', () => {
+ const options = {
+ ...initialValues,
+ length: '50',
+ avoidAmbiguous: true
+ };
+ const result = generatePassword(options);
+ expect(result).not.toMatch(/[iIl0O]/);
+ expect(result).toHaveLength(50);
+ });
+
+ it('should include symbols when includeSymbols is true', () => {
+ const options = {
+ ...initialValues,
+ length: '30',
+ includeLowercase: false,
+ includeUppercase: false,
+ includeNumbers: false,
+ includeSymbols: true
+ };
+ const result = generatePassword(options);
+ expect(result).toMatch(/^[!@#$%^&*()_+~`|}{[\]:;?><,./\-=]+$/);
+ expect(result).toHaveLength(30);
+ });
+
+ it('should exclude ambiguous characters from symbols too', () => {
+ const options = {
+ ...initialValues,
+ length: '50',
+ includeLowercase: false,
+ includeUppercase: false,
+ includeNumbers: true,
+ includeSymbols: true,
+ avoidAmbiguous: true
+ };
+ const result = generatePassword(options);
+ expect(result).not.toMatch(/[iIl0O]/);
+ expect(result).toHaveLength(50);
+ });
+
+ it('should handle edge case with very short length', () => {
+ const options = { ...initialValues, length: '1' };
+ const result = generatePassword(options);
+ expect(result).toHaveLength(1);
+ });
+
+ it('should handle negative length', () => {
+ const options = { ...initialValues, length: '-5' };
+ const result = generatePassword(options);
+ expect(result).toBe('');
+ });
+});
diff --git a/src/pages/tools/string/password-generator/service.ts b/src/pages/tools/string/password-generator/service.ts
new file mode 100644
index 0000000..fe20a6b
--- /dev/null
+++ b/src/pages/tools/string/password-generator/service.ts
@@ -0,0 +1,38 @@
+import type { InitialValuesType } from './initialValues';
+
+export function generatePassword(options: InitialValuesType): string {
+ const length = parseInt(options.length || '', 10);
+ if (isNaN(length) || length <= 0) {
+ return '';
+ }
+
+ let charset = '';
+ const lower = 'abcdefghijklmnopqrstuvwxyz';
+ const upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ const numbers = '0123456789';
+ const symbols = '!@#$%^&*()_+~`|}{[]:;?><,./-=';
+
+ if (options.includeLowercase) charset += lower;
+ if (options.includeUppercase) charset += upper;
+ if (options.includeNumbers) charset += numbers;
+ if (options.includeSymbols) charset += symbols;
+
+ if (options.avoidAmbiguous) {
+ // ambiguous set = i, I, l, 0, O
+ const ambig = new Set(['i', 'I', 'l', '0', 'O']);
+ charset = Array.from(charset)
+ .filter((c) => !ambig.has(c))
+ .join('');
+ }
+
+ if (!charset) {
+ return ''; // nothing to pick from
+ }
+
+ let pwd = '';
+ for (let i = 0; i < length; i++) {
+ const idx = Math.floor(Math.random() * charset.length);
+ pwd += charset[idx];
+ }
+ return pwd;
+}
diff --git a/src/pages/tools/string/quote/index.tsx b/src/pages/tools/string/quote/index.tsx
index 61035a0..64b523c 100644
--- a/src/pages/tools/string/quote/index.tsx
+++ b/src/pages/tools/string/quote/index.tsx
@@ -9,6 +9,7 @@ import { ToolComponentProps } from '@tools/defineTool';
import { GetGroupsType } from '@components/options/ToolOptions';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
+import { useTranslation } from 'react-i18next';
interface InitialValuesType {
leftQuote: string;
@@ -70,6 +71,7 @@ const exampleCards: CardExampleType[] = [
];
export default function Quote({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -93,33 +95,33 @@ export default function Quote({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Quote Options',
+ title: t('quote.quoteOptions'),
component: (
updateField('leftQuote', val)}
- description={'Left quote character(s)'}
+ description={t('quote.leftQuoteDescription')}
/>
updateField('rightQuote', val)}
- description={'Right quote character(s)'}
+ description={t('quote.rightQuoteDescription')}
/>
updateField('doubleQuotation', checked)}
- title={'Allow double quotation'}
+ title={t('quote.allowDoubleQuotation')}
/>
updateField('emptyQuoting', checked)}
- title={'Quote empty lines'}
+ title={t('quote.quoteEmptyLines')}
/>
updateField('multiLine', checked)}
- title={'Process as multi-line text'}
+ title={t('quote.processAsMultiLine')}
/>
)
@@ -130,15 +132,20 @@ export default function Quote({ title }: ToolComponentProps) {
+
+ }
+ resultComponent={
+
}
- resultComponent={ }
initialValues={initialValues}
getGroups={getGroups}
toolInfo={{
- title: 'Text Quoter',
- description:
- "This tool allows you to add quotes around text. You can choose different quote characters, handle multi-line text, and control how empty lines are processed. It's useful for preparing text for programming, formatting data, or creating stylized text."
+ title: t('quote.toolInfo.title'),
+ description: t('quote.toolInfo.description')
}}
exampleCards={exampleCards}
input={input}
diff --git a/src/pages/tools/string/quote/meta.ts b/src/pages/tools/string/quote/meta.ts
index e6e3da8..87fc4c1 100644
--- a/src/pages/tools/string/quote/meta.ts
+++ b/src/pages/tools/string/quote/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('string', {
- name: 'Quote',
path: 'quote',
- icon: 'proicons:quote',
- description:
- 'A tool to add quotation marks or custom characters around text. Perfect for formatting strings for code, citations, or stylistic purposes.',
- shortDescription: 'Add quotes around text easily.',
+ icon: 'material-symbols-light:format-quote',
+
keywords: ['quote'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:quote.title',
+ description: 'string:quote.description',
+ shortDescription: 'string:quote.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/randomize-case/meta.ts b/src/pages/tools/string/randomize-case/meta.ts
index f6b576e..f9fc493 100644
--- a/src/pages/tools/string/randomize-case/meta.ts
+++ b/src/pages/tools/string/randomize-case/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('string', {
- name: 'Randomize case',
path: 'randomize-case',
- icon: 'material-symbols-light:format-textdirection-l-to-r',
- description:
- "World's simplest browser-based utility for randomizing the case of text. Just paste your text and get it instantly transformed with random uppercase and lowercase letters. Perfect for creating playful text styles, meme text, or simulating chaotic writing.",
- shortDescription: 'Convert text to random uppercase and lowercase letters',
+ icon: 'material-symbols-light:shuffle',
+
keywords: ['randomize', 'case'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:randomizeCase.title',
+ description: 'string:randomizeCase.description',
+ shortDescription: 'string:randomizeCase.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/string/remove-duplicate-lines/meta.ts b/src/pages/tools/string/remove-duplicate-lines/meta.ts
index cf18eff..4312d7d 100644
--- a/src/pages/tools/string/remove-duplicate-lines/meta.ts
+++ b/src/pages/tools/string/remove-duplicate-lines/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('string', {
- name: 'Remove duplicate lines',
path: 'remove-duplicate-lines',
icon: 'pepicons-print:duplicate-off',
- description:
- "Load your text in the input form on the left and you'll instantly get text with no duplicate lines in the output area. Powerful, free, and fast. Load text lines โ get unique text lines",
- shortDescription: 'Quickly delete all repeated lines from text',
+
keywords: ['remove', 'duplicate', 'lines'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:removeDuplicateLines.title',
+ description: 'string:removeDuplicateLines.description',
+ shortDescription: 'string:removeDuplicateLines.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/repeat/index.tsx b/src/pages/tools/string/repeat/index.tsx
index 0a954e2..2df00ba 100644
--- a/src/pages/tools/string/repeat/index.tsx
+++ b/src/pages/tools/string/repeat/index.tsx
@@ -9,6 +9,7 @@ import { initialValues, InitialValuesType } from './initialValues';
import ToolContent from '@components/ToolContent';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
+import { useTranslation } from 'react-i18next';
const exampleCards: CardExampleType[] = [
{
@@ -48,6 +49,7 @@ const exampleCards: CardExampleType[] = [
];
export default function Replacer({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -60,12 +62,12 @@ export default function Replacer({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Text Repetitions',
+ title: t('repeat.textRepetitions'),
component: (
updateField('repeatAmount', val)}
type={'number'}
@@ -74,12 +76,12 @@ export default function Replacer({ title }: ToolComponentProps) {
)
},
{
- title: 'Repetitions Delimiter',
+ title: t('repeat.repetitionsDelimiter'),
component: (
updateField('delimiter', val)}
type={'text'}
@@ -98,15 +100,18 @@ export default function Replacer({ title }: ToolComponentProps) {
input={input}
setInput={setInput}
inputComponent={
-
+
}
resultComponent={
-
+
}
toolInfo={{
- title: 'Repeat text',
- description:
- 'This tool allows you to repeat a given text multiple times with an optional separator.'
+ title: t('repeat.toolInfo.title'),
+ description: t('repeat.toolInfo.description')
}}
exampleCards={exampleCards}
/>
diff --git a/src/pages/tools/string/repeat/meta.ts b/src/pages/tools/string/repeat/meta.ts
index fb021cd..7128a33 100644
--- a/src/pages/tools/string/repeat/meta.ts
+++ b/src/pages/tools/string/repeat/meta.ts
@@ -2,13 +2,16 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('string', {
- name: 'Repeat text',
path: 'repeat',
- shortDescription: 'Repeat text multiple times',
+
icon: 'material-symbols-light:replay',
- description:
- 'This tool allows you to repeat a given text multiple times with an optional separator.',
+
keywords: ['text', 'repeat'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:repeat.title',
+ description: 'string:repeat.description',
+ shortDescription: 'string:repeat.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/reverse/index.tsx b/src/pages/tools/string/reverse/index.tsx
index b017b79..8406c65 100644
--- a/src/pages/tools/string/reverse/index.tsx
+++ b/src/pages/tools/string/reverse/index.tsx
@@ -12,6 +12,7 @@ import ToolExamples, {
import { ToolComponentProps } from '@tools/defineTool';
import { FormikProps } from 'formik';
import ToolContent from '@components/ToolContent';
+import { useTranslation } from 'react-i18next';
const initialValues = {
multiLine: true,
@@ -58,6 +59,7 @@ const exampleCards: CardExampleType[] = [
];
export default function Reverse({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -74,27 +76,27 @@ export default function Reverse({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Reversal options',
+ title: t('reverse.reversalOptions'),
component: [
updateField('multiLine', val)}
/>,
updateField('emptyItems', val)}
/>,
updateField('trim', val)}
/>
]
@@ -109,9 +111,15 @@ export default function Reverse({ title }: ToolComponentProps) {
compute={computeExternal}
input={input}
setInput={setInput}
- inputComponent={ }
+ inputComponent={
+
+ }
resultComponent={
-
+
}
exampleCards={exampleCards}
/>
diff --git a/src/pages/tools/string/reverse/meta.ts b/src/pages/tools/string/reverse/meta.ts
index faee92c..9dfdb73 100644
--- a/src/pages/tools/string/reverse/meta.ts
+++ b/src/pages/tools/string/reverse/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('string', {
- name: 'Reverse',
path: 'reverse',
icon: 'material-symbols-light:swap-horiz',
- description:
- "World's simplest browser-based utility for reversing text. Input any text and get it instantly reversed, character by character. Perfect for creating mirror text, analyzing palindromes, or playing with text patterns. Preserves spaces and special characters while reversing.",
- shortDescription: 'Reverse any text character by character',
+
keywords: ['reverse'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:reverse.title',
+ description: 'string:reverse.description',
+ shortDescription: 'string:reverse.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/rot13/index.tsx b/src/pages/tools/string/rot13/index.tsx
index eae341f..ca0e848 100644
--- a/src/pages/tools/string/rot13/index.tsx
+++ b/src/pages/tools/string/rot13/index.tsx
@@ -5,6 +5,7 @@ import ToolTextResult from '@components/result/ToolTextResult';
import { rot13 } from './service';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
+import { useTranslation } from 'react-i18next';
type InitialValuesType = Record;
@@ -30,6 +31,7 @@ const exampleCards: CardExampleType[] = [
];
export default function Rot13({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -41,15 +43,20 @@ export default function Rot13({ title }: ToolComponentProps) {
+
+ }
+ resultComponent={
+
}
- resultComponent={ }
initialValues={initialValues}
getGroups={null}
toolInfo={{
- title: 'What Is ROT13?',
- description:
- 'ROT13 (rotate by 13 places) is a simple letter substitution cipher that replaces a letter with the 13th letter after it in the alphabet. ROT13 is a special case of the Caesar cipher which was developed in ancient Rome. Because there are 26 letters in the English alphabet, ROT13 is its own inverse; that is, to undo ROT13, the same algorithm is applied, so the same action can be used for encoding and decoding.'
+ title: t('rot13.toolInfo.title'),
+ description: t('rot13.toolInfo.description')
}}
exampleCards={exampleCards}
input={input}
diff --git a/src/pages/tools/string/rot13/meta.ts b/src/pages/tools/string/rot13/meta.ts
index 2031a92..3f11c6d 100644
--- a/src/pages/tools/string/rot13/meta.ts
+++ b/src/pages/tools/string/rot13/meta.ts
@@ -3,12 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('string', {
- name: 'Rot13',
+ i18n: {
+ name: 'string:rot13.title',
+ description: 'string:rot13.description',
+ shortDescription: 'string:rot13.shortDescription'
+ },
+
path: 'rot13',
icon: 'hugeicons:encrypt',
- description:
- 'A simple tool to encode or decode text using the ROT13 cipher, which replaces each letter with the letter 13 positions after it in the alphabet.',
- shortDescription: 'Encode or decode text using ROT13 cipher.',
+
keywords: ['rot13'],
userTypes: ['Developers', 'CyberSec', 'Students'],
component: lazy(() => import('./index'))
diff --git a/src/pages/tools/string/rotate/index.tsx b/src/pages/tools/string/rotate/index.tsx
index df19411..cb4fea5 100644
--- a/src/pages/tools/string/rotate/index.tsx
+++ b/src/pages/tools/string/rotate/index.tsx
@@ -10,6 +10,7 @@ import { GetGroupsType } from '@components/options/ToolOptions';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import SimpleRadio from '@components/options/SimpleRadio';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
+import { useTranslation } from 'react-i18next';
interface InitialValuesType {
step: string;
@@ -63,6 +64,7 @@ const exampleCards: CardExampleType[] = [
];
export default function Rotate({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -79,29 +81,29 @@ export default function Rotate({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Rotation Options',
+ title: t('rotate.rotationOptions'),
component: (
updateField('step', val)}
- description={'Number of positions to rotate'}
+ description={t('rotate.stepDescription')}
type="number"
/>
updateField('direction', 'right')}
checked={values.direction === 'right'}
- title={'Rotate Right'}
+ title={t('rotate.rotateRight')}
/>
updateField('direction', 'left')}
checked={values.direction === 'left'}
- title={'Rotate Left'}
+ title={t('rotate.rotateLeft')}
/>
updateField('multiLine', checked)}
- title={'Process as multi-line text (rotate each line separately)'}
+ title={t('rotate.processAsMultiLine')}
/>
)
@@ -112,15 +114,20 @@ export default function Rotate({ title }: ToolComponentProps) {
+
+ }
+ resultComponent={
+
}
- resultComponent={ }
initialValues={initialValues}
getGroups={getGroups}
toolInfo={{
- title: 'String Rotation',
- description:
- 'This tool allows you to rotate characters in a string by a specified number of positions. You can rotate to the left or right, and process multi-line text by rotating each line separately. String rotation is useful for simple text transformations, creating patterns, or implementing basic encryption techniques.'
+ title: t('rotate.toolInfo.title'),
+ description: t('rotate.toolInfo.description')
}}
exampleCards={exampleCards}
input={input}
diff --git a/src/pages/tools/string/rotate/meta.ts b/src/pages/tools/string/rotate/meta.ts
index c0b6a99..f06e63b 100644
--- a/src/pages/tools/string/rotate/meta.ts
+++ b/src/pages/tools/string/rotate/meta.ts
@@ -3,12 +3,15 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('string', {
- name: 'Rotate',
+ i18n: {
+ name: 'string:rotate.title',
+ description: 'string:rotate.description',
+ shortDescription: 'string:rotate.shortDescription'
+ },
+
path: 'rotate',
icon: 'carbon:rotate',
- description:
- 'A tool to rotate characters in a string by a specified number of positions. Shift characters left or right while maintaining their relative order.',
- shortDescription: 'Shift characters in text by position.',
+
keywords: ['rotate'],
userTypes: ['General Users', 'Students', 'Developers'],
component: lazy(() => import('./index'))
diff --git a/src/pages/tools/string/split/index.tsx b/src/pages/tools/string/split/index.tsx
index b147e32..4961fda 100644
--- a/src/pages/tools/string/split/index.tsx
+++ b/src/pages/tools/string/split/index.tsx
@@ -11,6 +11,8 @@ import ToolExamples, {
import { ToolComponentProps } from '@tools/defineTool';
import { FormikProps } from 'formik';
import ToolContent from '@components/ToolContent';
+import { useTranslation } from 'react-i18next';
+import { ParseKeys } from 'i18next';
const initialValues = {
splitSeparatorType: 'symbol' as SplitOperatorType,
@@ -24,55 +26,45 @@ const initialValues = {
charAfterChunk: ''
};
const splitOperators: {
- title: string;
- description: string;
+ title: ParseKeys<'string'>;
+ description: ParseKeys<'string'>;
type: SplitOperatorType;
}[] = [
{
- title: 'Use a Symbol for Splitting',
- description:
- 'Character that will be used to\n' +
- 'break text into parts.\n' +
- '(Space by default.)',
+ title: 'split.symbolTitle',
+ description: 'split.symbolDescription',
type: 'symbol'
},
{
- title: 'Use a Regex for Splitting',
+ title: 'split.regexTitle',
type: 'regex',
- description:
- 'Regular expression that will be\n' +
- 'used to break text into parts.\n' +
- '(Multiple spaces by default.)'
+ description: 'split.regexDescription'
},
{
- title: 'Use Length for Splitting',
- description:
- 'Number of symbols that will be\n' + 'put in each output chunk.',
+ title: 'split.lengthTitle',
+ description: 'split.lengthDescription',
type: 'length'
},
{
- title: 'Use a Number of Chunks',
- description: 'Number of chunks of equal\n' + 'length in the output.',
+ title: 'split.chunksTitle',
+ description: 'split.chunksDescription',
type: 'chunks'
}
];
const outputOptions: {
- description: string;
+ description: ParseKeys<'string'>;
accessor: keyof typeof initialValues;
}[] = [
{
- description:
- 'Character that will be put\n' +
- 'between the split chunks.\n' +
- '(It\'s newline "\\n" by default.)',
+ description: 'split.outputSeparatorDescription',
accessor: 'outputSeparator'
},
{
- description: 'Character before each chunk',
+ description: 'split.charBeforeChunkDescription',
accessor: 'charBeforeChunk'
},
{
- description: 'Character after each chunk',
+ description: 'split.charAfterChunkDescription',
accessor: 'charAfterChunk'
}
];
@@ -132,6 +124,7 @@ easy`,
];
export default function SplitText({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -170,18 +163,20 @@ export default function SplitText({ title }: ToolComponentProps) {
title={title}
input={input}
inputComponent={ }
- resultComponent={ }
+ resultComponent={
+
+ }
initialValues={initialValues}
getGroups={({ values, updateField }) => [
{
- title: 'Split separator options',
+ title: t('split.splitSeparatorOptions'),
component: splitOperators.map(({ title, description, type }) => (
updateField('splitSeparatorType', type)}
onTextChange={(val) => updateField(`${type}Value`, val)}
@@ -189,13 +184,13 @@ export default function SplitText({ title }: ToolComponentProps) {
))
},
{
- title: 'Output separator options',
+ title: t('split.outputSeparatorOptions'),
component: outputOptions.map((option) => (
updateField(option.accessor, value)}
- description={option.description}
+ description={t(option.description)}
/>
))
}
diff --git a/src/pages/tools/string/split/meta.ts b/src/pages/tools/string/split/meta.ts
index 68f3960..6970a3d 100644
--- a/src/pages/tools/string/split/meta.ts
+++ b/src/pages/tools/string/split/meta.ts
@@ -3,13 +3,15 @@ import { lazy } from 'react';
export const tool = defineTool('string', {
path: 'split',
- name: 'Text splitter',
- icon: 'material-symbols-light:arrow-split',
- description:
- "World's simplest browser-based utility for splitting text. Load your text in the input form on the left and you'll automatically get pieces of this text on the right. Powerful, free, and fast. Load text โ get chunks.",
- shortDescription: 'Quickly split a text',
- longDescription: 'Quickly split a text',
- keywords: ['text', 'split'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+
+ icon: 'material-symbols-light:call-split',
+
+ keywords: ['split'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:split.title',
+ description: 'string:split.description',
+ shortDescription: 'string:split.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/statistic/index.tsx b/src/pages/tools/string/statistic/index.tsx
index 4ca3059..c803174 100644
--- a/src/pages/tools/string/statistic/index.tsx
+++ b/src/pages/tools/string/statistic/index.tsx
@@ -10,6 +10,7 @@ import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
+import { useTranslation } from 'react-i18next';
const initialValues: InitialValuesType = {
emptyLines: false,
@@ -216,6 +217,7 @@ export default function Truncate({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -228,49 +230,45 @@ export default function Truncate({
updateField
}) => [
{
- title: 'Delimiters Options',
+ title: t('statistic.delimitersOptions'),
component: (
updateField('sentenceDelimiters', val)}
- placeholder="e.g. ., !, ?, ..."
- description={
- 'Enter custom characters used to delimit sentences in your language (separated by comma) or leave it blank for default.'
- }
+ placeholder={t('statistic.sentenceDelimitersPlaceholder')}
+ description={t('statistic.sentenceDelimitersDescription')}
/>
updateField('wordDelimiters', val)}
- placeholder="eg. \\s.,;:!?\โยซยป()โฆ"
- description={
- 'Enter custom Regex to count Words or leave it blank for default.'
- }
+ placeholder={t('statistic.wordDelimitersPlaceholder')}
+ description={t('statistic.wordDelimitersDescription')}
/>
)
},
{
- title: 'Statistics Options',
+ title: t('statistic.statisticsOptions'),
component: (
updateField('wordCount', value)}
- title="Word Frequency Analysis"
- description="Count how often each word appears in the text"
+ title={t('statistic.wordFrequencyAnalysis')}
+ description={t('statistic.wordFrequencyAnalysisDescription')}
/>
updateField('characterCount', value)}
- title="Character Frequency Analysis"
- description="Count how often each character appears in the text"
+ title={t('statistic.characterFrequencyAnalysis')}
+ description={t('statistic.characterFrequencyAnalysisDescription')}
/>
updateField('emptyLines', value)}
- title="Include Empty Lines"
- description="Include blank lines when counting lines"
+ title={t('statistic.includeEmptyLines')}
+ description={t('statistic.includeEmptyLinesDescription')}
/>
)
@@ -286,12 +284,19 @@ export default function Truncate({
input={input}
setInput={setInput}
inputComponent={
-
+
}
resultComponent={
-
+
}
- toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
+ toolInfo={{
+ title: t('statistic.toolInfo.title', { title }),
+ description: longDescription
+ }}
exampleCards={exampleCards}
/>
);
diff --git a/src/pages/tools/string/statistic/meta.ts b/src/pages/tools/string/statistic/meta.ts
index c3a32d6..b7b7821 100644
--- a/src/pages/tools/string/statistic/meta.ts
+++ b/src/pages/tools/string/statistic/meta.ts
@@ -2,15 +2,16 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('string', {
- name: 'Text Statistics',
path: 'statistics',
- shortDescription: 'Get statistics about your text',
+
icon: 'fluent:document-landscape-data-24-filled',
- description:
- 'Load your text in the input form on the left and you will automatically get statistics about your text on the right.',
- longDescription:
- 'This tool provides various statistics about the text you input, including the number of lines, words, and characters. You can also choose to include empty lines in the count. it can count words and characters based on custom delimiters, allowing for flexible text analysis. Additionally, it can provide frequency statistics for words and characters, helping you understand the distribution of terms in your text.',
+
keywords: ['text', 'statistics', 'count', 'lines', 'words', 'characters'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:statistic.title',
+ description: 'string:statistic.description',
+ shortDescription: 'string:statistic.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/text-replacer/index.tsx b/src/pages/tools/string/text-replacer/index.tsx
index ee99fe0..3908f62 100644
--- a/src/pages/tools/string/text-replacer/index.tsx
+++ b/src/pages/tools/string/text-replacer/index.tsx
@@ -10,6 +10,7 @@ import { initialValues, InitialValuesType } from './initialValues';
import ToolContent from '@components/ToolContent';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
+import { useTranslation } from 'react-i18next';
const exampleCards: CardExampleType[] = [
{
@@ -60,6 +61,7 @@ const exampleCards: CardExampleType[] = [
];
export default function Replacer({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -72,16 +74,16 @@ export default function Replacer({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Search text',
+ title: t('textReplacer.searchText'),
component: (
updateField('mode', 'text')}
checked={values.mode === 'text'}
- title={'Find This Pattern in Text'}
+ title={t('textReplacer.findPatternInText')}
/>
updateField('searchValue', val)}
type={'text'}
@@ -89,12 +91,10 @@ export default function Replacer({ title }: ToolComponentProps) {
updateField('mode', 'regexp')}
checked={values.mode === 'regexp'}
- title={'Find a Pattern Using a RegExp'}
+ title={t('textReplacer.findPatternUsingRegexp')}
/>
updateField('searchRegexp', val)}
type={'text'}
@@ -103,12 +103,12 @@ export default function Replacer({ title }: ToolComponentProps) {
)
},
{
- title: 'Replace Text',
+ title: t('textReplacer.replaceText'),
component: (
updateField('replaceValue', val)}
type={'text'}
@@ -128,18 +128,17 @@ export default function Replacer({ title }: ToolComponentProps) {
setInput={setInput}
inputComponent={
}
resultComponent={
-
+
}
toolInfo={{
- title: 'Text Replacer',
- description:
- 'Easily replace specific text in your content with this simple, browser-based tool. Just input your text, set the text you want to replace and the replacement value, and instantly get the updated version.'
+ title: t('textReplacer.toolInfo.title'),
+ description: t('textReplacer.toolInfo.description')
}}
exampleCards={exampleCards}
/>
diff --git a/src/pages/tools/string/text-replacer/meta.ts b/src/pages/tools/string/text-replacer/meta.ts
index 77649b7..d677374 100644
--- a/src/pages/tools/string/text-replacer/meta.ts
+++ b/src/pages/tools/string/text-replacer/meta.ts
@@ -2,12 +2,16 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('string', {
- name: 'Text Replacer',
+ i18n: {
+ name: 'string:textReplacer.title',
+ description: 'string:textReplacer.description',
+ shortDescription: 'string:textReplacer.shortDescription'
+ },
+
path: 'replacer',
- shortDescription: 'Quickly replace text in your content',
+
icon: 'material-symbols-light:find-replace',
- description:
- 'Easily replace specific text in your content with this simple, browser-based tool. Just input your text, set the text you want to replace and the replacement value, and instantly get the updated version.',
+
keywords: ['text', 'replace'],
userTypes: ['General Users', 'Students', 'Developers'],
component: lazy(() => import('./index'))
diff --git a/src/pages/tools/string/to-morse/index.tsx b/src/pages/tools/string/to-morse/index.tsx
index 866fb93..f50e547 100644
--- a/src/pages/tools/string/to-morse/index.tsx
+++ b/src/pages/tools/string/to-morse/index.tsx
@@ -4,6 +4,7 @@ import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
import { compute } from './service';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
+import { useTranslation } from 'react-i18next';
const initialValues = {
dotSymbol: '.',
@@ -11,6 +12,7 @@ const initialValues = {
};
export default function ToMorse() {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
const computeOptions = (optionsValues: typeof initialValues, input: any) => {
@@ -20,33 +22,31 @@ export default function ToMorse() {
return (
}
- resultComponent={ }
+ resultComponent={
+
+ }
getGroups={({ values, updateField }) => [
{
- title: 'Short Signal',
+ title: t('toMorse.shortSignal'),
component: (
updateField('dotSymbol', val)}
/>
)
},
{
- title: 'Long Signal',
+ title: t('toMorse.longSignal'),
component: (
updateField('dashSymbol', val)}
/>
diff --git a/src/pages/tools/string/to-morse/meta.ts b/src/pages/tools/string/to-morse/meta.ts
index 05e0736..53ffce8 100644
--- a/src/pages/tools/string/to-morse/meta.ts
+++ b/src/pages/tools/string/to-morse/meta.ts
@@ -3,13 +3,14 @@ import { lazy } from 'react';
// import image from '@assets/text.png';
export const tool = defineTool('string', {
- name: 'String To morse',
path: 'to-morse',
icon: 'arcticons:morse',
- description:
- "World's simplest browser-based utility for converting text to Morse code. Load your text in the input form on the left and you'll instantly get Morse code in the output area. Powerful, free, and fast. Load text โ get Morse code.",
- shortDescription: 'Quickly encode text to morse',
keywords: ['to', 'morse'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:toMorse.title',
+ description: 'string:toMorse.description',
+ shortDescription: 'string:toMorse.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/truncate/index.tsx b/src/pages/tools/string/truncate/index.tsx
index 8f60b6a..399054e 100644
--- a/src/pages/tools/string/truncate/index.tsx
+++ b/src/pages/tools/string/truncate/index.tsx
@@ -11,6 +11,7 @@ import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
import SimpleRadio from '@components/options/SimpleRadio';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
+import { useTranslation } from 'react-i18next';
const exampleCards: CardExampleType[] = [
{
@@ -67,6 +68,7 @@ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
];
export default function Truncate({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -79,31 +81,31 @@ export default function Truncate({ title }: ToolComponentProps) {
updateField
}) => [
{
- title: 'Truncation Side',
+ title: t('truncate.truncationSide'),
component: (
updateField('truncationSide', 'right')}
checked={values.truncationSide === 'right'}
- title={'Right-side Truncation'}
- description={'Remove characters from the end of the text.'}
+ title={t('truncate.rightSideTruncation')}
+ description={t('truncate.rightSideDescription')}
/>
updateField('truncationSide', 'left')}
checked={values.truncationSide === 'left'}
- title={'Left-side Truncation'}
- description={'Remove characters from the start of the text.'}
+ title={t('truncate.leftSideTruncation')}
+ description={t('truncate.leftSideDescription')}
/>
)
},
{
- title: 'Length and Lines',
+ title: t('truncate.lengthAndLines'),
component: (
updateField('maxLength', val)}
type={'number'}
@@ -111,27 +113,25 @@ export default function Truncate({ title }: ToolComponentProps) {
updateField('lineByLine', val)}
checked={values.lineByLine}
- title={'Line-by-line Truncating'}
- description={'Truncate each line separately.'}
+ title={t('truncate.lineByLineTruncating')}
+ description={t('truncate.lineByLineDescription')}
/>
)
},
{
- title: 'Suffix and Affix',
+ title: t('truncate.suffixAndAffix'),
component: (
updateField('addIndicator', val)}
checked={values.addIndicator}
- title={'Add Truncation Indicator'}
+ title={t('truncate.addTruncationIndicator')}
description={''}
/>
updateField('indicator', val)}
type={'text'}
@@ -150,15 +150,18 @@ export default function Truncate({ title }: ToolComponentProps) {
input={input}
setInput={setInput}
inputComponent={
-
+
}
resultComponent={
-
+
}
toolInfo={{
- title: 'Truncate text',
- description:
- 'Load your text in the input form on the left and you will automatically get truncated text on the right.'
+ title: t('truncate.toolInfo.title'),
+ description: t('truncate.toolInfo.description')
}}
exampleCards={exampleCards}
/>
diff --git a/src/pages/tools/string/truncate/meta.ts b/src/pages/tools/string/truncate/meta.ts
index 2bec54e..38541fc 100644
--- a/src/pages/tools/string/truncate/meta.ts
+++ b/src/pages/tools/string/truncate/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('string', {
- name: 'Truncate text',
path: 'truncate',
- shortDescription: 'Truncate your text easily',
- icon: 'material-symbols-light:short-text',
- description:
- 'Load your text in the input form on the left and you will automatically get truncated text on the right.',
- keywords: ['text', 'truncate'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols-light:content-cut',
+
+ keywords: ['truncate'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:truncate.title',
+ description: 'string:truncate.description',
+ shortDescription: 'string:truncate.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/string/uppercase/index.tsx b/src/pages/tools/string/uppercase/index.tsx
index e234cda..a09713f 100644
--- a/src/pages/tools/string/uppercase/index.tsx
+++ b/src/pages/tools/string/uppercase/index.tsx
@@ -5,6 +5,7 @@ import { UppercaseInput } from './service';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
import ToolContent from '@components/ToolContent';
+import { useTranslation } from 'react-i18next';
const initialValues = {};
@@ -35,6 +36,7 @@ const exampleCards: CardExampleType[] = [
];
export default function Uppercase({ title }: ToolComponentProps) {
+ const { t } = useTranslation('string');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -53,9 +55,15 @@ export default function Uppercase({ title }: ToolComponentProps) {
compute={computeExternal}
input={input}
setInput={setInput}
- inputComponent={ }
+ inputComponent={
+
+ }
resultComponent={
-
+
}
exampleCards={exampleCards}
/>
diff --git a/src/pages/tools/string/uppercase/meta.ts b/src/pages/tools/string/uppercase/meta.ts
index 52e6fbb..23d4363 100644
--- a/src/pages/tools/string/uppercase/meta.ts
+++ b/src/pages/tools/string/uppercase/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('string', {
- name: 'Uppercase',
path: 'uppercase',
- icon: 'material-symbols-light:text-fields',
- description:
- "World's simplest browser-based utility for converting text to uppercase. Just input your text and it will be automatically converted to all capital letters. Perfect for creating headlines, emphasizing text, or standardizing text format. Supports various text formats and preserves special characters.",
- shortDescription: 'Convert text to uppercase letters',
+ icon: 'material-symbols-light:format-textdirection-l-to-r',
+
keywords: ['uppercase'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'string:uppercase.title',
+ description: 'string:uppercase.description',
+ shortDescription: 'string:uppercase.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/time/check-leap-years/index.tsx b/src/pages/tools/time/check-leap-years/index.tsx
index 99672bd..b960f14 100644
--- a/src/pages/tools/time/check-leap-years/index.tsx
+++ b/src/pages/tools/time/check-leap-years/index.tsx
@@ -6,6 +6,7 @@ import ToolTextResult from '@components/result/ToolTextResult';
import { GetGroupsType } from '@components/options/ToolOptions';
import { CardExampleType } from '@components/examples/ToolExamples';
import { checkLeapYear } from './service';
+import { useTranslation } from 'react-i18next';
const initialValues = {};
@@ -56,6 +57,7 @@ export default function ConvertDaysToHours({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('time');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -75,7 +77,10 @@ export default function ConvertDaysToHours({
getGroups={getGroups}
setInput={setInput}
compute={compute}
- toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
+ toolInfo={{
+ title: t('checkLeapYears.toolInfo.title', { title }),
+ description: longDescription
+ }}
exampleCards={exampleCards}
/>
);
diff --git a/src/pages/tools/time/check-leap-years/meta.ts b/src/pages/tools/time/check-leap-years/meta.ts
index 05dc96a..203cd45 100644
--- a/src/pages/tools/time/check-leap-years/meta.ts
+++ b/src/pages/tools/time/check-leap-years/meta.ts
@@ -3,13 +3,14 @@ import { lazy } from 'react';
export const tool = defineTool('time', {
path: 'check-leap-years',
- name: 'Check Leap Years',
- icon: 'arcticons:calendar-simple-29',
- description:
- ' You can check if a given calendar year is a leap year. You can enter one or many different years into the input field with one date per line and get the answer to the test question of whether the given year is a leap year.',
- shortDescription: 'Check if a year is a leap year',
- keywords: ['check', 'leap', 'years'],
- longDescription: `This is a quick online utility for testing if the given year is a leap year. Just as a reminder, a leap year has 366 days, which is one more day than a common year. This extra day is added to the month of February and it falls on February 29th. There's a simple mathematical formula for calculating if the given year is a leap year. Leap years are those years that are divisible by 4 but not divisible by 100, as well as years that are divisible by 100 and 400 simultaneously. Our algorithm checks each input year using this formula and outputs the year's status. For example, if you enter the value "2025" as input, the program will display "2025 is not a leap year.", and for the value "2028", the status will be "2028 is a leap year.". You can also enter multiple years as the input in a column and get a matching column of statuses as the output.`,
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+ icon: 'material-symbols:calendar-month',
+
+ keywords: ['leap', 'year', 'calendar', 'date'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'time:checkLeapYears.title',
+ description: 'time:checkLeapYears.description',
+ shortDescription: 'time:checkLeapYears.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/time/convert-days-to-hours/index.tsx b/src/pages/tools/time/convert-days-to-hours/index.tsx
index 96f200e..b8f83c1 100644
--- a/src/pages/tools/time/convert-days-to-hours/index.tsx
+++ b/src/pages/tools/time/convert-days-to-hours/index.tsx
@@ -8,6 +8,7 @@ import { GetGroupsType } from '@components/options/ToolOptions';
import { CardExampleType } from '@components/examples/ToolExamples';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import { convertDaysToHours } from './service';
+import { useTranslation } from 'react-i18next';
const initialValues = {
hoursFlag: false
@@ -18,7 +19,7 @@ const exampleCards: CardExampleType[] = [
title: 'Full Days to Hours',
description:
'This example calculates how many hours there are in 1 day, in one week (7 days), in one month (30 days), and in even longer time periods. To see all the results at once, we enter each individual day value on a new line. We also use the "days" suffix in the input and add the "hours" suffix to the output.',
- sampleText: `1 day
+ sampleText: `1 day
7 days
30 days
90 days
@@ -62,6 +63,7 @@ export default function ConvertDaysToHours({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('time');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -74,14 +76,14 @@ export default function ConvertDaysToHours({
updateField
}) => [
{
- title: 'Hours Name',
+ title: t('convertDaysToHours.hoursName'),
component: (
updateField('hoursFlag', val)}
checked={values.hoursFlag}
- title={'Add Hours Name'}
- description={'Append the string hours to output values'}
+ title={t('convertDaysToHours.addHoursName')}
+ description={t('convertDaysToHours.addHoursNameDescription')}
/>
)
@@ -98,7 +100,10 @@ export default function ConvertDaysToHours({
getGroups={getGroups}
setInput={setInput}
compute={compute}
- toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
+ toolInfo={{
+ title: t('convertDaysToHours.toolInfo.title'),
+ description: t('convertDaysToHours.toolInfo.description')
+ }}
exampleCards={exampleCards}
/>
);
diff --git a/src/pages/tools/time/convert-days-to-hours/meta.ts b/src/pages/tools/time/convert-days-to-hours/meta.ts
index 3a8f62b..f624ce6 100644
--- a/src/pages/tools/time/convert-days-to-hours/meta.ts
+++ b/src/pages/tools/time/convert-days-to-hours/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('time', {
- name: 'Convert days to hours',
path: 'convert-days-to-hours',
icon: 'material-symbols:schedule',
- description:
- 'Convert days to hours with simple calculations. Useful for time tracking and scheduling.',
- shortDescription: 'Convert days to hours easily.',
- keywords: ['days', 'hours', 'convert', 'time', 'calculation'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+
+ keywords: ['days', 'hours', 'convert', 'time'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'time:convertDaysToHours.title',
+ description: 'time:convertDaysToHours.description',
+ shortDescription: 'time:convertDaysToHours.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/time/convert-hours-to-days/meta.ts b/src/pages/tools/time/convert-hours-to-days/meta.ts
index 8fdb28d..d30b528 100644
--- a/src/pages/tools/time/convert-hours-to-days/meta.ts
+++ b/src/pages/tools/time/convert-hours-to-days/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('time', {
- name: 'Convert hours to days',
path: 'convert-hours-to-days',
icon: 'material-symbols:schedule',
- description:
- 'Convert hours to days with simple calculations. Useful for time tracking and scheduling.',
- shortDescription: 'Convert hours to days easily.',
- keywords: ['hours', 'days', 'convert', 'time', 'calculation'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+
+ keywords: ['hours', 'days', 'convert', 'time'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'time:convertHoursToDays.title',
+ description: 'time:convertHoursToDays.description',
+ shortDescription: 'time:convertHoursToDays.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/time/convert-seconds-to-time/index.tsx b/src/pages/tools/time/convert-seconds-to-time/index.tsx
index 026fdd3..0e5d10d 100644
--- a/src/pages/tools/time/convert-seconds-to-time/index.tsx
+++ b/src/pages/tools/time/convert-seconds-to-time/index.tsx
@@ -8,6 +8,7 @@ import { GetGroupsType } from '@components/options/ToolOptions';
import { CardExampleType } from '@components/examples/ToolExamples';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import { convertSecondsToTime } from './service';
+import { useTranslation } from 'react-i18next';
const initialValues = {
paddingFlag: false
@@ -68,6 +69,7 @@ export default function SecondsToTime({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('time');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -80,14 +82,14 @@ export default function SecondsToTime({
updateField
}) => [
{
- title: 'Time Padding',
+ title: t('convertSecondsToTime.timePadding'),
component: (
updateField('paddingFlag', val)}
checked={values.paddingFlag}
- title={'Add Padding'}
- description={'Add zero padding to hours, minutes, and seconds.'}
+ title={t('convertSecondsToTime.addPadding')}
+ description={t('convertSecondsToTime.addPaddingDescription')}
/>
)
@@ -104,7 +106,10 @@ export default function SecondsToTime({
getGroups={getGroups}
setInput={setInput}
compute={compute}
- toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
+ toolInfo={{
+ title: t('convertSecondsToTime.toolInfo.title', { title }),
+ description: longDescription
+ }}
exampleCards={exampleCards}
/>
);
diff --git a/src/pages/tools/time/convert-seconds-to-time/meta.ts b/src/pages/tools/time/convert-seconds-to-time/meta.ts
index 2801ac5..fee7203 100644
--- a/src/pages/tools/time/convert-seconds-to-time/meta.ts
+++ b/src/pages/tools/time/convert-seconds-to-time/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('time', {
- name: 'Convert seconds to time',
path: 'convert-seconds-to-time',
icon: 'material-symbols:schedule',
- description:
- 'Convert seconds to readable time format (HH:MM:SS). Useful for time calculations and formatting.',
- shortDescription: 'Convert seconds to time format (HH:MM:SS)',
- keywords: ['seconds', 'time', 'convert', 'format', 'HH:MM:SS'],
- userTypes: ['General Users', 'Students'],
- component: lazy(() => import('./index'))
+
+ keywords: ['seconds', 'time', 'convert', 'format'],
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'time:convertSecondsToTime.title',
+ description: 'time:convertSecondsToTime.description',
+ shortDescription: 'time:convertSecondsToTime.shortDescription',
+ userTypes: ['General Users', 'Students']
+ }
});
diff --git a/src/pages/tools/time/convert-time-to-seconds/index.tsx b/src/pages/tools/time/convert-time-to-seconds/index.tsx
index d7bae7e..be48eb5 100644
--- a/src/pages/tools/time/convert-time-to-seconds/index.tsx
+++ b/src/pages/tools/time/convert-time-to-seconds/index.tsx
@@ -5,6 +5,7 @@ import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
import { CardExampleType } from '@components/examples/ToolExamples';
import { convertTimetoSeconds } from './service';
+import { useTranslation } from 'react-i18next';
const initialValues = {};
type InitialValuesType = typeof initialValues;
@@ -75,6 +76,7 @@ export default function TimeToSeconds({
title,
longDescription
}: ToolComponentProps) {
+ const { t } = useTranslation('time');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
@@ -92,7 +94,10 @@ export default function TimeToSeconds({
getGroups={null}
setInput={setInput}
compute={compute}
- toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
+ toolInfo={{
+ title: t('convertTimeToSeconds.toolInfo.title', { title }),
+ description: longDescription
+ }}
exampleCards={exampleCards}
/>
);
diff --git a/src/pages/tools/time/convert-time-to-seconds/meta.ts b/src/pages/tools/time/convert-time-to-seconds/meta.ts
index cbc4e92..fd4d039 100644
--- a/src/pages/tools/time/convert-time-to-seconds/meta.ts
+++ b/src/pages/tools/time/convert-time-to-seconds/meta.ts
@@ -2,13 +2,15 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('time', {
- name: 'Convert time to seconds',
path: 'convert-time-to-seconds',
icon: 'material-symbols:schedule',
- description:
- 'Convert time format (HH:MM:SS) to total seconds. Useful for time calculations and programming.',
- shortDescription: 'Convert time format (HH:MM:SS) to seconds',
+
keywords: ['time', 'seconds', 'convert', 'format', 'HH:MM:SS'],
- userTypes: ['General Users', 'Students', 'Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'time:convertTimeToSeconds.title',
+ description: 'time:convertTimeToSeconds.description',
+ shortDescription: 'time:convertTimeToSeconds.shortDescription',
+ userTypes: ['General Users', 'Students', 'Developers']
+ }
});
diff --git a/src/pages/tools/time/crontab-guru/meta.ts b/src/pages/tools/time/crontab-guru/meta.ts
index 66c842b..5b901f9 100644
--- a/src/pages/tools/time/crontab-guru/meta.ts
+++ b/src/pages/tools/time/crontab-guru/meta.ts
@@ -2,12 +2,8 @@ import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('time', {
- name: 'Crontab explainer',
path: 'crontab-guru',
- icon: 'mdi:calendar-clock',
- description:
- 'Parse, validate, and explain crontab expressions in plain English.',
- shortDescription: 'Crontab expression parser and explainer',
+ icon: 'material-symbols:schedule',
keywords: [
'crontab',
'cron',
@@ -18,8 +14,11 @@ export const tool = defineTool('time', {
'parser',
'explain'
],
- longDescription:
- 'Enter a crontab expression (like "35 16 * * 0-5") to get a human-readable explanation and validation. Useful for understanding and debugging cron schedules. Inspired by crontab.guru.',
- userTypes: ['Developers'],
- component: lazy(() => import('./index'))
+ component: lazy(() => import('./index')),
+ i18n: {
+ name: 'time:crontabGuru.title',
+ description: 'time:crontabGuru.description',
+ shortDescription: 'time:crontabGuru.shortDescription',
+ userTypes: ['Developers']
+ }
});
diff --git a/src/pages/tools/time/time-between-dates/index.tsx b/src/pages/tools/time/time-between-dates/index.tsx
index 94491b9..7caef08 100644
--- a/src/pages/tools/time/time-between-dates/index.tsx
+++ b/src/pages/tools/time/time-between-dates/index.tsx
@@ -11,6 +11,7 @@ import {
} from './service';
import * as Yup from 'yup';
import { CardExampleType } from '@components/examples/ToolExamples';
+import { useTranslation } from 'react-i18next';
type TimeUnit =
| 'milliseconds'
@@ -120,11 +121,12 @@ const exampleCards: CardExampleType[] = [
];
export default function TimeBetweenDates() {
+ const { t } = useTranslation('time');
const [result, setResult] = useState('');
return (
[
{
- title: 'Start Date & Time',
+ title: t('timeBetweenDates.startDateTime'),
component: (