mirror of
https://github.com/CorentinTh/it-tools.git
synced 2024-12-26 01:31:30 +08:00
Compare commits
45 commits
ba84e82a8e
...
f0c255d2f2
Author | SHA1 | Date | |
---|---|---|---|
|
f0c255d2f2 | ||
|
12a974de42 | ||
|
07e53f0e2f | ||
|
08d977b8cd | ||
|
63fbd3b45c | ||
|
b47d132839 | ||
|
0b1b98f93e | ||
|
ea8c4ed077 | ||
|
ae1363937b | ||
|
c7b80fbc78 | ||
|
131497322d | ||
|
f836666417 | ||
|
aa8cba96de | ||
|
5732483fc2 | ||
|
bd184d934d | ||
|
7ca5933178 | ||
|
f962c416a3 | ||
|
1c35ac3704 | ||
|
72517002f3 | ||
|
f5c4ab19bc | ||
|
67094980c9 | ||
|
87984e2081 | ||
|
318fb6efb9 | ||
|
f1a5489e21 | ||
|
e1b4f9aafe | ||
|
76a19d218d | ||
|
b430baef40 | ||
|
dd4b7e687b | ||
|
30144aa3f5 | ||
|
e876d03608 | ||
|
81cf6b5483 | ||
|
a0bc3468b2 | ||
|
5a7b0f9636 | ||
|
b59942ad9f | ||
|
38d568798c | ||
|
9dfd347edf | ||
|
33e5294a94 | ||
|
2852c30e1f | ||
|
124284278f | ||
|
a7992340f7 | ||
|
2c2fb216e3 | ||
|
221ddfa75c | ||
|
cb5b462e11 | ||
|
9eac9cb2a9 | ||
|
23f82d956a |
76 changed files with 3406 additions and 529 deletions
34
.github/ISSUE_TEMPLATE/bug-report.md
vendored
34
.github/ISSUE_TEMPLATE/bug-report.md
vendored
|
@ -1,34 +0,0 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve our tools
|
||||
title: '[BUG] '
|
||||
labels: bug
|
||||
assignees: CorentinTh
|
||||
---
|
||||
|
||||
**Which tool is impacted?**
|
||||
Example: the token generator
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Configuration (please complete the following information):**
|
||||
|
||||
- Device: [e.g. iPhone6, ]
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
48
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
48
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
name: 🐞 Bug Report
|
||||
description: File a bug report.
|
||||
labels: ['bug', 'triage']
|
||||
assignees:
|
||||
- CorentinTh
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
- type: textarea
|
||||
id: bug-description
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!
|
||||
placeholder: Bug description
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Also tell us, what did you expect to happen? If you have a screenshot, you can paste it here.
|
||||
placeholder: Tell us what you see!
|
||||
value: 'A bug happened!'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: System information
|
||||
description: What is you environment? You can use the `npx envinfo --system --browsers` command to get this information.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: app-type
|
||||
attributes:
|
||||
label: Where did you encounter the bug?
|
||||
options:
|
||||
- Public app (it-tools.tech)
|
||||
- A self hosted
|
||||
- Other (installations, docker, etc.)
|
||||
validations:
|
||||
required: true
|
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
blank_issues_enabled: false
|
56
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
56
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
name: 🚀 New feature proposal
|
||||
description: Propose a new feature/enhancement or tool idea for IT-Tools
|
||||
labels: ['enhancement', 'triage']
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for your interest in the project and taking the time to fill out this feature report!
|
||||
|
||||
- type: dropdown
|
||||
id: request-type
|
||||
attributes:
|
||||
label: What type of request is this?
|
||||
options:
|
||||
- New tool idea
|
||||
- New feature for an existing tool
|
||||
- Deployment or CI/CD improvement
|
||||
- Self-hosting improvement
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: feature-description
|
||||
attributes:
|
||||
label: Clear and concise description of the feature you are proposing
|
||||
description: A clear and concise description of what the feature is.
|
||||
placeholder: 'Example: a token generator tool'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: alternative
|
||||
attributes:
|
||||
label: Is their example of this tool in the wild?
|
||||
description: Provide link to already existing tool (like websites, apps, cli, ...) or npm packages that could be used or provide inspiration for the feature.
|
||||
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Any other context or screenshots about the feature request here.
|
||||
|
||||
- type: checkboxes
|
||||
id: checkboxes
|
||||
attributes:
|
||||
label: Validations
|
||||
description: Before submitting the issue, please make sure you do the following
|
||||
options:
|
||||
- label: Check the feature is not already implemented in the project.
|
||||
required: true
|
||||
- label: Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
|
||||
required: true
|
||||
- label: Check that the feature can be implemented in a client side only app (IT-Tools is client side only, no server).
|
||||
required: true
|
19
.github/ISSUE_TEMPLATE/new-tool-request.md
vendored
19
.github/ISSUE_TEMPLATE/new-tool-request.md
vendored
|
@ -1,19 +0,0 @@
|
|||
---
|
||||
name: New tool request
|
||||
about: Suggest a new tool idea
|
||||
title: '[NEW TOOL]'
|
||||
labels: new tool
|
||||
assignees: CorentinTh
|
||||
---
|
||||
|
||||
**What tool do you want?**
|
||||
Example: a token generator
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Is their example of this tool in the wild?**
|
||||
Provide link to already existing tool or npm packages if any exists
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the feature request here.
|
13
.github/ISSUE_TEMPLATE/other-request.md
vendored
13
.github/ISSUE_TEMPLATE/other-request.md
vendored
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
name: Other request
|
||||
about: Any request that does not concern a tool creation, a new feature request on a tool or a bug
|
||||
title: '[OTHER] '
|
||||
labels:
|
||||
assignees: CorentinTh
|
||||
---
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the feature request here.
|
13
.github/ISSUE_TEMPLATE/tool-improvement.md
vendored
13
.github/ISSUE_TEMPLATE/tool-improvement.md
vendored
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
name: Tool improvement
|
||||
about: Improvement on an existing tool
|
||||
title: '[TOOL IMPROVEMENT]'
|
||||
labels: enhancement
|
||||
assignees: CorentinTh
|
||||
---
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the feature request here.
|
BIN
.github/logo-dark.png
vendored
Normal file
BIN
.github/logo-dark.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
BIN
.github/logo-white.png
vendored
Normal file
BIN
.github/logo-white.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
BIN
.github/logo.png
vendored
BIN
.github/logo.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 7.8 KiB |
10
.github/sponsor-banner.svg
vendored
Normal file
10
.github/sponsor-banner.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 57 KiB |
69
.github/workflows/codeql-analysis.yml
vendored
69
.github/workflows/codeql-analysis.yml
vendored
|
@ -1,69 +0,0 @@
|
|||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ dev ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ dev ]
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
2
.github/workflows/docker-nightly-release.yml
vendored
2
.github/workflows/docker-nightly-release.yml
vendored
|
@ -32,7 +32,7 @@ jobs:
|
|||
- run: corepack enable
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
|
|
2
.github/workflows/releases.yml
vendored
2
.github/workflows/releases.yml
vendored
|
@ -61,7 +61,7 @@ jobs:
|
|||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
|
|
109
CHANGELOG.md
109
CHANGELOG.md
|
@ -2,9 +2,77 @@
|
|||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## Version 2024.10.22-7ca5933
|
||||
|
||||
### Features
|
||||
- **new tool**: Regex Tester (and Cheatsheet) (#1030) (f5c4ab1)
|
||||
- **new tool**: Markdown to HTML (#916) (87984e2)
|
||||
- **new-tool**: add email normalizer (#1243) (318fb6e)
|
||||
- **new tools**: JSON to XML and XML to JSON (#1231) (f1a5489)
|
||||
- **lorem-ipsum**: add button to refresh text lorem-ipsum (#1213) (e1b4f9a)
|
||||
- **base64**: Base64 enhancements (#905) (30144aa)
|
||||
|
||||
### Bug fixes
|
||||
- **favorites**: store favorites regardless of languages (#1202) (7ca5933)
|
||||
- **emoji-picker**: debounced search input (#1181) (76a19d2)
|
||||
- **format-transformer**: set overflow for output area width (#787) (b430bae)
|
||||
- **jwt-parser**: prevent UI overflow on small screen (#1095) (dd4b7e6)
|
||||
|
||||
### Refactoring
|
||||
- **regex-tester**: better description (7251700)
|
||||
|
||||
### Chores
|
||||
- **sponsors**: fern sponsor banners (#1314) (f962c41)
|
||||
- **readme**: updated logos (#1294) (6709498)
|
||||
|
||||
### Documentation
|
||||
- **author**: updated author links (#1316) (1c35ac3)
|
||||
|
||||
## Version 2024.05.13-a0bc346
|
||||
|
||||
### Features
|
||||
- **i18n**: added German translation (#1038) (2c2fb21)
|
||||
- **new tool**: Outlook Safelink Decoder (#911) (d3b32cc)
|
||||
- **new tool**: ascii art generator (#886) (fe349ad)
|
||||
- **i18n**: get locales on build (#880) (dc04615)
|
||||
- **i18n**: added vi tools translations (#876) (079aa21)
|
||||
- **i18n**: added zh tools translations (#874) (9c6b122)
|
||||
- **i18n**: added missing locale files in tools (#863) (7f5fa00)
|
||||
- **i18n**: added vietnamese language (#859) (1334bff)
|
||||
- **i18n**: added spanish language (#854) (85b50bb)
|
||||
- **i18n**: added portuguese language (#813) (c65ffb6)
|
||||
- **i18n**: added ukrainian language (#827) (693f362)
|
||||
- **new-tool**: yaml formater (#779) (fc06f01)
|
||||
- **new-tool**: added unicode conversion utilities (#858) (c46207f)
|
||||
|
||||
### Bug fixes
|
||||
- **language**: English language cleanup (#1036) (221ddfa)
|
||||
- **url-encoder, validation**: typo in validation of url-encoder.vue #1024 (cb5b462)
|
||||
- **integer base converter**: support bigint (#872) (9eac9cb)
|
||||
- **bcrypt tool**: allow salt rounds up to 100 (#987) (23f82d9)
|
||||
|
||||
### Refactoring
|
||||
- **lint**: removed extra semi (33e5294)
|
||||
- **auto-imports**: regen auto imports (1242842)
|
||||
- **home**: lightened tool cards (#882) (a07806c)
|
||||
- **home**: removed n-grid to prevent layout shift (#881) (10e56b3)
|
||||
- **i18n**: added locales per tool (#861) (95698cb)
|
||||
|
||||
### Chores
|
||||
- **issues**: prevent empty issues (#1078) (a0bc346)
|
||||
- **issues**: removed old issue templates (#1077) (5a7b0f9)
|
||||
- **node**: upgraded node version in CI workflows (b59942a)
|
||||
- **version**: release 2024.05.10-33e5294 (38d5687)
|
||||
- **issues**: improved issues template (2852c30)
|
||||
- **issues**: improved bug issue template (#1046) (a799234)
|
||||
|
||||
### Documentation
|
||||
- **changelog**: update changelog for 2024.05.10-33e5294 (9dfd347)
|
||||
|
||||
## Version 2023.12.21-5ed3693
|
||||
|
||||
### Features
|
||||
|
||||
- **i18n**: improve chinese i18n (#757) (2e56641)
|
||||
- **i18n**: add tooltip and favoriteButton i18n (#756) (a1037cf)
|
||||
- **i18n**: add Chinese translation base (#718) (8f99eb6)
|
||||
|
@ -12,6 +80,7 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
- **new tool**: numeronym generator (#729) (e07e2ae)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **jwt-parser**: jwt claim array support (#799) (5ed3693)
|
||||
- **camera-recorder**: stop camera on navigation (#782) (80e46c9)
|
||||
- **doc**: updated create new tool command in readme (#762) (7a70dbb)
|
||||
|
@ -20,6 +89,7 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
- **eta**: corrected example (#737) (821cbea)
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **about, i18n**: improved i18n dx with markdown (#753) (bd3edcb)
|
||||
- **token, i18n**: complete fr translation (#752) (de1ee69)
|
||||
- **uuid generator**: uuid version picker (#751) (38586ca)
|
||||
|
@ -29,6 +99,7 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
- **bcrypt**: fix input label align (#721) (093ff31)
|
||||
|
||||
### Chores
|
||||
|
||||
- **deps**: switched from oui to oui-data for mac address lookup (#693) (0fe9a20)
|
||||
- **deps**: update unocss monorepo to ^0.57.0 (#638) (2e396d8)
|
||||
- **docker**: added armv7 plateform for docker releases (#722) (fe1de8c)
|
||||
|
@ -36,19 +107,23 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
## Version 2023.11.02-7d94e11
|
||||
|
||||
### Features
|
||||
|
||||
- **i18n**: language selector (#710) (e86fd96)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **dockerfile**: revert replacement of nginx image with non-privileged one (#716) (7d94e11)
|
||||
- **encryption**: alert on decryption error (#711) (02b0d0d)
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **math-evaluator**: improved description (e87f4b1)
|
||||
- **math-evaluator**: improved search and UX (#713) (58de897)
|
||||
|
||||
## Version 2023.11.01-e164afb
|
||||
|
||||
### Features
|
||||
|
||||
- **command-palette**: clear prompt on palette close (#708) (d013696)
|
||||
- **command-palette**: added about page in command palette (99b1eb9)
|
||||
- **new tool**: random MAC address generator (#657) (cc3425d)
|
||||
|
@ -67,11 +142,13 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
- **new tool**: text diff and comparator (#588) (81bfe57)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **deps**: fix issue on slugify (#593) (#673) (720201a)
|
||||
- **deps**: update dependency monaco-editor to ^0.43.0 (#620) (e371ef7)
|
||||
- **deps**: update dependency sql-formatter to v13 (#606) (c7d4562)
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **ui**: better ui demo preview menu (#664) (015c673)
|
||||
- **color-converter**: improved color-converter UX (#701) (abb8335)
|
||||
- **docker**: improved docker config (#700) (020e9cb)
|
||||
|
@ -88,6 +165,7 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
- **bcrypt**: fix typo (#604) (e18bae1)
|
||||
|
||||
### Chores
|
||||
|
||||
- **deps**: clean unused dependencies (#709) (e164afb)
|
||||
- **deps**: update docker/setup-qemu-action action to v3 (#627) (4365226)
|
||||
- **deps**: update docker/setup-buildx-action action to v3 (#626) (57ecda1)
|
||||
|
@ -102,19 +180,23 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
- **deps**: update dependency typescript to ~5.2.0 (#587) (f3e14fc)
|
||||
|
||||
### Doc
|
||||
|
||||
- **readme**: added contributors list (#622) (557b304)
|
||||
- **hosting**: added cloudron in the other hosting solutions section (#589) (06c3547)
|
||||
|
||||
## Version 2023.08.21-6f93cba
|
||||
|
||||
### Features
|
||||
|
||||
- **copy**: support legacy copy to clipboard for older browser (#581) (6f93cba)
|
||||
- **new tool**: string obfuscator (#575) (c58d6e3)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **deps**: update dependency sql-formatter to v12 (#520) (2bcb77a)
|
||||
|
||||
### Chores
|
||||
|
||||
- **deps**: switched to fucking typescript v5 (#501) (76b2761)
|
||||
- **deps**: update dependency @antfu/eslint-config to ^0.40.0 (#552) (6ff9a01)
|
||||
- **deps**: update dependency prettier to v3 (#564) (a2b9b15)
|
||||
|
@ -124,6 +206,7 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
## Version 2023.08.16-9bd4ad4
|
||||
|
||||
### Features
|
||||
|
||||
- **Case Converter**: Add lowercase and uppercase (#534) (7b6232a)
|
||||
- **new tool**: emoji picker (#551) (93f7cf0)
|
||||
- **ui**: added c-select in the ui lib (#550) (dfa1ba8)
|
||||
|
@ -144,6 +227,7 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
- **base64-string-converter**: switch to encode and decode url safe base64 strings (#392) (0b20f1c)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **deps**: update dependency uuid to v9 (#566) (5e12991)
|
||||
- **deps**: update dependency mathjs to v11 (#519) (7924456)
|
||||
- **deps**: update dependency @vueuse/router to v10 (#516) (ea0f27c)
|
||||
|
@ -163,6 +247,7 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
- **ipv4-converter**: removed readonly on input (7aed9c5)
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **navbar**: consistent spacing in navbar buttons (#507) (30f88fc)
|
||||
- **ui**: remove n-text (#506) (72c98a3)
|
||||
- **ui**: replaced some n-input to c-input (#505) (05ea545)
|
||||
|
@ -175,6 +260,7 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
- **ui**: replaced some n-input with c-input-text (f7fc779)
|
||||
|
||||
### Chores
|
||||
|
||||
- **deps**: update dependency vitest to ^0.34.0 (#562) (9bd4ad4)
|
||||
- **deps**: update dependency node to v18.17.1 (#560) (65a9474)
|
||||
- **deps**: update dependency unocss to ^0.55.0 (#561) (85cc7a8)
|
||||
|
@ -215,47 +301,58 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
- **lint**: switched to a better lint config (33c9b66)
|
||||
|
||||
### Refacor
|
||||
|
||||
- **transformers**: use monospace font for JSON and SQL text areas (#476) (ba4876d)
|
||||
|
||||
### Documentation
|
||||
|
||||
- **ide**: updated vscode extensions settings (#472) (847323c)
|
||||
|
||||
### Chors
|
||||
|
||||
- **deps**: updated vueuse dependency version (8515c24)
|
||||
|
||||
## Version 2023.05.14-77f2efc
|
||||
|
||||
### Features
|
||||
|
||||
- **list-converter**: a small converter who deals with column based data and do some stuff with it (#387) (83a7b3b)
|
||||
- **new tool**: phone parser and normalizer (ce3150c)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **phone-parser**: use default country code (a43c546)
|
||||
- **home**: prevent weird blue border on card (3f6c8f0)
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **ui**: replaced some n-input with c-input-text (77f2efc)
|
||||
|
||||
### Chores
|
||||
|
||||
- **issues**: updated new tool request issue template (edae4c6)
|
||||
|
||||
### Ui-lib
|
||||
|
||||
- **new-component**: added text input component in the c-lib (aad8d84)
|
||||
- **button**: size variants (401f13f)
|
||||
|
||||
## Version 2023.04.23-92bd835
|
||||
|
||||
### Features
|
||||
|
||||
- **ui-lib**: demo pages for c-lib components (92bd835)
|
||||
- **new-tool**: diff of two json objects (362f2fa)
|
||||
- **ipv4-range-expander**: expands a given IPv4 start and end address to a valid IPv4 subnet (#366) (df989e2)
|
||||
- **date converter**: auto focus main input (6d22025)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **ts**: cleaned legacy typechecking warning (e88c1d5)
|
||||
- **mac-address-lookup**: added copy handler on button click (c311e38)
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **ui-lib**: prevent c-button to shrink (61ece23)
|
||||
- **ui**: replaced naive ui cards with custom ones (f080933)
|
||||
- **clean**: removed unused lodash import (bb32513)
|
||||
|
@ -265,48 +362,60 @@ All notable changes to this project will be documented in this file. See [standa
|
|||
## Version 2023.04.14-dbad773
|
||||
|
||||
### Features
|
||||
|
||||
- **new-tool**: http status codes (8355bd2)
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **uuid-generator**: prevent NaN in quantity (6fb4994)
|
||||
|
||||
### Chores
|
||||
|
||||
- **release**: create a github release on new version (dbad773)
|
||||
- **version**: reset CHANGELOG content to support new format (85cb0ff)
|
||||
|
||||
## Version 2023.04.14-f9b77b7
|
||||
|
||||
### Features
|
||||
|
||||
- **new-tool**: http status codes (8355bd2)
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **uuid-generator**: prevent NaN in quantity (6fb4994)
|
||||
|
||||
### Chores
|
||||
|
||||
- **release**: create a github release on new version (f9b77b7)
|
||||
- **version**: reset CHANGELOG content to support new format (85cb0ff)
|
||||
|
||||
## Version 2023.04.14-2f0d239
|
||||
|
||||
### Features
|
||||
|
||||
- **new-tool**: http status codes (8355bd2)
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **uuid-generator**: prevent NaN in quantity (6fb4994)
|
||||
|
||||
### Chores
|
||||
|
||||
- **release**: create a github release on new version (2f0d239)
|
||||
- **version**: reset CHANGELOG content to support new format (85cb0ff)
|
||||
|
||||
## Version 2023.04.14-474cae4
|
||||
|
||||
### Features
|
||||
|
||||
- **new-tool**: http status codes (8355bd2)
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **uuid-generator**: prevent NaN in quantity (6fb4994)
|
||||
|
||||
### Chores
|
||||
|
||||
- **release**: create a github release on new version (474cae4)
|
||||
- **version**: reset CHANGELOG content to support new format (85cb0ff)
|
||||
|
||||
|
|
14
README.md
14
README.md
|
@ -1,7 +1,15 @@
|
|||
![logo](.github/logo.png)
|
||||
<picture>
|
||||
<source srcset="./.github/logo-dark.png" media="(prefers-color-scheme: light)">
|
||||
<source srcset="./.github/logo-white.png" media="(prefers-color-scheme: dark)">
|
||||
<img src="./.github/logo-dark.png" alt="logo">
|
||||
</picture>
|
||||
|
||||
Useful tools for developer and people working in IT. [Have a look !](https://it-tools.tech).
|
||||
|
||||
## Sponsors
|
||||
|
||||
[![Renderize banner](./.github/sponsor-banner.svg)](https://renderize.tech?utm_source=it-tools&utm_medium=readme)
|
||||
|
||||
## Functionalities and roadmap
|
||||
|
||||
Please check the [issues](https://github.com/CorentinTh/it-tools/issues) to see if some feature listed to be implemented.
|
||||
|
@ -109,11 +117,11 @@ It will create a directory in `src/tools` with the correct files, and a the impo
|
|||
|
||||
Big thanks to all the people who have already contributed!
|
||||
|
||||
[![contributors](https://contrib.rocks/image?repo=corentinth/it-tools)](https://github.com/corentinth/it-tools/graphs/contributors)
|
||||
[![contributors](https://contrib.rocks/image?repo=corentinth/it-tools&refresh=1)](https://github.com/corentinth/it-tools/graphs/contributors)
|
||||
|
||||
## Credits
|
||||
|
||||
Coded with ❤️ by [Corentin Thomasset](//corentin-thomasset.fr).
|
||||
Coded with ❤️ by [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=readme).
|
||||
|
||||
This project is continuously deployed using [vercel.com](https://vercel.com).
|
||||
|
||||
|
|
17
components.d.ts
vendored
17
components.d.ts
vendored
|
@ -72,6 +72,7 @@ declare module '@vue/runtime-core' {
|
|||
DockerRunToDockerComposeConverter: typeof import('./src/tools/docker-run-to-docker-compose-converter/docker-run-to-docker-compose-converter.vue')['default']
|
||||
DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default']
|
||||
Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default']
|
||||
EmailNormalizer: typeof import('./src/tools/email-normalizer/email-normalizer.vue')['default']
|
||||
EmojiCard: typeof import('./src/tools/emoji-picker/emoji-card.vue')['default']
|
||||
EmojiGrid: typeof import('./src/tools/emoji-picker/emoji-grid.vue')['default']
|
||||
EmojiPicker: typeof import('./src/tools/emoji-picker/emoji-picker.vue')['default']
|
||||
|
@ -84,6 +85,7 @@ declare module '@vue/runtime-core' {
|
|||
HashText: typeof import('./src/tools/hash-text/hash-text.vue')['default']
|
||||
HmacGenerator: typeof import('./src/tools/hmac-generator/hmac-generator.vue')['default']
|
||||
'Home.page': typeof import('./src/pages/Home.page.vue')['default']
|
||||
HtmlCleaner: typeof import('./src/tools/html-cleaner/html-cleaner.vue')['default']
|
||||
HtmlEntities: typeof import('./src/tools/html-entities/html-entities.vue')['default']
|
||||
HtmlWysiwygEditor: typeof import('./src/tools/html-wysiwyg-editor/html-wysiwyg-editor.vue')['default']
|
||||
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
|
||||
|
@ -110,6 +112,7 @@ declare module '@vue/runtime-core' {
|
|||
JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default']
|
||||
JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default']
|
||||
JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default']
|
||||
JsonToXml: typeof import('./src/tools/json-to-xml/json-to-xml.vue')['default']
|
||||
JsonToYaml: typeof import('./src/tools/json-to-yaml-converter/json-to-yaml.vue')['default']
|
||||
JsonViewer: typeof import('./src/tools/json-viewer/json-viewer.vue')['default']
|
||||
JwtParser: typeof import('./src/tools/jwt-parser/jwt-parser.vue')['default']
|
||||
|
@ -119,6 +122,7 @@ declare module '@vue/runtime-core' {
|
|||
LoremIpsumGenerator: typeof import('./src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue')['default']
|
||||
MacAddressGenerator: typeof import('./src/tools/mac-address-generator/mac-address-generator.vue')['default']
|
||||
MacAddressLookup: typeof import('./src/tools/mac-address-lookup/mac-address-lookup.vue')['default']
|
||||
MarkdownToHtml: typeof import('./src/tools/markdown-to-html/markdown-to-html.vue')['default']
|
||||
MathEvaluator: typeof import('./src/tools/math-evaluator/math-evaluator.vue')['default']
|
||||
MenuBar: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar.vue')['default']
|
||||
MenuBarItem: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar-item.vue')['default']
|
||||
|
@ -127,24 +131,19 @@ declare module '@vue/runtime-core' {
|
|||
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
||||
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
||||
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
||||
NCode: typeof import('naive-ui')['NCode']
|
||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
||||
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||
NDivider: typeof import('naive-ui')['NDivider']
|
||||
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||
NGi: typeof import('naive-ui')['NGi']
|
||||
NGrid: typeof import('naive-ui')['NGrid']
|
||||
NH1: typeof import('naive-ui')['NH1']
|
||||
NH3: typeof import('naive-ui')['NH3']
|
||||
NIcon: typeof import('naive-ui')['NIcon']
|
||||
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
||||
NLabel: typeof import('naive-ui')['NLabel']
|
||||
NLayout: typeof import('naive-ui')['NLayout']
|
||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||
NMenu: typeof import('naive-ui')['NMenu']
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NSpin: typeof import('naive-ui')['NSpin']
|
||||
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
||||
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
||||
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
||||
|
@ -154,11 +153,16 @@ declare module '@vue/runtime-core' {
|
|||
PhoneParserAndFormatter: typeof import('./src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue')['default']
|
||||
QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default']
|
||||
RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default']
|
||||
RegexMemo: typeof import('./src/tools/regex-memo/regex-memo.vue')['default']
|
||||
'RegexMemo.content': typeof import('./src/tools/regex-memo/regex-memo.content.md')['default']
|
||||
RegexTester: typeof import('./src/tools/regex-tester/regex-tester.vue')['default']
|
||||
ResultRow: typeof import('./src/tools/ipv4-range-expander/result-row.vue')['default']
|
||||
RomanNumeralConverter: typeof import('./src/tools/roman-numeral-converter/roman-numeral-converter.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default']
|
||||
SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default']
|
||||
SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default']
|
||||
SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default']
|
||||
SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default']
|
||||
SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default']
|
||||
|
@ -185,6 +189,7 @@ declare module '@vue/runtime-core' {
|
|||
UuidGenerator: typeof import('./src/tools/uuid-generator/uuid-generator.vue')['default']
|
||||
WifiQrCodeGenerator: typeof import('./src/tools/wifi-qr-code-generator/wifi-qr-code-generator.vue')['default']
|
||||
XmlFormatter: typeof import('./src/tools/xml-formatter/xml-formatter.vue')['default']
|
||||
XmlToJson: typeof import('./src/tools/xml-to-json/xml-to-json.vue')['default']
|
||||
YamlToJson: typeof import('./src/tools/yaml-to-json-converter/yaml-to-json.vue')['default']
|
||||
YamlToToml: typeof import('./src/tools/yaml-to-toml/yaml-to-toml.vue')['default']
|
||||
YamlViewer: typeof import('./src/tools/yaml-viewer/yaml-viewer.vue')['default']
|
||||
|
|
456
locales/de.yml
Normal file
456
locales/de.yml
Normal file
|
@ -0,0 +1,456 @@
|
|||
'404':
|
||||
notFound: 404 Nicht gefunden
|
||||
sorry: Entschuldigung, diese Seite scheint nicht zu existieren
|
||||
maybe: >-
|
||||
Vielleicht macht der Cache etwas Seltsames. Mit einem erzwungenen Neuladen
|
||||
versuchen?
|
||||
backHome: Zurück zur Startseite
|
||||
home:
|
||||
categories:
|
||||
newestTools: Neueste Tools
|
||||
favoriteTools: Deine Lieblingstools
|
||||
allTools: Alle Tools
|
||||
favoritesDndToolTip: 'Ziehen und Ablegen, um Favoriten neu zu ordnen'
|
||||
subtitle: Praktische Tools für Entwickler
|
||||
toggleMenu: Menü umschalten
|
||||
home: Startseite
|
||||
uiLib: UI-Bibliothek
|
||||
support: Unterstütze die Entwicklung von IT-Tools
|
||||
buyMeACoffee: Kauf mir einen Kaffee
|
||||
follow:
|
||||
title: Magst du IT-Tools?
|
||||
p1: Gib uns einen Stern auf
|
||||
githubRepository: IT-Tools GitHub-Repository
|
||||
p2: oder folge uns auf
|
||||
twitterXAccount: IT-Tools X-Konto
|
||||
thankYou: Vielen Dank!
|
||||
nav:
|
||||
github: GitHub-Repository
|
||||
githubRepository: IT-Tools GitHub-Repository
|
||||
twitterX: X-Konto
|
||||
twitterXAccount: IT-Tools X-Konto
|
||||
about: Über IT-Tools
|
||||
aboutLabel: Über
|
||||
darkMode: Dunkelmodus
|
||||
lightMode: Hellmodus
|
||||
mode: Wechseln zwischen dunklem/hellem Modus
|
||||
about:
|
||||
content: >
|
||||
# Über IT-Tools
|
||||
|
||||
Diese wunderbare Website, erstellt mit ❤ von [Corentin
|
||||
Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about), sammelt nützliche Tools für
|
||||
Entwickler und Menschen, die in der IT arbeiten. Wenn du sie nützlich
|
||||
findest, teile sie gerne mit Personen, von denen du denkst, dass sie sie
|
||||
ebenfalls nützlich finden könnten, und vergiss nicht, sie in deiner
|
||||
Lesezeichenleiste zu speichern!
|
||||
|
||||
IT-Tools ist Open Source (unter der GPL-3.0-Lizenz) und kostenlos und wird es
|
||||
immer sein, aber es kostet mich Geld, die Website zu hosten und den
|
||||
Domainnamen zu erneuern. Wenn du meine Arbeit unterstützen möchtest und mich
|
||||
ermutigen möchtest, mehr Tools hinzuzufügen, überlege bitte, mich durch
|
||||
[Sponsoring](https://www.buymeacoffee.com/cthmsst) zu unterstützen.
|
||||
|
||||
## Technologien
|
||||
|
||||
IT-Tools wurde mit Vue.js (Vue 3) und der Naive UI-Komponentenbibliothek
|
||||
erstellt und wird von Vercel gehostet und kontinuierlich bereitgestellt. In
|
||||
einigen Tools werden Drittanbieter-Open-Source-Bibliotheken verwendet. Du
|
||||
findest die vollständige Liste in der
|
||||
[package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json)-Datei
|
||||
des Repositorys.
|
||||
|
||||
## Einen Fehler gefunden? Ein Tool fehlt?
|
||||
|
||||
Wenn du ein Tool benötigst, das hier noch nicht vorhanden ist, und du
|
||||
denkst, dass es nützlich sein könnte, bist du herzlich eingeladen, einen
|
||||
Feature-Request im
|
||||
[Issues-Bereich](https://github.com/CorentinTh/it-tools/issues/new/choose)
|
||||
im GitHub-Repository einzureichen.
|
||||
|
||||
Und wenn du einen Fehler gefunden hast oder etwas nicht wie erwartet
|
||||
funktioniert, melde bitte einen Fehler im
|
||||
[Issues-Bereich](https://github.com/CorentinTh/it-tools/issues/new/choose)
|
||||
im GitHub-Repository.
|
||||
favoriteButton:
|
||||
remove: Aus Favoriten entfernen
|
||||
add: Zu Favoriten hinzufügen
|
||||
toolCard:
|
||||
new: Neu
|
||||
search:
|
||||
label: Suche
|
||||
tools:
|
||||
categories:
|
||||
favorite-tools: Deine Lieblingstools
|
||||
crypto: Krypto
|
||||
converter: Konverter
|
||||
web: Web
|
||||
images and videos: Bilder & Videos
|
||||
development: Entwicklung
|
||||
network: Netzwerk
|
||||
math: Mathematik
|
||||
measurement: Messung
|
||||
text: Text
|
||||
data: Daten
|
||||
password-strength-analyser:
|
||||
title: Passwortstärken-Analysator
|
||||
description: >-
|
||||
Ermittle die Stärke deines Passworts mit diesem Client-seitigen
|
||||
Passwortstärken-Analysator und Tool zur Schätzung der Knackzeit.
|
||||
chronometer:
|
||||
title: Chronometer
|
||||
description: >-
|
||||
Überwache die Dauer einer Sache. Im Grunde ein Chronometer mit einfachen
|
||||
Chronometerfunktionen.
|
||||
token-generator:
|
||||
title: Token-Generator
|
||||
description: >-
|
||||
Generiere eine zufällige Zeichenfolge mit den von dir gewünschten Zeichen,
|
||||
Groß- oder Kleinbuchstaben, Zahlen und/oder Symbolen.
|
||||
uppercase: Großbuchstaben (ABC...)
|
||||
lowercase: Kleinbuchstaben (abc...)
|
||||
numbers: Zahlen (123...)
|
||||
symbols: Symbole (!-;...)
|
||||
length: Länge
|
||||
tokenPlaceholder: Der Token ...
|
||||
copied: Token in die Zwischenablage kopiert
|
||||
button:
|
||||
copy: Kopieren
|
||||
refresh: Aktualisieren
|
||||
percentage-calculator:
|
||||
title: Prozentrechner
|
||||
description: >-
|
||||
Berechne einfach Prozentsätze von einem Wert zu einem anderen Wert oder
|
||||
von einem Prozentsatz zu einem Wert.
|
||||
svg-placeholder-generator:
|
||||
title: SVG-Platzhalter-Generator
|
||||
description: >-
|
||||
Generiere SVG-Bilder, die als Platzhalter in deinen Anwendungen verwendet
|
||||
werden können.
|
||||
json-to-csv:
|
||||
title: JSON zu CSV
|
||||
description: Konvertiere JSON mit automatischer Headererkennung in CSV.
|
||||
camera-recorder:
|
||||
title: Kamera-Rekorder
|
||||
description: Mache ein Foto oder nimm ein Video von deiner Webcam oder Kamera auf.
|
||||
keycode-info:
|
||||
title: Keycode-Info
|
||||
description: >-
|
||||
Finde den JavaScript-Keycode, den Code, den Standort und die Modifikatoren
|
||||
einer beliebigen gedrückten Taste.
|
||||
emoji-picker:
|
||||
title: Emoji-Picker
|
||||
description: >-
|
||||
Einfaches Kopieren und Einfügen von Emojis. Erhalte außerdem den Unicode-
|
||||
und Codepunkt-Wert jedes Emojis.
|
||||
color-converter:
|
||||
title: Farbkonverter
|
||||
description: >-
|
||||
Konvertiere Farben zwischen den verschiedenen Formaten (Hex, RGB, HSL und
|
||||
CSS-Name).
|
||||
bcrypt:
|
||||
title: Bcrypt
|
||||
description: >-
|
||||
Hashen und Vergleichen von Strings mit bcrypt. Bcrypt ist eine auf der
|
||||
Blowfish-Chiffre basierende Hash-Funktion.
|
||||
crontab-generator:
|
||||
title: Crontab-Generator
|
||||
description: >-
|
||||
Überprüfe und generiere Crontab und erhalte die menschenlesbare
|
||||
Beschreibung des Cron-Zeitplans.
|
||||
http-status-codes:
|
||||
title: HTTP-Statuscodes
|
||||
description: Liste aller HTTP-Statuscodes, ihrer Namen und ihrer Bedeutung.
|
||||
sql-prettify:
|
||||
title: SQL verschönern und formatieren
|
||||
description: >-
|
||||
Formatiere und verschönere deine SQL-Abfragen online (unterstützt
|
||||
verschiedene SQL-Dialekte).
|
||||
benchmark-builder:
|
||||
title: Benchmark-Builder
|
||||
description: >-
|
||||
Vergleiche ganz einfach die Ausführungszeit von Aufgaben mit diesem sehr
|
||||
einfachen Online-Benchmark-Builder.
|
||||
git-memo:
|
||||
title: Git-Spickzettel
|
||||
description: >-
|
||||
Git ist eine dezentrale Versionsverwaltungssoftware. Mit diesem
|
||||
Spickzettel hast du schnellen Zugriff auf die gängigsten Git-Befehle.
|
||||
slugify-string:
|
||||
title: Slugify String
|
||||
description: Mache einen String URL-, Dateinamen- und ID-sicher.
|
||||
encryption:
|
||||
title: Text verschlüsseln / entschlüsseln
|
||||
description: >-
|
||||
Verschlüssele und entschlüssele Klartext mithilfe von Kryptoalgorithmen
|
||||
wie AES, TripleDES, Rabbit oder RC4.
|
||||
random-port-generator:
|
||||
title: Zufälliger Port-Generator
|
||||
description: >-
|
||||
Generiere zufällige Portnummern außerhalb des Bereichs der "bekannten"
|
||||
Ports (0-1023).
|
||||
yaml-prettify:
|
||||
title: YAML verschönern und formatieren
|
||||
description: Verschönere deinen YAML-String in ein menschenlesbares Format.
|
||||
eta-calculator:
|
||||
title: ETA-Rechner
|
||||
description: >-
|
||||
Ein ETA (Estimated Time of Arrival)-Rechner, um die ungefähre Endzeit
|
||||
einer Aufgabe zu erfahren, z. B. den Zeitpunkt des Endes eines Downloads.
|
||||
roman-numeral-converter:
|
||||
title: Römische Zahlen Konverter
|
||||
description: >-
|
||||
Konvertiere römische Zahlen in Dezimalzahlen und Dezimalzahlen in römische
|
||||
Zahlen.
|
||||
hmac-generator:
|
||||
title: HMAC-Generator
|
||||
description: >-
|
||||
Berechnet einen hashbasierten Nachrichtenauthentifizierungscode (HMAC)
|
||||
unter Verwendung eines geheimen Schlüssels und deiner bevorzugten
|
||||
Hash-Funktion.
|
||||
bip39-generator:
|
||||
title: BIP39-Passphrasengenerator
|
||||
description: >-
|
||||
Generiere BIP39-Passphrasen aus vorhandener oder zufälliger Mnemonik oder
|
||||
erhalte die Mnemonik aus der Passphrase.
|
||||
base64-file-converter:
|
||||
title: Base64-Dateikonverter
|
||||
description: Konvertiere Strings, Dateien oder Bilder in ihre Base64-Repräsentation.
|
||||
list-converter:
|
||||
title: Listenkonverter
|
||||
description: >-
|
||||
Dieses Tool kann spaltenbasierte Daten verarbeiten und verschiedene
|
||||
Änderungen (transponieren, Präfix und Suffix hinzufügen, Liste umkehren,
|
||||
Liste sortieren, Werte in Kleinbuchstaben umwandeln, Werte abschneiden)
|
||||
auf jede Zeile anwenden.
|
||||
base64-string-converter:
|
||||
title: Base64-String-Encoder/Decoder
|
||||
description: Codiere und decodiere Strings einfach in ihre Base64-Repräsentation.
|
||||
toml-to-yaml:
|
||||
title: TOML zu YAML
|
||||
description: Parse und konvertiere TOML zu YAML.
|
||||
math-evaluator:
|
||||
title: Mathematischer Auswerter
|
||||
description: >-
|
||||
Ein Taschenrechner zum Auswerten mathematischer Ausdrücke. Du kannst
|
||||
Funktionen wie sqrt, cos, sin, abs usw. verwenden.
|
||||
json-to-yaml-converter:
|
||||
title: JSON zu YAML
|
||||
description: Konvertiere JSON einfach in YAML mit diesem Live-Online-Konverter.
|
||||
url-parser:
|
||||
title: URL-Parser
|
||||
description: >-
|
||||
Parse eine URL-Zeichenfolge, um alle verschiedenen Teile (Protokoll,
|
||||
Ursprung, Parameter, Port, Benutzername-Passwort usw.) zu erhalten.
|
||||
iban-validator-and-parser:
|
||||
title: IBAN-Validator und -Parser
|
||||
description: >-
|
||||
Validiere und parse IBAN-Nummern. Überprüfe, ob die IBAN gültig ist, und
|
||||
erhalte das Land, BBAN, ob es sich um eine QR-IBAN handelt und das
|
||||
IBAN-freundliche Format.
|
||||
user-agent-parser:
|
||||
title: User-Agent-Parser
|
||||
description: >-
|
||||
Erkenne und parse Browser, Engine, Betriebssystem, CPU und
|
||||
Gerätetyp/-modell aus einer User-Agent-Zeichenfolge.
|
||||
numeronym-generator:
|
||||
title: Numeronym-Generator
|
||||
description: >-
|
||||
Ein Numeronym ist ein Wort, bei dem eine Zahl verwendet wird, um eine
|
||||
Abkürzung zu bilden. Zum Beispiel ist "i18n" ein Numeronym für
|
||||
"internationalization", wobei 18 für die Anzahl der Buchstaben zwischen
|
||||
dem ersten "i" und dem letzten "n" im Wort steht.
|
||||
case-converter:
|
||||
title: Fall-Konverter
|
||||
description: >-
|
||||
Ändere den Fall eines Strings und wähle zwischen verschiedenen Formaten
|
||||
aus.
|
||||
html-entities:
|
||||
title: HTML-Entity-Escape
|
||||
description: >-
|
||||
Escape oder unescape HTML-Entitäten (ersetze <, >, &, " und ' durch ihre
|
||||
HTML-Version).
|
||||
json-prettify:
|
||||
title: JSON verschönern und formatieren
|
||||
description: Verschönere deinen JSON-String in ein menschenlesbares Format.
|
||||
docker-run-to-docker-compose-converter:
|
||||
title: Docker run zu Docker compose Konverter
|
||||
description: Wandle docker run-Befehle in docker-compose-Dateien um!
|
||||
mac-address-lookup:
|
||||
title: MAC-Adressensuche
|
||||
description: Finde den Anbieter und Hersteller eines Geräts anhand seiner MAC-Adresse.
|
||||
mime-types:
|
||||
title: MIME-Typen
|
||||
description: Konvertiere MIME-Typen in Erweiterungen und umgekehrt.
|
||||
toml-to-json:
|
||||
title: TOML zu JSON
|
||||
description: Parse und konvertiere TOML zu JSON.
|
||||
lorem-ipsum-generator:
|
||||
title: Lorem Ipsum Generator
|
||||
description: >-
|
||||
Lorem Ipsum ist ein Platzhaltertext, der häufig verwendet wird, um die
|
||||
visuelle Form eines Dokuments oder einer Schriftart ohne Verwendung von
|
||||
bedeutendem Inhalt zu demonstrieren.
|
||||
qrcode-generator:
|
||||
title: QR-Code-Generator
|
||||
description: >-
|
||||
Generiere und downloade QR-Codes für eine URL oder einfach einen Text und
|
||||
passe die Hintergrund- und Vordergrundfarben an.
|
||||
wifi-qrcode-generator:
|
||||
title: WLAN-QR-Code-Generator
|
||||
description: >-
|
||||
Generiere und lade QR-Codes für schnelle Verbindungen zu WLAN-Netzwerken
|
||||
herunter.
|
||||
xml-formatter:
|
||||
title: XML-Formatter
|
||||
description: Verschönere deinen XML-String in ein menschenlesbares Format.
|
||||
temperature-converter:
|
||||
title: Temperaturkonverter
|
||||
description: >-
|
||||
Temperaturgradumrechnungen für Kelvin, Celsius, Fahrenheit, Rankine,
|
||||
Delisle, Newton, Réaumur und Rømer.
|
||||
chmod-calculator:
|
||||
title: Chmod-Rechner
|
||||
description: >-
|
||||
Berechne deine Chmod-Berechtigungen und -Befehle mit diesem
|
||||
Online-Chmod-Rechner.
|
||||
rsa-key-pair-generator:
|
||||
title: RSA-Schlüsselpaar-Generator
|
||||
description: Generiere neue zufällige RSA-Private- und Public-Key-PEM-Zertifikate.
|
||||
html-wysiwyg-editor:
|
||||
title: HTML-WYSIWYG-Editor
|
||||
description: >-
|
||||
Online-HTML-Editor mit funktionsreichem WYSIWYG-Editor, erhalte sofort den
|
||||
Quellcode des Inhalts.
|
||||
yaml-to-toml:
|
||||
title: YAML zu TOML
|
||||
description: Parse und konvertiere YAML zu TOML.
|
||||
mac-address-generator:
|
||||
title: MAC-Adressen-Generator
|
||||
description: >-
|
||||
Gebe die Menge und das Präfix ein. MAC-Adressen werden in deiner gewählten
|
||||
Schreibweise (Groß- oder Kleinbuchstaben) generiert.
|
||||
json-diff:
|
||||
title: JSON-Unterschied
|
||||
description: Vergleiche zwei JSON-Objekte und erhalte die Unterschiede zwischen ihnen.
|
||||
jwt-parser:
|
||||
title: JWT-Parser
|
||||
description: >-
|
||||
Parse und decodiere deinen JSON-Web-Token (JWT) und zeige dessen Inhalt
|
||||
an.
|
||||
date-converter:
|
||||
title: Datum-Uhrzeit-Konverter
|
||||
description: Konvertiere Datum und Uhrzeit in verschiedene Formate.
|
||||
phone-parser-and-formatter:
|
||||
title: Telefonnummer-Parser und -Formatter
|
||||
description: >-
|
||||
Parse, validiere und formatiere Telefonnummern. Erhalte Informationen zur
|
||||
Telefonnummer, wie z. B. die Landesvorwahl, den Typ usw.
|
||||
ipv4-subnet-calculator:
|
||||
title: IPv4-Subnetzrechner
|
||||
description: >-
|
||||
Parse deine IPv4-CIDR-Blöcke und erhalte alle Informationen, die du über
|
||||
dein Subnetz benötigst.
|
||||
og-meta-generator:
|
||||
title: Open Graph Meta-Generator
|
||||
description: Generiere Open Graph- und Social-HTML-Metatags für deine Website.
|
||||
ipv6-ula-generator:
|
||||
title: IPv6-ULA-Generator
|
||||
description: >-
|
||||
Generiere deine eigenen lokalen, nicht routbaren IP-Adressen in deinem
|
||||
Netzwerk gemäß RFC4193.
|
||||
hash-text:
|
||||
title: Text hashen
|
||||
description: >-
|
||||
Hashe einen Text-String mit der von dir benötigten Funktion: MD5, SHA1,
|
||||
SHA256, SHA224, SHA512, SHA384, SHA3 oder RIPEMD160
|
||||
json-to-toml:
|
||||
title: JSON zu TOML
|
||||
description: Parse und konvertiere JSON zu TOML.
|
||||
device-information:
|
||||
title: Geräteinformationen
|
||||
description: >-
|
||||
Informationen zu deinem aktuellen Gerät (Bildschirmgröße, Pixelverhältnis,
|
||||
Benutzeragent, ...) erhalten.
|
||||
pdf-signature-checker:
|
||||
title: PDF-Signaturprüfer
|
||||
description: >-
|
||||
Überprüfe die Signaturen einer PDF-Datei. Eine signierte PDF-Datei enthält
|
||||
eine oder mehrere Signaturen, die verwendet werden können, um
|
||||
festzustellen, ob der Inhalt der Datei seit dem Zeitpunkt der Signierung
|
||||
geändert wurde.
|
||||
json-minify:
|
||||
title: JSON minifizieren
|
||||
description: >-
|
||||
Minifiziere und komprimiere dein JSON, indem unnötige Leerzeichen entfernt
|
||||
werden.
|
||||
ulid-generator:
|
||||
title: ULID-Generator
|
||||
description: >-
|
||||
Generiere zufällige Universally Unique Lexicographically Sortable
|
||||
Identifier (ULID).
|
||||
string-obfuscator:
|
||||
title: String-Verschleierer
|
||||
description: >-
|
||||
Verschleiere einen String (wie ein Secret, eine IBAN oder ein Token), um
|
||||
ihn weitergeben zu können und identifizierbar zu machen, ohne seinen
|
||||
Inhalt preiszugeben.
|
||||
base-converter:
|
||||
title: Ganzzahl-Basiskonverter
|
||||
description: >-
|
||||
Konvertiere Zahlen zwischen verschiedenen Basen (Dezimal, Hexadezimal,
|
||||
Binär, Oktal, Base64, ...).
|
||||
yaml-to-json-converter:
|
||||
title: YAML zu JSON
|
||||
description: Konvertiere YAML einfach in JSON mit diesem Live-Online-Konverter.
|
||||
uuid-generator:
|
||||
title: UUID-Generator
|
||||
description: >-
|
||||
Ein Universally Unique Identifier (UUID) ist eine 128-Bit-Nummer, die zur
|
||||
Identifizierung von Informationen in Computersystemen verwendet wird. Die
|
||||
Anzahl der möglichen UUIDs beträgt 16^32, was 2^128 oder etwa 3,4x10^38
|
||||
entspricht (was ziemlich viel ist!).
|
||||
ipv4-address-converter:
|
||||
title: IPv4-Adresskonverter
|
||||
description: >-
|
||||
Konvertiere eine IP-Adresse in Dezimal, Binär, Hexadezimal oder sogar in
|
||||
IPv6.
|
||||
text-statistics:
|
||||
title: Textstatistiken
|
||||
description: >-
|
||||
Informationen zu einem Text erhalten, wie die Anzahl der Zeichen, die
|
||||
Anzahl der Wörter, die Größe usw.
|
||||
text-to-nato-alphabet:
|
||||
title: Text zu NATO-Alphabet
|
||||
description: >-
|
||||
Wandle Text in das NATO-Phonetik-Alphabet für die mündliche Übermittlung
|
||||
um.
|
||||
basic-auth-generator:
|
||||
title: Basic-Auth-Generator
|
||||
description: >-
|
||||
Generiere einen Base64-Basic-Auth-Header aus einem Benutzernamen und einem
|
||||
Passwort.
|
||||
text-to-unicode:
|
||||
title: Text zu Unicode
|
||||
description: Parse und konvertiere Text in Unicode und umgekehrt.
|
||||
ipv4-range-expander:
|
||||
title: IPv4-Bereichserweiterer
|
||||
description: >-
|
||||
Bei Angabe einer Start- und End-IPv4-Adresse berechnet dieses Tool ein
|
||||
gültiges IPv4-Netzwerk mit seiner CIDR-Notation.
|
||||
text-diff:
|
||||
title: Textunterschied
|
||||
description: Vergleiche zwei Texte und sieh die Unterschiede zwischen ihnen.
|
||||
otp-generator:
|
||||
title: OTP-Code-Generator
|
||||
description: >-
|
||||
Generiere und validiere zeitbasierte OTPs (Einmalpasswörter) für
|
||||
Multi-Faktor-Authentifizierung.
|
||||
url-encoder:
|
||||
title: Kodieren/Decodieren von URL-formatierten Zeichenfolgen
|
||||
description: >-
|
||||
Kodiere zum URL-kodierten Format (auch als "prozentkodiert" bekannt) oder
|
||||
decodiere es.
|
||||
text-to-binary:
|
||||
title: Text zu ASCII-Binär
|
||||
description: Konvertiere Text in seine ASCII-Binärrepräsentation und umgekehrt.
|
101
locales/en.yml
101
locales/en.yml
|
@ -3,24 +3,25 @@ home:
|
|||
newestTools: Newest tools
|
||||
favoriteTools: 'Your favorite tools'
|
||||
allTools: 'All the tools'
|
||||
favoritesDndToolTip: 'Drag and drop to reorder favorites'
|
||||
subtitle: 'Handy tools for developers'
|
||||
toggleMenu: 'Toggle menu'
|
||||
home: Home
|
||||
uiLib: 'UI Lib'
|
||||
support: 'Support IT Tools development'
|
||||
support: 'Support IT-Tools development'
|
||||
buyMeACoffee: 'Buy me a coffee'
|
||||
follow:
|
||||
title: 'You like it-tools?'
|
||||
p1: 'Give us a star on'
|
||||
githubRepository: 'IT-Tools GitHub repository'
|
||||
p2: 'or follow us on'
|
||||
twitterAccount: 'IT-Tools Twitter account'
|
||||
thankYou: 'Thank you !'
|
||||
twitterXAccount: 'IT-Tools X account'
|
||||
thankYou: 'Thank you!'
|
||||
nav:
|
||||
github: 'GitHub repository'
|
||||
githubRepository: 'IT-Tools GitHub repository'
|
||||
twitter: 'Twitter account'
|
||||
twitterAccount: 'IT Tools Twitter account'
|
||||
twitterX: 'X account'
|
||||
twitterXAccount: 'IT Tools X account'
|
||||
about: 'About IT-Tools'
|
||||
aboutLabel: 'About'
|
||||
darkMode: 'Dark mode'
|
||||
|
@ -30,9 +31,9 @@ about:
|
|||
content: >
|
||||
# About IT-Tools
|
||||
|
||||
This wonderful website, made with ❤ by [Corentin Thomasset](https://github.com/CorentinTh) , aggregates useful tools for developer and people working in IT. If you find it useful, please feel free to share it to people you think may find it useful too and don't forget to bookmark it in your shortcut bar!
|
||||
This wonderful website, made with ❤ by [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about) , aggregates useful tools for developer and people working in IT. If you find it useful, please feel free to share it to people you think may find it useful too and don't forget to bookmark it in your shortcut bar!
|
||||
|
||||
IT Tools is open-source (under the MIT license) and free, and will always be, but it costs me money to host and renew the domain name. If you want to support my work, and encourage me to add more tools, please consider supporting by [sponsoring me](https://www.buymeacoffee.com/cthmsst).
|
||||
IT Tools is open-source (under the GPL-3.0 license) and free, and will always be, but it costs me money to host and renew the domain name. If you want to support my work, and encourage me to add more tools, please consider supporting by [sponsoring me](https://www.buymeacoffee.com/cthmsst).
|
||||
|
||||
## Technologies
|
||||
|
||||
|
@ -72,7 +73,7 @@ tools:
|
|||
|
||||
password-strength-analyser:
|
||||
title: Password strength analyser
|
||||
description: Discover the strength of your password with this client side only password strength analyser and crack time estimation tool.
|
||||
description: Discover the strength of your password with this client-side-only password strength analyser and crack time estimation tool.
|
||||
|
||||
chronometer:
|
||||
title: Chronometer
|
||||
|
@ -98,7 +99,7 @@ tools:
|
|||
|
||||
svg-placeholder-generator:
|
||||
title: SVG placeholder generator
|
||||
description: Generate svg images to use as placeholder in your applications.
|
||||
description: Generate svg images to use as a placeholder in your applications.
|
||||
|
||||
json-to-csv:
|
||||
title: JSON to CSV
|
||||
|
@ -126,11 +127,11 @@ tools:
|
|||
|
||||
crontab-generator:
|
||||
title: Crontab generator
|
||||
description: Validate and generate crontab and get the human readable description of the cron schedule.
|
||||
description: Validate and generate crontab and get the human-readable description of the cron schedule.
|
||||
|
||||
http-status-codes:
|
||||
title: HTTP status codes
|
||||
description: The list of all HTTP status codes their name and their meaning.
|
||||
description: The list of all HTTP status codes, their name, and their meaning.
|
||||
|
||||
sql-prettify:
|
||||
title: SQL prettify and format
|
||||
|
@ -142,7 +143,7 @@ tools:
|
|||
|
||||
git-memo:
|
||||
title: Git cheatsheet
|
||||
description: Git is a decentralized version management software. With this cheatsheet you will have a quick access to the most common git commands.
|
||||
description: Git is a decentralized version management software. With this cheatsheet, you will have quick access to the most common git commands.
|
||||
|
||||
slugify-string:
|
||||
title: Slugify string
|
||||
|
@ -150,7 +151,7 @@ tools:
|
|||
|
||||
encryption:
|
||||
title: Encrypt / decrypt text
|
||||
description: Encrypt and decrypt text clear text using crypto algorithm like AES, TripleDES, Rabbit or RC4.
|
||||
description: Encrypt clear text and decrypt ciphertext using crypto algorithms like AES, TripleDES, Rabbit or RC4.
|
||||
|
||||
random-port-generator:
|
||||
title: Random port generator
|
||||
|
@ -158,11 +159,11 @@ tools:
|
|||
|
||||
yaml-prettify:
|
||||
title: YAML prettify and format
|
||||
description: Prettify your YAML string to a human friendly readable format.
|
||||
description: Prettify your YAML string into a friendly, human-readable format.
|
||||
|
||||
eta-calculator:
|
||||
title: ETA calculator
|
||||
description: An ETA (Estimated Time of Arrival) calculator to know the approximate end time of a task, for example the moment of ending of a download.
|
||||
description: An ETA (Estimated Time of Arrival) calculator to determine the approximate end time of a task, for example, the end time and duration of a file download.
|
||||
|
||||
roman-numeral-converter:
|
||||
title: Roman numeral converter
|
||||
|
@ -174,11 +175,11 @@ tools:
|
|||
|
||||
bip39-generator:
|
||||
title: BIP39 passphrase generator
|
||||
description: Generate BIP39 passphrase from existing or random mnemonic, or get the mnemonic from the passphrase.
|
||||
description: Generate a BIP39 passphrase from an existing or random mnemonic, or get the mnemonic from the passphrase.
|
||||
|
||||
base64-file-converter:
|
||||
title: Base64 file converter
|
||||
description: Convert string, files or images into a it\'s base64 representation.
|
||||
description: Convert a string, file, or image into its base64 representation.
|
||||
|
||||
list-converter:
|
||||
title: List converter
|
||||
|
@ -186,7 +187,7 @@ tools:
|
|||
|
||||
base64-string-converter:
|
||||
title: Base64 string encoder/decoder
|
||||
description: Simply encode and decode string into a their base64 representation.
|
||||
description: Simply encode and decode strings into their base64 representation.
|
||||
|
||||
toml-to-yaml:
|
||||
title: TOML to YAML
|
||||
|
@ -198,15 +199,15 @@ tools:
|
|||
|
||||
json-to-yaml-converter:
|
||||
title: JSON to YAML converter
|
||||
description: Simply convert JSON to YAML with this live online converter.
|
||||
description: Simply convert JSON to YAML with this online live converter.
|
||||
|
||||
url-parser:
|
||||
title: Url parser
|
||||
description: Parse an url string to get all the different parts (protocol, origin, params, port, username-password, ...)
|
||||
title: URL parser
|
||||
description: Parse a URL into its separate constituent parts (protocol, origin, params, port, username-password, ...)
|
||||
|
||||
iban-validator-and-parser:
|
||||
title: IBAN validator and parser
|
||||
description: Validate and parse IBAN numbers. Check if IBAN is valid and get the country, BBAN, if it is a QR-IBAN and the IBAN friendly format.
|
||||
description: Validate and parse IBAN numbers. Check if an IBAN is valid and get the country, BBAN, if it is a QR-IBAN and the IBAN friendly format.
|
||||
|
||||
user-agent-parser:
|
||||
title: User-agent parser
|
||||
|
@ -218,27 +219,27 @@ tools:
|
|||
|
||||
case-converter:
|
||||
title: Case converter
|
||||
description: Change the case of a string and chose between different formats
|
||||
description: Transform the case of a string and choose between different formats
|
||||
|
||||
html-entities:
|
||||
title: Escape html entities
|
||||
description: Escape or unescape html entities (replace <,>, &, " and \' to their html version)
|
||||
title: Escape HTML entities
|
||||
description: Escape or unescape HTML entities (replace characters like <,>, &, " and \' with their HTML version)
|
||||
|
||||
json-prettify:
|
||||
title: JSON prettify and format
|
||||
description: Prettify your JSON string to a human friendly readable format.
|
||||
description: Prettify your JSON string into a friendly, human-readable format.
|
||||
|
||||
docker-run-to-docker-compose-converter:
|
||||
title: Docker run to Docker compose converter
|
||||
description: Turns docker run commands into docker-compose files!
|
||||
description: Transforms "docker run" commands into docker-compose files!
|
||||
|
||||
mac-address-lookup:
|
||||
title: MAC address lookup
|
||||
description: Find the vendor and manufacturer of a device by its MAC address.
|
||||
|
||||
mime-types:
|
||||
title: Mime types
|
||||
description: Convert mime types to extensions and vice-versa.
|
||||
title: MIME types
|
||||
description: Convert MIME types to file extensions and vice-versa.
|
||||
|
||||
toml-to-json:
|
||||
title: TOML to JSON
|
||||
|
@ -250,19 +251,19 @@ tools:
|
|||
|
||||
qrcode-generator:
|
||||
title: QR Code generator
|
||||
description: Generate and download QR-code for an url or just a text and customize the background and foreground colors.
|
||||
description: Generate and download a QR code for a URL (or just plain text), and customize the background and foreground colors.
|
||||
|
||||
wifi-qrcode-generator:
|
||||
title: WiFi QR Code generator
|
||||
description: Generate and download QR-codes for quick connections to WiFi networks.
|
||||
description: Generate and download QR codes for quick connections to WiFi networks.
|
||||
|
||||
xml-formatter:
|
||||
title: XML formatter
|
||||
description: Prettify your XML string to a human friendly readable format.
|
||||
description: Prettify your XML string into a friendly, human-readable format.
|
||||
|
||||
temperature-converter:
|
||||
title: Temperature converter
|
||||
description: Temperature degrees conversions for Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur and Rømer.
|
||||
description: Degrees temperature conversions for Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur, and Rømer.
|
||||
|
||||
chmod-calculator:
|
||||
title: Chmod calculator
|
||||
|
@ -270,11 +271,11 @@ tools:
|
|||
|
||||
rsa-key-pair-generator:
|
||||
title: RSA key pair generator
|
||||
description: Generate new random RSA private and public key pem certificates.
|
||||
description: Generate a new random RSA private and public pem certificate key pair.
|
||||
|
||||
html-wysiwyg-editor:
|
||||
title: HTML WYSIWYG editor
|
||||
description: Online HTML editor with feature-rich WYSIWYG editor, get the source code of the content immediately.
|
||||
description: Online, feature-rich WYSIWYG HTML editor which generates the source code of the content immediately.
|
||||
|
||||
yaml-to-toml:
|
||||
title: YAML to TOML
|
||||
|
@ -302,15 +303,15 @@ tools:
|
|||
|
||||
ipv4-subnet-calculator:
|
||||
title: IPv4 subnet calculator
|
||||
description: Parse your IPv4 CIDR blocks and get all the info you need about your sub network.
|
||||
description: Parse your IPv4 CIDR blocks and get all the info you need about your subnet.
|
||||
|
||||
og-meta-generator:
|
||||
title: Open graph meta generator
|
||||
description: Generate open-graph and socials html meta tags for your website.
|
||||
description: Generate open-graph and socials HTML meta tags for your website.
|
||||
|
||||
ipv6-ula-generator:
|
||||
title: IPv6 ULA generator
|
||||
description: Generate your own local, non-routable IP addresses on your network according to RFC4193.
|
||||
description: Generate your own local, non-routable IP addresses for your network according to RFC4193.
|
||||
|
||||
hash-text:
|
||||
title: Hash text
|
||||
|
@ -330,7 +331,7 @@ tools:
|
|||
|
||||
json-minify:
|
||||
title: JSON minify
|
||||
description: Minify and compress your JSON by removing unnecessary white spaces.
|
||||
description: Minify and compress your JSON by removing unnecessary whitespace.
|
||||
|
||||
ulid-generator:
|
||||
title: ULID generator
|
||||
|
@ -342,31 +343,31 @@ tools:
|
|||
|
||||
base-converter:
|
||||
title: Integer base converter
|
||||
description: Convert number between different bases (decimal, hexadecimal, binary, octal, base64, ...)
|
||||
description: Convert a number between different bases (decimal, hexadecimal, binary, octal, base64, ...)
|
||||
|
||||
yaml-to-json-converter:
|
||||
title: YAML to JSON converter
|
||||
description: Simply convert YAML to JSON with this live online converter.
|
||||
description: Simply convert YAML to JSON with this online live converter.
|
||||
|
||||
uuid-generator:
|
||||
title: UUIDs generator
|
||||
description: A Universally Unique Identifier (UUID) is a 128-bit number used to identify information in computer systems. The number of possible UUIDs is 16^32, which is 2^128 or about 3.4x10^38 (which is a lot!).
|
||||
|
||||
ipv4-address-converter:
|
||||
title: Ipv4 address converter
|
||||
description: Convert an ip address into decimal, binary, hexadecimal or event in ipv6
|
||||
title: IPv4 address converter
|
||||
description: Convert an IP address into decimal, binary, hexadecimal, or even an IPv6 representation of it.
|
||||
|
||||
text-statistics:
|
||||
title: Text statistics
|
||||
description: Get information about a text, the amount of characters, the amount of words, it\'s size, ...
|
||||
description: Get information about a text, the number of characters, the number of words, its size in bytes, ...
|
||||
|
||||
text-to-nato-alphabet:
|
||||
title: Text to NATO alphabet
|
||||
description: Transform text into NATO phonetic alphabet for oral transmission.
|
||||
description: Transform text into the NATO phonetic alphabet for oral transmission.
|
||||
|
||||
basic-auth-generator:
|
||||
title: Basic auth generator
|
||||
description: Generate a base64 basic auth header from an username and a password.
|
||||
description: Generate a base64 basic auth header from a username and password.
|
||||
|
||||
text-to-unicode:
|
||||
title: Text to Unicode
|
||||
|
@ -374,7 +375,7 @@ tools:
|
|||
|
||||
ipv4-range-expander:
|
||||
title: IPv4 range expander
|
||||
description: Given a start and an end IPv4 address this tool calculates a valid IPv4 network with its CIDR notation.
|
||||
description: Given a start and an end IPv4 address, this tool calculates a valid IPv4 subnet along with its CIDR notation.
|
||||
|
||||
text-diff:
|
||||
title: Text diff
|
||||
|
@ -385,9 +386,9 @@ tools:
|
|||
description: Generate and validate time-based OTP (one time password) for multi-factor authentication.
|
||||
|
||||
url-encoder:
|
||||
title: Encode/decode url formatted strings
|
||||
description: Encode to url-encoded format (also known as "percent-encoded") or decode from it.
|
||||
title: Encode/decode URL-formatted strings
|
||||
description: Encode text to URL-encoded format (also known as "percent-encoded"), or decode from it.
|
||||
|
||||
text-to-binary:
|
||||
title: Text to ASCII binary
|
||||
description: Convert text to its ASCII binary representation and vice versa.
|
||||
description: Convert text to its ASCII binary representation and vice-versa.
|
||||
|
|
|
@ -3,6 +3,7 @@ home:
|
|||
newestTools: Nuevas herramientas
|
||||
favoriteTools: 'Tus herramientas favoritas'
|
||||
allTools: 'Todas las herramientas'
|
||||
favoritesDndToolTip: 'Arrastra y suelta para reordenar favoritos'
|
||||
subtitle: 'Herramientas practicas para desarrolladores'
|
||||
toggleMenu: 'Toggle menu'
|
||||
home: Home
|
||||
|
@ -14,13 +15,13 @@ home:
|
|||
p1: 'Danos una estrella en'
|
||||
githubRepository: 'Repositorio de IT-Tools en GitHub'
|
||||
p2: 'o síguenos en'
|
||||
twitterAccount: 'Cuenta de twitter de IT-Tools'
|
||||
twitterXAccount: 'Cuenta de X de IT-Tools'
|
||||
thankYou: 'Muchas gracias!'
|
||||
nav:
|
||||
github: 'Repositorio en github'
|
||||
githubRepository: 'IT-Tools GitHub repository'
|
||||
twitter: 'Cuenta de Twitter'
|
||||
twitterAccount: 'Cuenta de twitter de IT Tools'
|
||||
twitterX: 'Cuenta de X'
|
||||
twitterXAccount: 'Cuenta de X de IT Tools'
|
||||
about: 'Sobre IT-Tools'
|
||||
aboutLabel: 'Sobre'
|
||||
darkMode: 'Modo obscuro'
|
||||
|
@ -30,9 +31,9 @@ about:
|
|||
content: >
|
||||
# Sobre IT-Tools
|
||||
|
||||
Este maravilloso sitio web, hecho con ❤ por [Corentin Thomasset](https://github.com/CorentinTh) , agrega herramientas útiles para desarrolladores y personas que trabajan en IT. Si lo encuentra útil, no dude en compartirlo con las personas que crea que también pueden encontrarlo útil y ¡no olvide marcarlo como favorito en su barra de accesos directos!
|
||||
Este maravilloso sitio web, hecho con ❤ por [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about) , agrega herramientas útiles para desarrolladores y personas que trabajan en IT. Si lo encuentra útil, no dude en compartirlo con las personas que crea que también pueden encontrarlo útil y ¡no olvide marcarlo como favorito en su barra de accesos directos!
|
||||
|
||||
IT Tools es de código abierto (under the MIT license) y gratis, y siempre lo será, pero me cuesta dinero alojar y renovar el nombre de dominio. Si desea apoyar mi trabajo y animarme a agregar más herramientas, considere apoyarme a través de[sponsoring me](https://www.buymeacoffee.com/cthmsst).
|
||||
IT Tools es de código abierto (under the GPL-3.0 license) y gratis, y siempre lo será, pero me cuesta dinero alojar y renovar el nombre de dominio. Si desea apoyar mi trabajo y animarme a agregar más herramientas, considere apoyarme a través de[sponsoring me](https://www.buymeacoffee.com/cthmsst).
|
||||
|
||||
## Tecnologías
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ home:
|
|||
newestTools: 'Les nouveaux outils'
|
||||
favoriteTools: 'Vos outils favoris'
|
||||
allTools: 'Tous les outils'
|
||||
favoritesDndToolTip: 'Faites glisser et déposez pour réordonner vos favoris'
|
||||
subtitle: 'Outils pour les développeurs'
|
||||
toggleMenu: 'Menu'
|
||||
home: Accueil
|
||||
|
@ -13,13 +14,13 @@ home:
|
|||
p1: 'Soutenez-nous avec une star sur'
|
||||
githubRepository: "le dépôt GitHub d'IT-Tools"
|
||||
p2: 'ou suivez-nous sur'
|
||||
twitterAccount: "le compte Twitter d'IT-Tools"
|
||||
twitterXAccount: "le compte X d'IT-Tools"
|
||||
thankYou: 'Merci !'
|
||||
nav:
|
||||
github: 'Dépôt GitHub'
|
||||
githubRepository: "Dépôt GitHub d'IT-Tools"
|
||||
twitter: 'Compte Twitter'
|
||||
twitterAccount: "Compte Twitter d'IT-Tools"
|
||||
twitterX: 'Compte X'
|
||||
twitterXAccount: "Compte X d'IT-Tools"
|
||||
about: "À propos d'IT-Tools"
|
||||
aboutLabel: 'À propos'
|
||||
darkMode: 'Mode sombre'
|
||||
|
@ -29,9 +30,9 @@ about:
|
|||
content: >
|
||||
# À propos de IT-Tools
|
||||
|
||||
Ce merveilleux site, fait avec ❤ par [Corentin Thomasset](https://github.com/CorentinTh), regroupe des outils utiles pour les développeurs et les personnes travaillant dans l'informatique. Si vous le trouvez utile, n'hésitez pas à le partager et n'oubliez pas de le mettre dans vos favoris !
|
||||
Ce merveilleux site, fait avec ❤ par [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about), regroupe des outils utiles pour les développeurs et les personnes travaillant dans l'informatique. Si vous le trouvez utile, n'hésitez pas à le partager et n'oubliez pas de le mettre dans vos favoris !
|
||||
|
||||
IT Tools est open-source (sous licence MIT) et gratuit, et le restera toujours, mais cela me coûte de l'argent pour l'héberger et renouveler le nom de domaine. Si vous voulez soutenir mon travail, et m'encourager à ajouter plus d'outils, n'hésitez pas à me [soutenir](https://www.buymeacoffee.com/cthmsst).
|
||||
IT Tools est open-source (sous licence GPL-3.0) et gratuit, et le restera toujours, mais cela me coûte de l'argent pour l'héberger et renouveler le nom de domaine. Si vous voulez soutenir mon travail, et m'encourager à ajouter plus d'outils, n'hésitez pas à me [soutenir](https://www.buymeacoffee.com/cthmsst).
|
||||
|
||||
## Technologies
|
||||
|
||||
|
|
394
locales/no.yml
Normal file
394
locales/no.yml
Normal file
|
@ -0,0 +1,394 @@
|
|||
home:
|
||||
categories:
|
||||
newestTools: Nyeste verktøy
|
||||
favoriteTools: 'Dine favoritt verktøy'
|
||||
allTools: 'Alle verktøyene'
|
||||
favoritesDndToolTip: 'Dra og slipp for å omordne favoritter'
|
||||
subtitle: 'Nyttige verktøy for utviklere'
|
||||
toggleMenu: 'Vekslemenmy'
|
||||
home: Hjem
|
||||
uiLib: 'UI Bib'
|
||||
support: 'Støtt utviklingen av IT-Tools'
|
||||
buyMeACoffee: 'Kjøp en kaffe til meg'
|
||||
follow:
|
||||
title: 'Liker du it-tools?'
|
||||
p1: 'Gi oss en stjerne på'
|
||||
githubRepository: 'IT-Tools GitHub-depotet'
|
||||
p2: 'eller følg oss på'
|
||||
twitterXAccount: 'IT-Tools sin X konto'
|
||||
thankYou: 'Tusen takk!'
|
||||
nav:
|
||||
github: 'GitHub-depot'
|
||||
githubRepository: 'IT-Tools GitHub-depot'
|
||||
twitterX: 'X konto'
|
||||
twitterXAccount: 'IT Tools X konto'
|
||||
about: 'Om IT-Tools'
|
||||
aboutLabel: 'Om'
|
||||
darkMode: 'Mørk modus'
|
||||
lightMode: 'Lys modus'
|
||||
mode: 'Veksle mørk/lys modus'
|
||||
about:
|
||||
content: >
|
||||
# Om IT-Tools
|
||||
|
||||
Denne vidunderlige nettsiden, laget med ❤ av [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about) , sammenstiller nyttige verktøy for utviklere og folk som jobber innen IT. Hvis du finner dette nyttig, Del det gjerne med andre som du tror kan få nytte av dette, og ikke glem å lage et bokmerke!
|
||||
|
||||
IT Tools er åpen kildekode (under GPL-3.0 lisensen) og gratis, og det vil det alltid være, men det koster å drifte og å fornye domenet. Hvis du ønsker å støtte arbeidet mitt, og motivere meg til å legge til flere verktøy, gjerne støtt meg ved å [sponse meg](https://www.buymeacoffee.com/cthmsst).
|
||||
|
||||
## Teknologier
|
||||
|
||||
IT Tools er laget i Vue.js (Vue 3) med Naive UI komponent bibliotektet og er hosted og kontinuerlig deployet av Vercel. Tredjeparts åpen-kildekode biblioteker er brukt i noen verktøy, du kan finne den komplette listen i [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json) filen i depoet.
|
||||
|
||||
## Funnet en feil? Et verktøy som mangler?
|
||||
|
||||
Hvis du trenger et verktøy som foreløpig ikke er tilgjengelig her, og du tenker det kan være nyttig for andre, så er du velkommen til å legge til en funksjonsforespørsel i [problem seksjonen](https://github.com/CorentinTh/it-tools/issues/new/choose) i github-depotet.
|
||||
|
||||
Og hvis du har funnet en feil, eller noe ikke oppfører seg som forventet, vennligst send inn en feilrapport i [problem seksjonen](https://github.com/CorentinTh/it-tools/issues/new/choose) i github-depotet.
|
||||
|
||||
404:
|
||||
notFound: '404 ikke funnet'
|
||||
sorry: 'Beklager, denne siden ser ikke ut til å eksistere'
|
||||
maybe: 'Kanskje informasjonskapslene oppfører seg rart, prøvd en tvungen oppfriskning?'
|
||||
backHome: 'Tilbake til start'
|
||||
favoriteButton:
|
||||
remove: 'Fjern fra favoritter'
|
||||
add: 'Legg til favoritter'
|
||||
toolCard:
|
||||
new: Ny
|
||||
search:
|
||||
label: Søk
|
||||
tools:
|
||||
categories:
|
||||
favorite-tools: 'Dine favoritt verktøy'
|
||||
crypto: Krypto
|
||||
converter: Konvertering
|
||||
web: Web
|
||||
images and videos: 'Bilder & Videoer'
|
||||
development: Utvikling
|
||||
network: Nettverk
|
||||
math: Matte
|
||||
measurement: Måling
|
||||
text: Tekst
|
||||
data: Data
|
||||
|
||||
password-strength-analyser:
|
||||
title: Analyseverktøy for passordstyrke
|
||||
description: Oppdag styrken av passordet ditt med dette kun-klient-maskin passordstyrke analyse verktøyet og se den estimerte knekketiden.
|
||||
|
||||
chronometer:
|
||||
title: Kronometer
|
||||
description: Overvåk varigheten av noe. I bunn og grunn et kronometer med enkle funksjoner.
|
||||
|
||||
token-generator:
|
||||
title: Token generator
|
||||
description: Generer en tilfeldig streng med store og/eller små bokstaver, siffer og/eller symboler.
|
||||
|
||||
uppercase: Store bokstaver (ABC...)
|
||||
lowercase: Små bokstaver (abc...)
|
||||
numbers: Siffer (123...)
|
||||
symbols: Symboler (!-;...)
|
||||
length: Lengde
|
||||
tokenPlaceholder: 'Tokenet...'
|
||||
copied: Tokenet er kopiert til utklippstavlen.
|
||||
button:
|
||||
copy: Kopier
|
||||
refresh: Oppfrisk
|
||||
percentage-calculator:
|
||||
title: Prosent kalkulator
|
||||
description: Beregn enkelt prosenter fra en verdi til en annen, eller fra en prosent til en verdi.
|
||||
|
||||
svg-placeholder-generator:
|
||||
title: SVG plassholder generator
|
||||
description: Generer svg bilder til å bruke som plassholder i applikasjonen din.
|
||||
|
||||
json-to-csv:
|
||||
title: JSON til CSV
|
||||
description: Konverter JSON til CSV med automatisk oppdagelse av headeren.
|
||||
|
||||
camera-recorder:
|
||||
title: Kameraopptak
|
||||
description: Ta et bilde eller spill inn en video med webkamera eller kameraet ditt.
|
||||
|
||||
keycode-info:
|
||||
title: Tastekode info
|
||||
description: Finn javascript tastekode, kode, plassering og modifikatorer av hvilken som helst tast.
|
||||
|
||||
emoji-picker:
|
||||
title: Emoji velger
|
||||
description: Klipp og lim emojis og få unicode og kode verdien av hver emoji.
|
||||
|
||||
color-converter:
|
||||
title: Farge konverter
|
||||
description: Konverter farger mellom de forskjellige formatene (hex, rgb, hsl og css navn).
|
||||
|
||||
bcrypt:
|
||||
title: Bcrypt
|
||||
description: Hash og sammenlign tekst ved hjelp av bcrypt. Bcrypt er en passord-hashings funksjon basert på Blowfish cipher.
|
||||
|
||||
crontab-generator:
|
||||
title: Crontab generator
|
||||
description: Verifiser og generer crontab og få den mennesklig leselige beskrivelsen av cron timeplanen.
|
||||
|
||||
http-status-codes:
|
||||
title: HTTP status koder
|
||||
description: Liste over alle HTTP status koder, navnet dems, og betydningen.
|
||||
|
||||
sql-prettify:
|
||||
title: SQL forskjønning and format
|
||||
description: Formater og forskjønn SQL spørringene dine (den støtter forskjellige SQL dialekter).
|
||||
|
||||
benchmark-builder:
|
||||
title: Bygg en referansemåler
|
||||
description: Sammenlign enkelt kjøretiden av oppgaver med denne enkle referansemåls byggeren.
|
||||
|
||||
git-memo:
|
||||
title: Git jukselapp
|
||||
description: Git er en desentralisert versjons håndterings programvare. Med denne jukselappen vil du få kjapp tilgang til de vanligste kommandoene.
|
||||
|
||||
slugify-string:
|
||||
title: Slugify streng
|
||||
description: Lag en trygg url, filbane eller id.
|
||||
|
||||
encryption:
|
||||
title: Krypter / decrypter tekst
|
||||
description: Krypter klartekst og dekrypter ciphertekst ved bruk av krypteringsalgoritmer som AES, TripleDES, Rabbit eller RC4.
|
||||
|
||||
random-port-generator:
|
||||
title: Tilfeldig port generator
|
||||
description: Generer tilfeldige portnumre utenfor scopet av "kjente" porter (0-1023).
|
||||
|
||||
yaml-prettify:
|
||||
title: YAML forskjønning og formatering
|
||||
description: Forskjønn YAML strengene dine til et lettlest format.
|
||||
|
||||
eta-calculator:
|
||||
title: ETA kalkulator
|
||||
description: En ETA (Estimert Tid for Ankomst) kalkulator for å anslå den sannsynelige slutt tiden for en oppgave, for eksempel, slutttiden og varigheten av en filnedlastning.
|
||||
|
||||
roman-numeral-converter:
|
||||
title: Romertall konverter
|
||||
description: Konverter romertall til tall eller konverter tall til romertall.
|
||||
|
||||
hmac-generator:
|
||||
title: Hmac generator
|
||||
description: Beregn en hash-basert meldings authentiserings kode (HMAC) ved bruk av en hemmelig nøkkel og din foretrukne hashings funksjon.
|
||||
|
||||
bip39-generator:
|
||||
title: BIP39 nøkkelords generator
|
||||
description: Generer et BIP39 nøkkelord fra en eksisterende eller tilfeldig huskesetning, eller få ut en huskesetning fra nøkkelordet.
|
||||
|
||||
base64-file-converter:
|
||||
title: Base64 fil konverter
|
||||
description: Konverter en base64 streng til fil eller en fil, bilde til en base64 representasjon.
|
||||
|
||||
list-converter:
|
||||
title: Liste konverterer
|
||||
description: Dette verktøyet kan prosessere kolonnebasert data og foreta forskjellige endringer (transposering, legge til prefix og suffix, reversere lister, sortere lister, gjøre om til små bokstaver, trunkere verdier) på hver rad.
|
||||
|
||||
base64-string-converter:
|
||||
title: Base64 string kode/dekoder
|
||||
description: Enkelt kode eller dekode en tekststreng til base64 representasjonen av strengen.
|
||||
|
||||
toml-to-yaml:
|
||||
title: TOML til YAML
|
||||
description: Parser og konverter TOML til YAML.
|
||||
|
||||
math-evaluator:
|
||||
title: Matematikkevaluator
|
||||
description: En Kalkulator for å evaluere matematiske uttrykk. Du kan bruke funksjoner som sqrt, cos, sin, abs, etc.
|
||||
|
||||
json-to-yaml-converter:
|
||||
title: JSON til YAML konverterer
|
||||
description: Enkelt konverter JSON til YAML med dette verktøyet.
|
||||
|
||||
url-parser:
|
||||
title: URL analyse
|
||||
description: Parsere en URL ned til bestanddelene (protokoll, opprinnelse, parametre, port, brukernavn-passord, ...).
|
||||
|
||||
iban-validator-and-parser:
|
||||
title: IBAN validering og analysering
|
||||
description: Valider og parser IBAN numre. Sjekk om et IBAN er gyldig og få landet, BBAN, om det er en QR-IBAN og IBAN i et vennlig format.
|
||||
|
||||
user-agent-parser:
|
||||
title: User-agent analysering
|
||||
description: Detekter og parser nettleser, motor, OS, CPU, og enhet type/modell fra en user-agent tekst streng.
|
||||
|
||||
numeronym-generator:
|
||||
title: Numeronym generator
|
||||
description: Et numeronym er et ord hvor et nummer er brukt til å lage en forkortelse. For eksempel, "i18n" er et numeronym for "internasjonalisering" hvor 18 står for antall bokstaver mellom første bokstaven i og den siste bokstaven n i ordet.
|
||||
|
||||
case-converter:
|
||||
title: Bokstavkonvertering
|
||||
description: Formater bokstavene med store eller små bokstaver, samt andre format.
|
||||
|
||||
html-entities:
|
||||
title: HTML streng rensing
|
||||
description: Rens bort eller omsvøp HTML entiteter (erstatt tegn som <,>, &, " and \' med deres HTML versjon).
|
||||
|
||||
json-prettify:
|
||||
title: JSON forskjønning og formatering
|
||||
description: Forskjønn JSON strenger til et lettlest format.
|
||||
|
||||
docker-run-to-docker-compose-converter:
|
||||
title: Docker run til Docker compose konverter
|
||||
description: Konverter "docker run" kommandoer til docker-compose filer!
|
||||
|
||||
mac-address-lookup:
|
||||
title: MAC address oppslagsverk
|
||||
description: Finn forhandler og produsent basert på MAC adressen.
|
||||
|
||||
mime-types:
|
||||
title: MIME typer
|
||||
description: Konverter MIME typer til fil utvidelser og visa-versa.
|
||||
|
||||
toml-to-json:
|
||||
title: TOML til JSON
|
||||
description: Parser og konverter TOML til JSON.
|
||||
|
||||
lorem-ipsum-generator:
|
||||
title: Lorem ipsum generator
|
||||
description: Lorem ipsum er brukt som plassholder tekst, vanligvis brukt til å demonstrere den visuelle formen av et dokument eller font-type uten å måtte ha meningsfult innhold.
|
||||
|
||||
qrcode-generator:
|
||||
title: QR Kode generator
|
||||
description: Generer og last ned en QR kode til en URL (eller ren tekst), og tilpass bakgrunns og forgrunns farger.
|
||||
|
||||
wifi-qrcode-generator:
|
||||
title: WiFi QR Kode generator
|
||||
description: Generer og last ned QR koder for rask tilkobling til wifi nettverket.
|
||||
|
||||
xml-formatter:
|
||||
title: XML formaterer
|
||||
description: Forskjønn en XML streng til et lettlest format.
|
||||
|
||||
temperature-converter:
|
||||
title: Temperatur konverter
|
||||
description: Temperatur konversjoner mellom Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur, og Rømer.
|
||||
|
||||
chmod-calculator:
|
||||
title: Chmod kalkulator
|
||||
description: Beregn chmod tillatelser og kommandoer med denne chmod kalkulatoren.
|
||||
|
||||
rsa-key-pair-generator:
|
||||
title: RSA nøkkelpar generator
|
||||
description: Generer et nytt tilfeldig RSA privat og offentlig pem sertifikat nøkkel par.
|
||||
|
||||
html-wysiwyg-editor:
|
||||
title: HTML WYSIWYG editor
|
||||
description: Online, funksjonsrik WYSIWYG HTML editor som genererer kildekoden for innholdet øyeblikkelig.
|
||||
|
||||
yaml-to-toml:
|
||||
title: YAML til TOML
|
||||
description: Parser og konverter YAML til TOML.
|
||||
|
||||
mac-address-generator:
|
||||
title: MAC adresse generator
|
||||
description: Sett inn antall og prefix. MAC addressene blir generert i ønsket format
|
||||
|
||||
json-diff:
|
||||
title: JSON diff
|
||||
description: Sammenlign to JSON objekter og finn forskjellene mellom dem.
|
||||
|
||||
jwt-parser:
|
||||
title: JWT parser
|
||||
description: Parse og dekode et JSON Web Token (jwt) og vis innholdet.
|
||||
|
||||
date-converter:
|
||||
title: Dato-tid konverter
|
||||
description: Konverter dato og tid til forskjellige formater.
|
||||
|
||||
phone-parser-and-formatter:
|
||||
title: Telefon format og parserer
|
||||
description: Parser, valider og formater telefon numre. få innformasjonen om telefon nummeret, slik som landskoden, type etc.
|
||||
|
||||
ipv4-subnet-calculator:
|
||||
title: IPv4 subnet kalkulator
|
||||
description: Parser IPv4 CIDR blokker of åf all info du trenger om subnettet.
|
||||
|
||||
og-meta-generator:
|
||||
title: Open graph meta generator
|
||||
description: Generer open-graph og SoMe HTML meta tagger til nettsiden din.
|
||||
|
||||
ipv6-ula-generator:
|
||||
title: IPv6 ULA generator
|
||||
description: Generer din egen lokale, ikke-rutbare IP adresse til nettverket ditt i henhold til RFC4193.
|
||||
|
||||
hash-text:
|
||||
title: Hash tekst
|
||||
description: 'Hash en tekst streng med en av algoritmene : MD5, SHA1, SHA256, SHA224, SHA512, SHA384, SHA3 eller RIPEMD160'
|
||||
|
||||
json-to-toml:
|
||||
title: JSON til TOML
|
||||
description: Parser og konverter JSON til TOML.
|
||||
|
||||
device-information:
|
||||
title: Enhets informasjon
|
||||
description: Få informasjon om din nåværende enhet (skjermstørrelse, piksel-forhold, user agent, etc.)
|
||||
|
||||
pdf-signature-checker:
|
||||
title: PDF signatur sjekker
|
||||
description: Bekreft signaturen til en PDF fil. En signert PDF fil inneholder en eller flere signaturer som kan bli brukt til å bestemme om en fil har blitt endret etter at den var signert.
|
||||
|
||||
json-minify:
|
||||
title: JSON minifiser
|
||||
description: Minifiser og komprimer JSON ved å fjerne unødvendige mellomrom.
|
||||
|
||||
ulid-generator:
|
||||
title: ULID generator
|
||||
description: Generer tilfeldig Universell Unik Leksikografisk Sorterbar Identifikator (ULID).
|
||||
|
||||
string-obfuscator:
|
||||
title: Streng obfuskator
|
||||
description: Obfusker en streng (som en hemmelighet, en IBAN, eller et token) og gjør den delbar og identifiserbar uten å vise innholdet.
|
||||
|
||||
base-converter:
|
||||
title: Heltalls konverter
|
||||
description: Konverter et heltall mellom forskjellige baser (desimal, hexadesimal, binær, oktal, base64, etc.)
|
||||
|
||||
yaml-to-json-converter:
|
||||
title: YAML til JSON konverter
|
||||
description: Konverterl YAML til JSON.
|
||||
|
||||
uuid-generator:
|
||||
title: UUIDs generator
|
||||
description: En universell Unik Identifikator (UUID) er et 128-bit nummer, brukt til å identifisere informasjon i datasystemer.
|
||||
|
||||
ipv4-address-converter:
|
||||
title: IPv4 adresse konverter
|
||||
description: Konverter en IPv4 adresse til desimal, binær, hexadesimal, eller en IPv6 representasjon.
|
||||
|
||||
text-statistics:
|
||||
title: Tekst statistikk
|
||||
description: Få informasjonen om en tekst, antall karakterer, antall ord, størrelsen i bytes, etc.
|
||||
|
||||
text-to-nato-alphabet:
|
||||
title: Tekst til NATO alfabetet
|
||||
description: Transformer teksten til det NATO fonetiske alfabetet for muntlig gjengivelse.
|
||||
|
||||
basic-auth-generator:
|
||||
title: Basic auth generator
|
||||
description: Generer en base64 basic auth header fra et brukernavn og passord.
|
||||
|
||||
text-to-unicode:
|
||||
title: Tekst til Unicode
|
||||
description: Parser og konverter tekst til unicode og visa-versa
|
||||
|
||||
ipv4-range-expander:
|
||||
title: IPv4 range utvider
|
||||
description: Gitt en start og en slutt IPv4 adresse, kalkulerer dette verktøyet et gyldig IPv4 subnet sammen med sin CIDR notasjon.
|
||||
|
||||
text-diff:
|
||||
title: Tekst diff
|
||||
description: Sammenlign to tekster og vis forskjellen mellom dem.
|
||||
|
||||
otp-generator:
|
||||
title: OTP kode generator
|
||||
description: Generer og valider tidsbasert OTP (one time password) for multi-faktor autentisering.
|
||||
|
||||
url-encoder:
|
||||
title: Kode/dekode URL-formaterte strenger
|
||||
description: Kode tekst til URL-kodet format (også kjent som "prosent-kodet"), eller dekode fra det.
|
||||
|
||||
text-to-binary:
|
||||
title: Tekst til ASCII binært
|
||||
description: Konverter tekst til sin ASCII binære representasjon og visa-versa.
|
|
@ -3,6 +3,7 @@ home:
|
|||
newestTools: 'Novas ferramentas'
|
||||
favoriteTools: 'Suas ferramentas favoritas'
|
||||
allTools: 'Todas as ferramentas'
|
||||
favoritesDndToolTip: 'Arraste e solte para reordenar favoritos'
|
||||
subtitle: 'Ferraentas úteis para desenvolvedores'
|
||||
toggleMenu: 'Menu'
|
||||
home: 'Início'
|
||||
|
@ -14,13 +15,13 @@ home:
|
|||
p1: 'Dê uma estrela no'
|
||||
githubRepository: 'repositório do IT-Tools no GitHub'
|
||||
p2: 'ou siga nossa'
|
||||
twitterAccount: 'conta IT-Tools no Twitter'
|
||||
twitterXAccount: 'conta IT-Tools no X'
|
||||
thankYou: 'Obrigado !'
|
||||
nav:
|
||||
github: 'Repositório no GitHub'
|
||||
githubRepository: 'repositório do IT-Tools no GitHub'
|
||||
twitter: 'Conta no Twitter'
|
||||
twitterAccount: 'conta do IT Tools no Twitter'
|
||||
twitterX: 'Conta no X'
|
||||
twitterXAccount: 'conta do IT Tools no X'
|
||||
about: 'Sobre o IT-Tools'
|
||||
aboutLabel: 'Sobre'
|
||||
darkMode: 'Modo Escuro'
|
||||
|
@ -30,9 +31,9 @@ about:
|
|||
content: >
|
||||
# Sobre o IT-Tools
|
||||
|
||||
Este site maravilhoso, feito com ❤ por [Corentin Thomasset](https://github.com/CorentinTh), junta ferramentas úteis para desenvolvedores e outras pessoas que trabalham com TI. Se você achar o site útil, fique à vontade para compartilhar com quem também possa gostar e não esqueça de salvar o bookmark na sua barra de atalhos!
|
||||
Este site maravilhoso, feito com ❤ por [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about), junta ferramentas úteis para desenvolvedores e outras pessoas que trabalham com TI. Se você achar o site útil, fique à vontade para compartilhar com quem também possa gostar e não esqueça de salvar o bookmark na sua barra de atalhos!
|
||||
|
||||
O IT Tools é código aberto (sob a licença MIT), é gratuito, e sempre será, mas custa dinheiro para hospedar e renovar o domínio. Se quiser apoiar meu trabalho e me encorajar a adicionar mais ferramentas, por favor considere [ser patrocinador](https://www.buymeacoffee.com/cthmsst).
|
||||
O IT Tools é código aberto (sob a licença GPL-3.0), é gratuito, e sempre será, mas custa dinheiro para hospedar e renovar o domínio. Se quiser apoiar meu trabalho e me encorajar a adicionar mais ferramentas, por favor considere [ser patrocinador](https://www.buymeacoffee.com/cthmsst).
|
||||
|
||||
## Tecnologias
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ home:
|
|||
newestTools: Найновіші інструменти
|
||||
favoriteTools: 'Ваші улюблені інструменти'
|
||||
allTools: 'Усі інструменти'
|
||||
favoritesDndToolTip: 'Перетягніть і відпустіть, щоб змінити порядок улюблених'
|
||||
subtitle: 'Зручні інструменти для розробників'
|
||||
toggleMenu: 'Перемикання меню'
|
||||
home: Головна
|
||||
|
@ -14,13 +15,13 @@ home:
|
|||
p1: 'Додайте нам зірку на'
|
||||
githubRepository: 'GitHub-репозиторій IT-Tools'
|
||||
p2: 'або слідкуйте за нами на'
|
||||
twitterAccount: 'Твіттер-акаунт IT-Tools'
|
||||
twitterXAccount: 'X-акаунт IT-Tools'
|
||||
thankYou: 'Дякуємо!'
|
||||
nav:
|
||||
github: 'GitHub-репозиторій'
|
||||
githubRepository: 'GitHub-репозиторій IT-Tools'
|
||||
twitter: 'Твіттер'
|
||||
twitterAccount: 'Твіттер-акаунт IT-Tools'
|
||||
twitterX: 'X'
|
||||
twitterXAccount: 'X-акаунт IT-Tools'
|
||||
about: 'Про IT-Tools'
|
||||
aboutLabel: 'Про нас'
|
||||
darkMode: 'Темний режим'
|
||||
|
@ -30,9 +31,9 @@ about:
|
|||
content: >
|
||||
# Про IT-Tools
|
||||
|
||||
Цей чудовий вебсайт, створений з ❤ [Corentin Thomasset](https://github.com/CorentinTh), агрегує корисні інструменти для розробників і людей, які працюють в сфері IT. Якщо вам це корисно, будь ласка, поділіться цим з людьми, які, на вашу думку, також можуть знайти його корисним, і не забудьте додати його до закладок у вашій панелі швидкого доступу!
|
||||
Цей чудовий вебсайт, створений з ❤ [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about), агрегує корисні інструменти для розробників і людей, які працюють в сфері IT. Якщо вам це корисно, будь ласка, поділіться цим з людьми, які, на вашу думку, також можуть знайти його корисним, і не забудьте додати його до закладок у вашій панелі швидкого доступу!
|
||||
|
||||
IT Tools є відкритим програмним забезпеченням (під ліцензією MIT) і безкоштовним, і завжди буде таким, але мені коштує гроші для хостингу і продовження доменного імені. Якщо ви хочете підтримати мою роботу і підтримати мене у додаванні нових інструментів, розгляньте можливість підтримки, [спонсоруючи мене](https://www.buymeacoffee.com/cthmsst).
|
||||
IT Tools є відкритим програмним забезпеченням (під ліцензією GPL-3.0) і безкоштовним, і завжди буде таким, але мені коштує гроші для хостингу і продовження доменного імені. Якщо ви хочете підтримати мою роботу і підтримати мене у додаванні нових інструментів, розгляньте можливість підтримки, [спонсоруючи мене](https://www.buymeacoffee.com/cthmsst).
|
||||
|
||||
## Технології
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ home:
|
|||
newestTools: Công cụ mới nhất
|
||||
favoriteTools: 'Công cụ yêu thích của bạn'
|
||||
allTools: 'Tất cả công cụ'
|
||||
favoritesDndToolTip: 'Kéo thả để sắp xếp lại yêu thích'
|
||||
subtitle: 'Công cụ cho nhà phát triển.'
|
||||
toggleMenu: 'Chuyển đổi menu'
|
||||
home: Trang chủ
|
||||
|
@ -14,13 +15,13 @@ home:
|
|||
p1: 'Hãy cho chúng tôi một ngôi sao trên'
|
||||
githubRepository: 'Kho GitHub IT-Tools'
|
||||
p2: 'hoặc theo dõi chúng tôi trên'
|
||||
twitterAccount: 'Tài khoản Twitter IT-Tools'
|
||||
twitterXAccount: 'Tài khoản X IT-Tools'
|
||||
thankYou: 'Cảm ơn bạn!'
|
||||
nav:
|
||||
github: 'Kho GitHub'
|
||||
githubRepository: 'Kho GitHub IT-Tools'
|
||||
twitter: 'Tài khoản Twitter'
|
||||
twitterAccount: 'Tài khoản Twitter IT Tools'
|
||||
twitterX: 'Tài khoản X'
|
||||
twitterXAccount: 'Tài khoản X IT Tools'
|
||||
about: 'Về IT-Tools'
|
||||
aboutLabel: 'Giới thiệu'
|
||||
darkMode: 'Chế độ tối'
|
||||
|
@ -30,9 +31,9 @@ about:
|
|||
content: >
|
||||
# Về IT-Tools
|
||||
|
||||
Website tuyệt vời này, được tạo ra bằng ❤ bởi [Corentin Thomasset](https://github.com/CorentinTh), tổng hợp các công cụ hữu ích cho nhà phát triển và những người làm việc trong lĩnh vực IT. Nếu bạn thấy nó hữu ích, xin đừng ngần ngại chia sẻ cho những người mà bạn nghĩ sẽ thấy nó hữu ích và đừng quên đánh dấu nó trong thanh lối tắt của bạn!
|
||||
Website tuyệt vời này, được tạo ra bằng ❤ bởi [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about), tổng hợp các công cụ hữu ích cho nhà phát triển và những người làm việc trong lĩnh vực IT. Nếu bạn thấy nó hữu ích, xin đừng ngần ngại chia sẻ cho những người mà bạn nghĩ sẽ thấy nó hữu ích và đừng quên đánh dấu nó trong thanh lối tắt của bạn!
|
||||
|
||||
IT Tools là mã nguồn mở (dưới giấy phép MIT) và miễn phí, và sẽ luôn như vậy, nhưng tôi phải trả tiền để lưu trữ và gia hạn tên miền. Nếu bạn muốn hỗ trợ công việc của tôi, và khích lệ tôi thêm nhiều công cụ hơn, hãy xem xét hỗ trợ bằng cách [tài trợ cho tôi](https://www.buymeacoffee.com/cthmsst).
|
||||
IT Tools là mã nguồn mở (dưới giấy phép GPL-3.0) và miễn phí, và sẽ luôn như vậy, nhưng tôi phải trả tiền để lưu trữ và gia hạn tên miền. Nếu bạn muốn hỗ trợ công việc của tôi, và khích lệ tôi thêm nhiều công cụ hơn, hãy xem xét hỗ trợ bằng cách [tài trợ cho tôi](https://www.buymeacoffee.com/cthmsst).
|
||||
|
||||
## Công nghệ
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ home:
|
|||
newestTools: '最新工具'
|
||||
favoriteTools: '我的收藏'
|
||||
allTools: '全部工具'
|
||||
favoritesDndToolTip: '拖放重新排列收藏夹'
|
||||
subtitle: '助力开发人员和 IT 工作者'
|
||||
toggleMenu: '切换菜单'
|
||||
home: '主页'
|
||||
|
@ -14,13 +15,13 @@ home:
|
|||
p1: '给我们 Star'
|
||||
githubRepository: 'GitHub 仓库'
|
||||
p2: '关注我们的'
|
||||
twitterAccount: 'Twitter'
|
||||
twitterXAccount: 'IT-Tools X 账号'
|
||||
thankYou: '感谢您的支持!'
|
||||
nav:
|
||||
github: 'GitHub 仓库'
|
||||
githubRepository: 'GitHub 仓库'
|
||||
twitter: 'Twitter 账号'
|
||||
twitterAccount: 'Twitter 账号'
|
||||
twitterX: 'Twitter 账号'
|
||||
twitterXAccount: 'IT-Tools X 账号'
|
||||
about: '关于 IT-Tools'
|
||||
aboutLabel: '关于'
|
||||
darkMode: '深色模式'
|
||||
|
@ -30,9 +31,9 @@ about:
|
|||
content: >
|
||||
# 关于 IT-Tools
|
||||
|
||||
IT-Tools 由 [Corentin Thomasset](https://github.com/CorentinTh) 用 ❤ 开发,汇集了对开发人员和 IT 从业者有用的工具。如果对您有帮助,请将其分享给您的朋友,并且添加到收藏夹中!
|
||||
IT-Tools 由 [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about) 用 ❤ 开发,汇集了对开发人员和 IT 从业者有用的工具。如果对您有帮助,请将其分享给您的朋友,并且添加到收藏夹中!
|
||||
|
||||
IT-Tools 永久免费且开源(MIT 许可证),但需要资金用于托管和续订域名。如果您想支持我的工作,并鼓励我添加更多工具,请考虑通过 [赞助我](https://www.buymeacoffee.com/cthmsst) 进行支持。
|
||||
IT-Tools 永久免费且开源(GPL-3.0 许可证),但需要资金用于托管和续订域名。如果您想支持我的工作,并鼓励我添加更多工具,请考虑通过 [赞助我](https://www.buymeacoffee.com/cthmsst) 进行支持。
|
||||
|
||||
## 技术
|
||||
|
||||
|
|
28
package.json
28
package.json
|
@ -1,7 +1,15 @@
|
|||
{
|
||||
"name": "it-tools",
|
||||
"version": "2023.12.21-5ed3693",
|
||||
"type": "module",
|
||||
"version": "2024.10.22-7ca5933",
|
||||
"packageManager": "pnpm@9.11.0",
|
||||
"description": "Collection of handy online tools for developers, with great UX. ",
|
||||
"author": "Corentin Th <corentin.thomasset74+it-tools@gmail.com> (https://corentin.tech)",
|
||||
"license": "GNU GPLv3",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/CorentinTh/it-tools"
|
||||
},
|
||||
"keywords": [
|
||||
"productivity",
|
||||
"converter",
|
||||
|
@ -13,12 +21,6 @@
|
|||
"developer-tools",
|
||||
"developer-productivity"
|
||||
],
|
||||
"author": "Corentin Th <corentin.thomasset74+it-tools@gmail.com> (https://github.com/CorentinTh)",
|
||||
"license": "GNU GPLv3",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/CorentinTh/it-tools"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && NODE_OPTIONS=--max_old_space_size=4096 vite build",
|
||||
|
@ -37,12 +39,15 @@
|
|||
"dependencies": {
|
||||
"@it-tools/bip39": "^0.0.4",
|
||||
"@it-tools/oggen": "^1.3.0",
|
||||
"@regexper/render": "^1.0.0",
|
||||
"@sindresorhus/slugify": "^2.2.1",
|
||||
"@tabler/icons-vue": "^3.20.0",
|
||||
"@tiptap/pm": "2.1.6",
|
||||
"@tiptap/starter-kit": "2.1.6",
|
||||
"@tiptap/vue-3": "2.0.3",
|
||||
"@types/figlet": "^1.5.8",
|
||||
"@types/js-beautify": "^1.14.3",
|
||||
"@types/markdown-it": "^13.0.7",
|
||||
"@vicons/material": "^0.12.0",
|
||||
"@vicons/tabler": "^0.12.0",
|
||||
"@vueuse/core": "^10.3.0",
|
||||
|
@ -58,6 +63,7 @@
|
|||
"crypto-js": "^4.1.1",
|
||||
"date-fns": "^2.29.3",
|
||||
"dompurify": "^3.0.6",
|
||||
"email-normalizer": "^1.0.0",
|
||||
"emojilib": "^3.0.10",
|
||||
"figlet": "^1.7.0",
|
||||
"figue": "^1.2.0",
|
||||
|
@ -66,10 +72,12 @@
|
|||
"iarna-toml-esm": "^3.0.5",
|
||||
"ibantools": "^4.3.3",
|
||||
"js-beautify": "^1.15.1",
|
||||
"js-base64": "^3.7.6",
|
||||
"json5": "^2.2.3",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"libphonenumber-js": "^1.10.28",
|
||||
"lodash": "^4.17.21",
|
||||
"markdown-it": "^14.0.0",
|
||||
"marked": "^10.0.0",
|
||||
"mathjs": "^11.9.1",
|
||||
"mime-types": "^2.1.35",
|
||||
|
@ -82,6 +90,7 @@
|
|||
"pinia": "^2.0.34",
|
||||
"plausible-tracker": "^0.3.8",
|
||||
"qrcode": "^1.5.1",
|
||||
"randexp": "^0.5.3",
|
||||
"sql-formatter": "^13.0.0",
|
||||
"ua-parser-js": "^1.0.35",
|
||||
"ulid": "^2.3.0",
|
||||
|
@ -91,8 +100,11 @@
|
|||
"vue": "^3.3.4",
|
||||
"vue-i18n": "^9.9.1",
|
||||
"vue-router": "^4.1.6",
|
||||
"vue-shadow-dom": "^4.2.0",
|
||||
"vue-tsc": "^1.8.1",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"xml-formatter": "^3.3.2",
|
||||
"xml-js": "^1.6.11",
|
||||
"yaml": "^2.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -128,7 +140,7 @@
|
|||
"less": "^4.1.3",
|
||||
"prettier": "^3.0.0",
|
||||
"typescript": "~5.2.0",
|
||||
"unocss": "^0.57.0",
|
||||
"unocss": "^0.65.1",
|
||||
"unocss-preset-scrollbar": "^0.2.1",
|
||||
"unplugin-icons": "^0.17.0",
|
||||
"unplugin-vue-components": "^0.25.0",
|
||||
|
|
1190
pnpm-lock.yaml
1190
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -48,7 +48,7 @@ const output = computed(() => transformer.value(input.value));
|
|||
monospace
|
||||
/>
|
||||
|
||||
<div>
|
||||
<div overflow-auto>
|
||||
<div mb-5px>
|
||||
{{ outputLabel }}
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { BrandGithub, BrandTwitter, InfoCircle, Moon, Sun } from '@vicons/tabler';
|
||||
import { IconBrandGithub, IconBrandX, IconInfoCircle, IconMoon, IconSun } from '@tabler/icons-vue';
|
||||
import { useStyleStore } from '@/stores/style.store';
|
||||
|
||||
const styleStore = useStyleStore();
|
||||
|
@ -16,32 +16,32 @@ const { isDarkTheme } = toRefs(styleStore);
|
|||
rel="noopener noreferrer"
|
||||
:aria-label="$t('home.nav.githubRepository')"
|
||||
>
|
||||
<n-icon size="25" :component="BrandGithub" />
|
||||
<n-icon size="25" :component="IconBrandGithub" />
|
||||
</c-button>
|
||||
</c-tooltip>
|
||||
|
||||
<c-tooltip :tooltip="$t('home.nav.twitter')" position="bottom">
|
||||
<c-tooltip :tooltip="$t('home.nav.twitterX')" position="bottom">
|
||||
<c-button
|
||||
circle
|
||||
variant="text"
|
||||
href="https://twitter.com/ittoolsdottech"
|
||||
href="https://x.com/ittoolsdottech"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
:aria-label="$t('home.nav.twitterAccount')"
|
||||
:aria-label="$t('home.nav.twitterXAccount')"
|
||||
>
|
||||
<n-icon size="25" :component="BrandTwitter" />
|
||||
<n-icon size="25" :component="IconBrandX" />
|
||||
</c-button>
|
||||
</c-tooltip>
|
||||
|
||||
<c-tooltip :tooltip="$t('home.nav.about')" position="bottom">
|
||||
<c-button circle variant="text" to="/about" :aria-label="$t('home.nav.aboutLabel')">
|
||||
<n-icon size="25" :component="InfoCircle" />
|
||||
<n-icon size="25" :component="IconInfoCircle" />
|
||||
</c-button>
|
||||
</c-tooltip>
|
||||
<c-tooltip :tooltip="isDarkTheme ? $t('home.nav.lightMode') : $t('home.nav.darkMode')" position="bottom">
|
||||
<c-button circle variant="text" :aria-label="$t('home.nav.mode')" @click="() => styleStore.toggleDark()">
|
||||
<n-icon v-if="isDarkTheme" size="25" :component="Sun" />
|
||||
<n-icon v-else size="25" :component="Moon" />
|
||||
<n-icon v-if="isDarkTheme" size="25" :component="IconSun" />
|
||||
<n-icon v-else size="25" :component="IconMoon" />
|
||||
</c-button>
|
||||
</c-tooltip>
|
||||
</template>
|
||||
|
|
|
@ -7,6 +7,7 @@ import sqlHljs from 'highlight.js/lib/languages/sql';
|
|||
import xmlHljs from 'highlight.js/lib/languages/xml';
|
||||
import yamlHljs from 'highlight.js/lib/languages/yaml';
|
||||
import iniHljs from 'highlight.js/lib/languages/ini';
|
||||
import markdownHljs from 'highlight.js/lib/languages/markdown';
|
||||
import { useCopy } from '@/composable/copy';
|
||||
|
||||
const props = withDefaults(
|
||||
|
@ -30,6 +31,7 @@ hljs.registerLanguage('html', xmlHljs);
|
|||
hljs.registerLanguage('xml', xmlHljs);
|
||||
hljs.registerLanguage('yaml', yamlHljs);
|
||||
hljs.registerLanguage('toml', iniHljs);
|
||||
hljs.registerLanguage('markdown', markdownHljs);
|
||||
|
||||
const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(props);
|
||||
const { height } = followHeightOf.value ? useElementSize(followHeightOf) : { height: ref(null) };
|
||||
|
|
21
src/composable/debouncedref.ts
Normal file
21
src/composable/debouncedref.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
function useDebouncedRef<T>(initialValue: T, delay: number, immediate: boolean = false) {
|
||||
const state = ref(initialValue);
|
||||
const debouncedRef = customRef((track, trigger) => ({
|
||||
get() {
|
||||
track();
|
||||
return state.value;
|
||||
},
|
||||
set: _.debounce(
|
||||
(value) => {
|
||||
state.value = value;
|
||||
trigger();
|
||||
},
|
||||
delay,
|
||||
{ leading: immediate },
|
||||
),
|
||||
}));
|
||||
return debouncedRef;
|
||||
}
|
||||
export default useDebouncedRef;
|
|
@ -1,8 +1,13 @@
|
|||
import { extension as getExtensionFromMime } from 'mime-types';
|
||||
import { extension as getExtensionFromMimeType, extension as getMimeTypeFromExtension } from 'mime-types';
|
||||
import type { Ref } from 'vue';
|
||||
import _ from 'lodash';
|
||||
|
||||
export { getMimeTypeFromBase64, useDownloadFileFromBase64 };
|
||||
export {
|
||||
getMimeTypeFromBase64,
|
||||
getMimeTypeFromExtension, getExtensionFromMimeType,
|
||||
useDownloadFileFromBase64, useDownloadFileFromBase64Refs,
|
||||
previewImageFromBase64,
|
||||
};
|
||||
|
||||
const commonMimeTypesSignatures = {
|
||||
'JVBERi0': 'application/pdf',
|
||||
|
@ -36,30 +41,78 @@ function getFileExtensionFromMimeType({
|
|||
defaultExtension?: string
|
||||
}) {
|
||||
if (mimeType) {
|
||||
return getExtensionFromMime(mimeType) ?? defaultExtension;
|
||||
return getExtensionFromMimeType(mimeType) ?? defaultExtension;
|
||||
}
|
||||
|
||||
return defaultExtension;
|
||||
}
|
||||
|
||||
function useDownloadFileFromBase64({ source, filename }: { source: Ref<string>; filename?: string }) {
|
||||
return {
|
||||
download() {
|
||||
if (source.value === '') {
|
||||
function downloadFromBase64({ sourceValue, filename, extension, fileMimeType }:
|
||||
{ sourceValue: string; filename?: string; extension?: string; fileMimeType?: string }) {
|
||||
if (sourceValue === '') {
|
||||
throw new Error('Base64 string is empty');
|
||||
}
|
||||
|
||||
const { mimeType } = getMimeTypeFromBase64({ base64String: source.value });
|
||||
const base64String = mimeType
|
||||
? source.value
|
||||
: `data:text/plain;base64,${source.value}`;
|
||||
const defaultExtension = extension ?? 'txt';
|
||||
const { mimeType } = getMimeTypeFromBase64({ base64String: sourceValue });
|
||||
let base64String = sourceValue;
|
||||
if (!mimeType) {
|
||||
const targetMimeType = fileMimeType ?? getMimeTypeFromExtension(defaultExtension);
|
||||
base64String = `data:${targetMimeType};base64,${sourceValue}`;
|
||||
}
|
||||
|
||||
const cleanFileName = filename ?? `file.${getFileExtensionFromMimeType({ mimeType })}`;
|
||||
const cleanExtension = extension ?? getFileExtensionFromMimeType(
|
||||
{ mimeType, defaultExtension });
|
||||
let cleanFileName = filename ?? `file.${cleanExtension}`;
|
||||
if (extension && !cleanFileName.endsWith(`.${extension}`)) {
|
||||
cleanFileName = `${cleanFileName}.${cleanExtension}`;
|
||||
}
|
||||
|
||||
const a = document.createElement('a');
|
||||
a.href = base64String;
|
||||
a.download = cleanFileName;
|
||||
a.click();
|
||||
}
|
||||
|
||||
function useDownloadFileFromBase64(
|
||||
{ source, filename, extension, fileMimeType }:
|
||||
{ source: Ref<string>; filename?: string; extension?: string; fileMimeType?: string }) {
|
||||
return {
|
||||
download() {
|
||||
downloadFromBase64({ sourceValue: source.value, filename, extension, fileMimeType });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function useDownloadFileFromBase64Refs(
|
||||
{ source, filename, extension }:
|
||||
{ source: Ref<string>; filename?: Ref<string>; extension?: Ref<string> }) {
|
||||
return {
|
||||
download() {
|
||||
downloadFromBase64({ sourceValue: source.value, filename: filename?.value, extension: extension?.value });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function previewImageFromBase64(base64String: string): HTMLImageElement {
|
||||
if (base64String === '') {
|
||||
throw new Error('Base64 string is empty');
|
||||
}
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.src = base64String;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.appendChild(img);
|
||||
|
||||
const previewContainer = document.getElementById('previewContainer');
|
||||
if (previewContainer) {
|
||||
previewContainer.innerHTML = '';
|
||||
previewContainer.appendChild(container);
|
||||
}
|
||||
else {
|
||||
throw new Error('Preview container element not found');
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { useRouteQuery } from '@vueuse/router';
|
||||
import { computed } from 'vue';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
|
||||
export { useQueryParam };
|
||||
export { useQueryParam, useQueryParamOrStorage };
|
||||
|
||||
const transformers = {
|
||||
number: {
|
||||
|
@ -16,6 +17,12 @@ const transformers = {
|
|||
fromQuery: (value: string) => value.toLowerCase() === 'true',
|
||||
toQuery: (value: boolean) => (value ? 'true' : 'false'),
|
||||
},
|
||||
object: {
|
||||
fromQuery: (value: string) => {
|
||||
return JSON.parse(value);
|
||||
},
|
||||
toQuery: (value: object) => JSON.stringify(value),
|
||||
},
|
||||
};
|
||||
|
||||
function useQueryParam<T>({ name, defaultValue }: { name: string; defaultValue: T }) {
|
||||
|
@ -33,3 +40,27 @@ function useQueryParam<T>({ name, defaultValue }: { name: string; defaultValue:
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
function useQueryParamOrStorage<T>({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue: T }) {
|
||||
const type = typeof defaultValue;
|
||||
const transformer = transformers[type as keyof typeof transformers] ?? transformers.string;
|
||||
|
||||
const storageRef = useStorage(storageName, defaultValue);
|
||||
const proxyDefaultValue = transformer.toQuery(defaultValue as never);
|
||||
const proxy = useRouteQuery(name, proxyDefaultValue);
|
||||
|
||||
const r = ref(defaultValue);
|
||||
|
||||
watch(r,
|
||||
(value) => {
|
||||
proxy.value = transformer.toQuery(value as never);
|
||||
storageRef.value = value as never;
|
||||
},
|
||||
{ deep: true });
|
||||
|
||||
r.value = (proxy.value && proxy.value !== proxyDefaultValue
|
||||
? transformer.fromQuery(proxy.value) as unknown as T
|
||||
: storageRef.value as T) as never;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -3,9 +3,11 @@ import _ from 'lodash';
|
|||
import { type Ref, reactive, watch } from 'vue';
|
||||
|
||||
type ValidatorReturnType = unknown;
|
||||
type GetErrorMessageReturnType = string;
|
||||
|
||||
export interface UseValidationRule<T> {
|
||||
validator: (value: T) => ValidatorReturnType
|
||||
getErrorMessage?: (value: T) => GetErrorMessageReturnType
|
||||
message: string
|
||||
}
|
||||
|
||||
|
@ -24,6 +26,15 @@ export function isFalsyOrHasThrown(cb: () => ValidatorReturnType): boolean {
|
|||
}
|
||||
}
|
||||
|
||||
export function getErrorMessageOrThrown(cb: () => GetErrorMessageReturnType): string {
|
||||
try {
|
||||
return cb() || '';
|
||||
}
|
||||
catch (e: any) {
|
||||
return e.toString();
|
||||
}
|
||||
}
|
||||
|
||||
export interface ValidationAttrs {
|
||||
feedback: string
|
||||
validationStatus: string | undefined
|
||||
|
@ -61,7 +72,13 @@ export function useValidation<T>({
|
|||
|
||||
for (const rule of get(rules)) {
|
||||
if (isFalsyOrHasThrown(() => rule.validator(source.value))) {
|
||||
if (rule.getErrorMessage) {
|
||||
const getErrorMessage = rule.getErrorMessage;
|
||||
state.message = rule.message.replace('{0}', getErrorMessageOrThrown(() => getErrorMessage(source.value)));
|
||||
}
|
||||
else {
|
||||
state.message = rule.message;
|
||||
}
|
||||
state.status = 'error';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,12 @@ export const config = figue({
|
|||
default: false,
|
||||
env: 'VITE_SHOW_BANNER',
|
||||
},
|
||||
showSponsorBanner: {
|
||||
doc: 'Show the sponsor banner',
|
||||
format: 'boolean',
|
||||
default: false,
|
||||
env: 'VITE_SHOW_SPONSOR_BANNER',
|
||||
},
|
||||
})
|
||||
.loadEnv({
|
||||
...import.meta.env,
|
||||
|
|
|
@ -81,7 +81,7 @@ const tools = computed<ToolCategory[]>(() => [
|
|||
</div>
|
||||
<div>
|
||||
© {{ new Date().getFullYear() }}
|
||||
<c-link target="_blank" rel="noopener" href="https://github.com/CorentinTh">
|
||||
<c-link target="_blank" rel="noopener" href="https://corentin.tech?utm_source=it-tools&utm_medium=footer">
|
||||
Corentin Thomasset
|
||||
</c-link>
|
||||
</div>
|
||||
|
|
|
@ -40,7 +40,7 @@ const toolDescription = computed<string>(() => t(`tools.${i18nKey.value}.descrip
|
|||
</n-h1>
|
||||
|
||||
<div>
|
||||
<FavoriteButton :tool="{ name: route.meta.name } as Tool" />
|
||||
<FavoriteButton :tool="{ name: route.meta.name, path: route.path } as Tool" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import { createPinia } from 'pinia';
|
|||
import { createHead } from '@vueuse/head';
|
||||
|
||||
import { registerSW } from 'virtual:pwa-register';
|
||||
import shadow from 'vue-shadow-dom';
|
||||
import { plausible } from './plugins/plausible.plugin';
|
||||
|
||||
import 'virtual:uno.css';
|
||||
|
@ -23,5 +24,6 @@ app.use(i18nPlugin);
|
|||
app.use(router);
|
||||
app.use(naive);
|
||||
app.use(plausible);
|
||||
app.use(shadow);
|
||||
|
||||
app.mount('#app');
|
||||
|
|
|
@ -128,7 +128,7 @@ function activateOption(option: PaletteOption) {
|
|||
<c-input-text ref="inputRef" v-model:value="searchPrompt" raw-text placeholder="Type to search a tool or a command..." autofocus clearable />
|
||||
|
||||
<div v-for="(options, category) in filteredSearchResult" :key="category">
|
||||
<div ml-3 mt-3 text-sm font-bold text-primary op-60>
|
||||
<div ml-3 mt-3 text-sm text-primary font-bold op-60>
|
||||
{{ category }}
|
||||
</div>
|
||||
<command-palette-option v-for="option in options" :key="option.name" :option="option" :selected="selectedOptionIndex === getOptionIndex(option)" @activated="activateOption" />
|
||||
|
|
|
@ -3,8 +3,10 @@ const { availableLocales, locale } = useI18n();
|
|||
|
||||
const localesLong: Record<string, string> = {
|
||||
en: 'English',
|
||||
de: 'Deutsch',
|
||||
es: 'Español',
|
||||
fr: 'Français',
|
||||
no: 'Norwegian',
|
||||
pt: 'Português',
|
||||
ru: 'Русский',
|
||||
uk: 'Українська',
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import { Heart } from '@vicons/tabler';
|
||||
import { IconDragDrop, IconFileDescription, IconHeart } from '@tabler/icons-vue';
|
||||
import { useHead } from '@vueuse/head';
|
||||
import { computed } from 'vue';
|
||||
import Draggable from 'vuedraggable';
|
||||
import ColoredCard from '../components/ColoredCard.vue';
|
||||
import ToolCard from '../components/ToolCard.vue';
|
||||
import { useToolStore } from '@/tools/tools.store';
|
||||
|
@ -10,13 +12,20 @@ const toolStore = useToolStore();
|
|||
|
||||
useHead({ title: 'IT Tools - Handy online tools for developers' });
|
||||
const { t } = useI18n();
|
||||
|
||||
const favoriteTools = computed(() => toolStore.favoriteTools);
|
||||
|
||||
// Update favorite tools order when drag is finished
|
||||
function onUpdateFavoriteTools() {
|
||||
toolStore.updateFavoriteTools(favoriteTools.value); // Update the store with the new order
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="pt-50px">
|
||||
<div class="grid-wrapper">
|
||||
<div v-if="config.showBanner" class="grid grid-cols-1 gap-12px lg:grid-cols-3 md:grid-cols-3 sm:grid-cols-2 xl:grid-cols-4">
|
||||
<ColoredCard :title="$t('home.follow.title')" :icon="Heart">
|
||||
<div class="grid grid-cols-1 gap-12px lg:grid-cols-3 md:grid-cols-3 sm:grid-cols-2 xl:grid-cols-4">
|
||||
<ColoredCard v-if="config.showBanner" :title="$t('home.follow.title')" :icon="IconHeart">
|
||||
{{ $t('home.follow.p1') }}
|
||||
<a
|
||||
href="https://github.com/CorentinTh/it-tools"
|
||||
|
@ -26,29 +35,58 @@ const { t } = useI18n();
|
|||
>GitHub</a>
|
||||
{{ $t('home.follow.p2') }}
|
||||
<a
|
||||
href="https://twitter.com/ittoolsdottech"
|
||||
href="https://x.com/ittoolsdottech"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
:aria-label="$t('home.follow.twitterAccount')"
|
||||
>Twitter</a>.
|
||||
:aria-label="$t('home.follow.twitterXAccount')"
|
||||
>X</a>.
|
||||
{{ $t('home.follow.thankYou') }}
|
||||
<n-icon :component="Heart" />
|
||||
<n-icon :component="IconHeart" />
|
||||
</ColoredCard>
|
||||
|
||||
<a href="https://renderize.tech?utm_source=it-tools&utm_medium=banner" target="_blank" rel="noopener" class="text-current decoration-none">
|
||||
<c-card v-if="config.showSponsorBanner" class="cursor-pointer !border-2px !hover:border-primary">
|
||||
<div class="flex items-center justify-between">
|
||||
<n-icon :component="IconFileDescription" class="text-neutral-400 dark:text-neutral-600" size="40" />
|
||||
<div class="rounded-full bg-#eeeeee px-10px py-2px text-xs text-black dark:bg-#333333 dark:text-white">
|
||||
Sponsor
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-5px flex items-baseline gap-4 text-balance text-lg text-black dark:text-white">
|
||||
Generate PDFs from HTML with Renderize API
|
||||
</div>
|
||||
<div class="text-neutral-500 dark:text-neutral-400">
|
||||
Automate your document generation with our fast, developer-friendly API. Start with a free forever plan.
|
||||
</div>
|
||||
</c-card>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<transition name="height">
|
||||
<div v-if="toolStore.favoriteTools.length > 0">
|
||||
<h3 class="mb-5px mt-25px font-500 text-neutral-400">
|
||||
<h3 class="mb-5px mt-25px text-neutral-400 font-500">
|
||||
{{ $t('home.categories.favoriteTools') }}
|
||||
<c-tooltip :tooltip="$t('home.categories.favoritesDndToolTip')">
|
||||
<n-icon :component="IconDragDrop" size="18" />
|
||||
</c-tooltip>
|
||||
</h3>
|
||||
<div class="grid grid-cols-1 gap-12px lg:grid-cols-3 md:grid-cols-3 sm:grid-cols-2 xl:grid-cols-4">
|
||||
<ToolCard v-for="tool in toolStore.favoriteTools" :key="tool.name" :tool="tool" />
|
||||
</div>
|
||||
<Draggable
|
||||
:list="favoriteTools"
|
||||
class="grid grid-cols-1 gap-12px lg:grid-cols-3 md:grid-cols-3 sm:grid-cols-2 xl:grid-cols-4"
|
||||
ghost-class="ghost-favorites-draggable"
|
||||
item-key="name"
|
||||
@end="onUpdateFavoriteTools"
|
||||
>
|
||||
<template #item="{ element: tool }">
|
||||
<ToolCard :tool="tool" />
|
||||
</template>
|
||||
</Draggable>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<div v-if="toolStore.newTools.length > 0">
|
||||
<h3 class="mb-5px mt-25px font-500 text-neutral-400">
|
||||
<h3 class="mb-5px mt-25px text-neutral-400 font-500">
|
||||
{{ t('home.categories.newestTools') }}
|
||||
</h3>
|
||||
<div class="grid grid-cols-1 gap-12px lg:grid-cols-3 md:grid-cols-3 sm:grid-cols-2 xl:grid-cols-4">
|
||||
|
@ -56,7 +94,7 @@ const { t } = useI18n();
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="mb-5px mt-25px font-500 text-neutral-400">
|
||||
<h3 class="mb-5px mt-25px text-neutral-400 font-500">
|
||||
{{ $t('home.categories.allTools') }}
|
||||
</h3>
|
||||
<div class="grid grid-cols-1 gap-12px lg:grid-cols-3 md:grid-cols-3 sm:grid-cols-2 xl:grid-cols-4">
|
||||
|
@ -81,4 +119,24 @@ const { t } = useI18n();
|
|||
opacity: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.ghost-favorites-draggable {
|
||||
opacity: 0.4;
|
||||
background-color: #ccc;
|
||||
border: 2px dashed #666;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
transform: scale(1.1);
|
||||
animation: ghost-favorites-draggable-animation 0.2s ease-out;
|
||||
}
|
||||
|
||||
@keyframes ghost-favorites-draggable-animation {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
100% {
|
||||
opacity: 0.4;
|
||||
transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,12 +2,19 @@
|
|||
import { useBase64 } from '@vueuse/core';
|
||||
import type { Ref } from 'vue';
|
||||
import { useCopy } from '@/composable/copy';
|
||||
import { useDownloadFileFromBase64 } from '@/composable/downloadBase64';
|
||||
import { getExtensionFromMimeType, getMimeTypeFromBase64, previewImageFromBase64, useDownloadFileFromBase64Refs } from '@/composable/downloadBase64';
|
||||
import { useValidation } from '@/composable/validation';
|
||||
import { isValidBase64 } from '@/utils/base64';
|
||||
|
||||
const fileName = ref('file');
|
||||
const fileExtension = ref('');
|
||||
const base64Input = ref('');
|
||||
const { download } = useDownloadFileFromBase64({ source: base64Input });
|
||||
const { download } = useDownloadFileFromBase64Refs(
|
||||
{
|
||||
source: base64Input,
|
||||
filename: fileName,
|
||||
extension: fileExtension,
|
||||
});
|
||||
const base64InputValidation = useValidation({
|
||||
source: base64Input,
|
||||
rules: [
|
||||
|
@ -18,6 +25,35 @@ const base64InputValidation = useValidation({
|
|||
],
|
||||
});
|
||||
|
||||
watch(
|
||||
base64Input,
|
||||
(newValue, _) => {
|
||||
const { mimeType } = getMimeTypeFromBase64({ base64String: newValue });
|
||||
if (mimeType) {
|
||||
fileExtension.value = getExtensionFromMimeType(mimeType) || fileExtension.value;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function previewImage() {
|
||||
if (!base64InputValidation.isValid) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const image = previewImageFromBase64(base64Input.value);
|
||||
image.style.maxWidth = '100%';
|
||||
image.style.maxHeight = '400px';
|
||||
const previewContainer = document.getElementById('previewContainer');
|
||||
if (previewContainer) {
|
||||
previewContainer.innerHTML = '';
|
||||
previewContainer.appendChild(image);
|
||||
}
|
||||
}
|
||||
catch (_) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
function downloadFile() {
|
||||
if (!base64InputValidation.isValid) {
|
||||
return;
|
||||
|
@ -44,6 +80,24 @@ async function onUpload(file: File) {
|
|||
|
||||
<template>
|
||||
<c-card title="Base64 to file">
|
||||
<n-grid cols="3" x-gap="12">
|
||||
<n-gi span="2">
|
||||
<c-input-text
|
||||
v-model:value="fileName"
|
||||
label="File Name"
|
||||
placeholder="Download filename"
|
||||
mb-2
|
||||
/>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<c-input-text
|
||||
v-model:value="fileExtension"
|
||||
label="Extension"
|
||||
placeholder="Extension"
|
||||
mb-2
|
||||
/>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<c-input-text
|
||||
v-model:value="base64Input"
|
||||
multiline
|
||||
|
@ -53,7 +107,14 @@ async function onUpload(file: File) {
|
|||
mb-2
|
||||
/>
|
||||
|
||||
<div flex justify-center>
|
||||
<div flex justify-center py-2>
|
||||
<div id="previewContainer" />
|
||||
</div>
|
||||
|
||||
<div flex justify-center gap-3>
|
||||
<c-button :disabled="base64Input === '' || !base64InputValidation.isValid" @click="previewImage()">
|
||||
Preview image
|
||||
</c-button>
|
||||
<c-button :disabled="base64Input === '' || !base64InputValidation.isValid" @click="downloadFile()">
|
||||
Download file
|
||||
</c-button>
|
||||
|
|
|
@ -28,7 +28,7 @@ const compareMatch = computed(() => compareSync(compareString.value, compareHash
|
|||
mb-2
|
||||
/>
|
||||
<n-form-item label="Salt count: " label-placement="left" label-width="120">
|
||||
<n-input-number v-model:value="saltCount" placeholder="Salt rounds..." :max="10" :min="0" w-full />
|
||||
<n-input-number v-model:value="saltCount" placeholder="Salt rounds..." :max="100" :min="0" w-full />
|
||||
</n-form-item>
|
||||
|
||||
<c-input-text :value="hashed" readonly text-center />
|
||||
|
|
65
src/tools/email-normalizer/email-normalizer.vue
Normal file
65
src/tools/email-normalizer/email-normalizer.vue
Normal file
|
@ -0,0 +1,65 @@
|
|||
<script setup lang="ts">
|
||||
import { normalizeEmail } from 'email-normalizer';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import { useCopy } from '@/composable/copy';
|
||||
|
||||
const emails = ref('');
|
||||
const normalizedEmails = computed(() => {
|
||||
if (!emails.value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return emails.value
|
||||
.split('\n')
|
||||
.map((email) => {
|
||||
return withDefaultOnError(() => normalizeEmail({ email }), `Unable to parse email: ${email}`);
|
||||
})
|
||||
.join('\n');
|
||||
});
|
||||
|
||||
const { copy } = useCopy({ source: normalizedEmails, text: 'Normalized emails copied to the clipboard', createToast: true });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="mb-2">
|
||||
Raw emails to normalize:
|
||||
</div>
|
||||
<c-input-text
|
||||
v-model:value="emails"
|
||||
placeholder="Put your emails here (one per line)..."
|
||||
rows="3"
|
||||
multiline
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="off"
|
||||
spellcheck="false"
|
||||
autofocus
|
||||
monospace
|
||||
/>
|
||||
|
||||
<div class="mb-2 mt-4">
|
||||
Normalized emails:
|
||||
</div>
|
||||
<c-input-text
|
||||
:value="normalizedEmails"
|
||||
placeholder="Normalized emails will appear here..."
|
||||
rows="3"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="off"
|
||||
spellcheck="false"
|
||||
multiline
|
||||
readonly
|
||||
monospace
|
||||
/>
|
||||
<div class="mt-4 flex justify-center gap-2">
|
||||
<c-button @click="emails = ''">
|
||||
Clear emails
|
||||
</c-button>
|
||||
<c-button :disabled="!normalizedEmails" @click="copy()">
|
||||
Copy normalized emails
|
||||
</c-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
12
src/tools/email-normalizer/index.ts
Normal file
12
src/tools/email-normalizer/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { Mail } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'Email normalizer',
|
||||
path: '/email-normalizer',
|
||||
description: 'Normalize email addresses to a standard format for easier comparison. Useful for deduplication and data cleaning.',
|
||||
keywords: ['email', 'normalizer'],
|
||||
component: () => import('./email-normalizer.vue'),
|
||||
icon: Mail,
|
||||
createdAt: new Date('2024-08-15'),
|
||||
});
|
|
@ -4,6 +4,7 @@ import emojiKeywords from 'emojilib';
|
|||
import _ from 'lodash';
|
||||
import type { EmojiInfo } from './emoji.types';
|
||||
import { useFuzzySearch } from '@/composable/fuzzySearch';
|
||||
import useDebouncedRef from '@/composable/debouncedref';
|
||||
|
||||
const escapeUnicode = ({ emoji }: { emoji: string }) => emoji.split('').map(unit => `\\u${unit.charCodeAt(0).toString(16).padStart(4, '0')}`).join('');
|
||||
const getEmojiCodePoints = ({ emoji }: { emoji: string }) => emoji.codePointAt(0) ? `0x${emoji.codePointAt(0)?.toString(16)}` : undefined;
|
||||
|
@ -23,7 +24,7 @@ const emojisGroups: { emojiInfos: EmojiInfo[]; group: string }[] = _
|
|||
.map((emojiInfos, group) => ({ group, emojiInfos }))
|
||||
.value();
|
||||
|
||||
const searchQuery = ref('');
|
||||
const searchQuery = useDebouncedRef('', 500);
|
||||
|
||||
const { searchResult } = useFuzzySearch({
|
||||
search: searchQuery,
|
||||
|
|
|
@ -84,8 +84,8 @@ const items: MenuItem[] = [
|
|||
type: 'button',
|
||||
icon: H3,
|
||||
title: 'Heading 3',
|
||||
action: () => editor.value.chain().focus().toggleHeading({ level: 4 }).run(),
|
||||
isActive: () => editor.value.isActive('heading', { level: 4 }),
|
||||
action: () => editor.value.chain().focus().toggleHeading({ level: 3 }).run(),
|
||||
isActive: () => editor.value.isActive('heading', { level: 3 }),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
import { tool as base64FileConverter } from './base64-file-converter';
|
||||
import { tool as base64StringConverter } from './base64-string-converter';
|
||||
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
||||
import { tool as emailNormalizer } from './email-normalizer';
|
||||
|
||||
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
||||
|
||||
import { tool as textToUnicode } from './text-to-unicode';
|
||||
import { tool as safelinkDecoder } from './safelink-decoder';
|
||||
import { tool as htmlCleaner } from './html-cleaner';
|
||||
import { tool as xmlToJson } from './xml-to-json';
|
||||
import { tool as jsonToXml } from './json-to-xml';
|
||||
import { tool as regexTester } from './regex-tester';
|
||||
import { tool as regexMemo } from './regex-memo';
|
||||
import { tool as markdownToHtml } from './markdown-to-html';
|
||||
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
|
||||
import { tool as numeronymGenerator } from './numeronym-generator';
|
||||
import { tool as macAddressGenerator } from './mac-address-generator';
|
||||
|
@ -109,6 +115,9 @@ export const toolsByCategory: ToolCategory[] = [
|
|||
tomlToJson,
|
||||
tomlToYaml,
|
||||
htmlCleaner,
|
||||
xmlToJson,
|
||||
jsonToXml,
|
||||
markdownToHtml,
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -150,6 +159,9 @@ export const toolsByCategory: ToolCategory[] = [
|
|||
dockerRunToDockerComposeConverter,
|
||||
xmlFormatter,
|
||||
yamlViewer,
|
||||
emailNormalizer,
|
||||
regexTester,
|
||||
regexMemo,
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -11,6 +11,9 @@ describe('integer-base-converter', () => {
|
|||
expect(convertBase({ value: '10100101', fromBase: 2, toBase: 16 })).toEqual('a5');
|
||||
expect(convertBase({ value: '192654', fromBase: 10, toBase: 8 })).toEqual('570216');
|
||||
expect(convertBase({ value: 'zz', fromBase: 64, toBase: 10 })).toEqual('2275');
|
||||
expect(convertBase({ value: '42540766411283223938465490632011909384', fromBase: 10, toBase: 10 })).toEqual('42540766411283223938465490632011909384');
|
||||
expect(convertBase({ value: '42540766411283223938465490632011909384', fromBase: 10, toBase: 16 })).toEqual('20010db8000085a300000000ac1f8908');
|
||||
expect(convertBase({ value: '20010db8000085a300000000ac1f8908', fromBase: 16, toBase: 10 })).toEqual('42540766411283223938465490632011909384');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,16 +5,16 @@ export function convertBase({ value, fromBase, toBase }: { value: string; fromBa
|
|||
let decValue = value
|
||||
.split('')
|
||||
.reverse()
|
||||
.reduce((carry: number, digit: string, index: number) => {
|
||||
.reduce((carry: bigint, digit: string, index: number) => {
|
||||
if (!fromRange.includes(digit)) {
|
||||
throw new Error(`Invalid digit "${digit}" for base ${fromBase}.`);
|
||||
}
|
||||
return (carry += fromRange.indexOf(digit) * fromBase ** index);
|
||||
}, 0);
|
||||
return (carry += BigInt(fromRange.indexOf(digit)) * BigInt(fromBase) ** BigInt(index));
|
||||
}, 0n);
|
||||
let newValue = '';
|
||||
while (decValue > 0) {
|
||||
newValue = toRange[decValue % toBase] + newValue;
|
||||
decValue = (decValue - (decValue % toBase)) / toBase;
|
||||
newValue = toRange[Number(decValue % BigInt(toBase))] + newValue;
|
||||
decValue = (decValue - (decValue % BigInt(toBase))) / BigInt(toBase);
|
||||
}
|
||||
return newValue || '0';
|
||||
}
|
||||
|
|
12
src/tools/json-to-xml/index.ts
Normal file
12
src/tools/json-to-xml/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { Braces } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'JSON to XML',
|
||||
path: '/json-to-xml',
|
||||
description: 'Convert JSON to XML',
|
||||
keywords: ['json', 'xml'],
|
||||
component: () => import('./json-to-xml.vue'),
|
||||
icon: Braces,
|
||||
createdAt: new Date('2024-08-09'),
|
||||
});
|
32
src/tools/json-to-xml/json-to-xml.vue
Normal file
32
src/tools/json-to-xml/json-to-xml.vue
Normal file
|
@ -0,0 +1,32 @@
|
|||
<script setup lang="ts">
|
||||
import convert from 'xml-js';
|
||||
import JSON5 from 'json5';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import type { UseValidationRule } from '@/composable/validation';
|
||||
|
||||
const defaultValue = '{"a":{"_attributes":{"x":"1.234","y":"It\'s"}}}';
|
||||
function transformer(value: string) {
|
||||
return withDefaultOnError(() => {
|
||||
return convert.js2xml(JSON5.parse(value), { compact: true });
|
||||
}, '');
|
||||
}
|
||||
|
||||
const rules: UseValidationRule<string>[] = [
|
||||
{
|
||||
validator: (v: string) => v === '' || JSON5.parse(v),
|
||||
message: 'Provided JSON is not valid.',
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<format-transformer
|
||||
input-label="Your JSON content"
|
||||
:input-default="defaultValue"
|
||||
input-placeholder="Paste your JSON content here..."
|
||||
output-label="Converted XML"
|
||||
output-language="xml"
|
||||
:transformer="transformer"
|
||||
:input-validation-rules="rules"
|
||||
/>
|
||||
</template>
|
|
@ -39,7 +39,7 @@ const validation = useValidation({
|
|||
{{ section.title }}
|
||||
</th>
|
||||
<tr v-for="{ claim, claimDescription, friendlyValue, value } in decodedJWT[section.key]" :key="claim + value">
|
||||
<td class="claims">
|
||||
<td class="claims" style="vertical-align: top;">
|
||||
<span font-bold>
|
||||
{{ claim }}
|
||||
</span>
|
||||
|
@ -47,7 +47,7 @@ const validation = useValidation({
|
|||
({{ claimDescription }})
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<td style="word-wrap: break-word;word-break: break-all;">
|
||||
<span>{{ value }}</span>
|
||||
<span v-if="friendlyValue" ml-2 op-70>
|
||||
({{ friendlyValue }})
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { generateLoremIpsum } from './lorem-ipsum-generator.service';
|
||||
import { useCopy } from '@/composable/copy';
|
||||
import { randIntFromInterval } from '@/utils/random';
|
||||
import { computedRefreshable } from '@/composable/computedRefreshable';
|
||||
|
||||
const paragraphs = ref(1);
|
||||
const sentences = ref([3, 8]);
|
||||
|
@ -9,7 +10,7 @@ const words = ref([8, 15]);
|
|||
const startWithLoremIpsum = ref(true);
|
||||
const asHTML = ref(false);
|
||||
|
||||
const loremIpsumText = computed(() =>
|
||||
const [loremIpsumText, refreshLoremIpsum] = computedRefreshable(() =>
|
||||
generateLoremIpsum({
|
||||
paragraphCount: paragraphs.value,
|
||||
asHTML: asHTML.value,
|
||||
|
@ -18,6 +19,7 @@ const loremIpsumText = computed(() =>
|
|||
startWithLoremIpsum: startWithLoremIpsum.value,
|
||||
}),
|
||||
);
|
||||
|
||||
const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to the clipboard' });
|
||||
</script>
|
||||
|
||||
|
@ -41,10 +43,13 @@ const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to
|
|||
|
||||
<c-input-text :value="loremIpsumText" multiline placeholder="Your lorem ipsum..." readonly mt-5 rows="5" />
|
||||
|
||||
<div mt-5 flex justify-center>
|
||||
<div mt-5 flex justify-center gap-3>
|
||||
<c-button autofocus @click="copy()">
|
||||
Copy
|
||||
</c-button>
|
||||
<c-button @click="refreshLoremIpsum">
|
||||
Refresh
|
||||
</c-button>
|
||||
</div>
|
||||
</c-card>
|
||||
</template>
|
||||
|
|
12
src/tools/markdown-to-html/index.ts
Normal file
12
src/tools/markdown-to-html/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { Markdown } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'Markdown to HTML',
|
||||
path: '/markdown-to-html',
|
||||
description: 'Convert Markdown to Html and allow to print (as PDF)',
|
||||
keywords: ['markdown', 'html', 'converter', 'pdf'],
|
||||
component: () => import('./markdown-to-html.vue'),
|
||||
icon: Markdown,
|
||||
createdAt: new Date('2024-08-25'),
|
||||
});
|
44
src/tools/markdown-to-html/markdown-to-html.vue
Normal file
44
src/tools/markdown-to-html/markdown-to-html.vue
Normal file
|
@ -0,0 +1,44 @@
|
|||
<script setup lang="ts">
|
||||
import markdownit from 'markdown-it';
|
||||
import TextareaCopyable from '@/components/TextareaCopyable.vue';
|
||||
|
||||
const inputMarkdown = ref('');
|
||||
const outputHtml = computed(() => {
|
||||
const md = markdownit();
|
||||
return md.render(inputMarkdown.value);
|
||||
});
|
||||
|
||||
function printHtml() {
|
||||
const w = window.open();
|
||||
if (w === null) {
|
||||
return;
|
||||
}
|
||||
w.document.body.innerHTML = outputHtml.value;
|
||||
w.print();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<c-input-text
|
||||
v-model:value="inputMarkdown"
|
||||
multiline raw-text
|
||||
placeholder="Your Markdown content..."
|
||||
rows="8"
|
||||
autofocus
|
||||
label="Your Markdown to convert:"
|
||||
/>
|
||||
|
||||
<n-divider />
|
||||
|
||||
<n-form-item label="Output HTML:">
|
||||
<TextareaCopyable :value="outputHtml" :word-wrap="true" language="html" />
|
||||
</n-form-item>
|
||||
|
||||
<div flex justify-center>
|
||||
<n-button @click="printHtml">
|
||||
Print as PDF
|
||||
</n-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
12
src/tools/regex-memo/index.ts
Normal file
12
src/tools/regex-memo/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { BrandJavascript } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'Regex cheatsheet',
|
||||
path: '/regex-memo',
|
||||
description: 'Javascript Regex/Regular Expression cheatsheet',
|
||||
keywords: ['regex', 'regular', 'expression', 'javascript', 'memo', 'cheatsheet'],
|
||||
component: () => import('./regex-memo.vue'),
|
||||
icon: BrandJavascript,
|
||||
createdAt: new Date('2024-09-20'),
|
||||
});
|
121
src/tools/regex-memo/regex-memo.content.md
Normal file
121
src/tools/regex-memo/regex-memo.content.md
Normal file
|
@ -0,0 +1,121 @@
|
|||
### Normal characters
|
||||
|
||||
Expression | Description
|
||||
:--|:--
|
||||
`.` or `[^\n\r]` | any character *excluding* a newline or carriage return
|
||||
`[A-Za-z]` | alphabet
|
||||
`[a-z]` | lowercase alphabet
|
||||
`[A-Z]` | uppercase alphabet
|
||||
`\d` or `[0-9]` | digit
|
||||
`\D` or `[^0-9]` | non-digit
|
||||
`_` | underscore
|
||||
`\w` or `[A-Za-z0-9_]` | alphabet, digit or underscore
|
||||
`\W` or `[^A-Za-z0-9_]` | inverse of `\w`
|
||||
`\S` | inverse of `\s`
|
||||
|
||||
### Whitespace characters
|
||||
|
||||
Expression | Description
|
||||
:--|:--
|
||||
` ` | space
|
||||
`\t` | tab
|
||||
`\n` | newline
|
||||
`\r` | carriage return
|
||||
`\s` | space, tab, newline or carriage return
|
||||
|
||||
### Character set
|
||||
|
||||
Expression | Description
|
||||
:--|:--
|
||||
`[xyz]` | either `x`, `y` or `z`
|
||||
`[^xyz]` | neither `x`, `y` nor `z`
|
||||
`[1-3]` | either `1`, `2` or `3`
|
||||
`[^1-3]` | neither `1`, `2` nor `3`
|
||||
|
||||
- Think of a character set as an `OR` operation on the single characters that are enclosed between the square brackets.
|
||||
- Use `^` after the opening `[` to “negate” the character set.
|
||||
- Within a character set, `.` means a literal period.
|
||||
|
||||
### Characters that require escaping
|
||||
|
||||
#### Outside a character set
|
||||
|
||||
Expression | Description
|
||||
:--|:--
|
||||
`\.` | period
|
||||
`\^` | caret
|
||||
`\$` | dollar sign
|
||||
`\|` | pipe
|
||||
`\\` | back slash
|
||||
`\/` | forward slash
|
||||
`\(` | opening bracket
|
||||
`\)` | closing bracket
|
||||
`\[` | opening square bracket
|
||||
`\]` | closing square bracket
|
||||
`\{` | opening curly bracket
|
||||
`\}` | closing curly bracket
|
||||
|
||||
#### Inside a character set
|
||||
|
||||
Expression | Description
|
||||
:--|:--
|
||||
`\\` | back slash
|
||||
`\]` | closing square bracket
|
||||
|
||||
- A `^` must be escaped only if it occurs immediately after the opening `[` of the character set.
|
||||
- A `-` must be escaped only if it occurs between two alphabets or two digits.
|
||||
|
||||
### Quantifiers
|
||||
|
||||
Expression | Description
|
||||
:--|:--
|
||||
`{2}` | exactly 2
|
||||
`{2,}` | at least 2
|
||||
`{2,7}` | at least 2 but no more than 7
|
||||
`*` | 0 or more
|
||||
`+` | 1 or more
|
||||
`?` | exactly 0 or 1
|
||||
|
||||
- The quantifier goes *after* the expression to be quantified.
|
||||
|
||||
### Boundaries
|
||||
|
||||
Expression | Description
|
||||
:--|:--
|
||||
`^` | start of string
|
||||
`$` | end of string
|
||||
`\b` | word boundary
|
||||
|
||||
- How word boundary matching works:
|
||||
- At the beginning of the string if the first character is `\w`.
|
||||
- Between two adjacent characters within the string, if the first character is `\w` and the second character is `\W`.
|
||||
- At the end of the string if the last character is `\w`.
|
||||
|
||||
### Matching
|
||||
|
||||
Expression | Description
|
||||
:--|:--
|
||||
`foo\|bar` | match either `foo` or `bar`
|
||||
`foo(?=bar)` | match `foo` if it’s before `bar`
|
||||
`foo(?!bar)` | match `foo` if it’s *not* before `bar`
|
||||
`(?<=bar)foo` | match `foo` if it’s after `bar`
|
||||
`(?<!bar)foo` | match `foo` if it’s *not* after `bar`
|
||||
|
||||
### Grouping and capturing
|
||||
|
||||
Expression | Description
|
||||
:--|:--
|
||||
`(foo)` | capturing group; match and capture `foo`
|
||||
`(?:foo)` | non-capturing group; match `foo` but *without* capturing `foo`
|
||||
`(foo)bar\1` | `\1` is a backreference to the 1st capturing group; match `foobarfoo`
|
||||
|
||||
- Capturing groups are only relevant in the following methods:
|
||||
- `string.match(regexp)`
|
||||
- `string.matchAll(regexp)`
|
||||
- `string.replace(regexp, callback)`
|
||||
- `\N` is a backreference to the `Nth` capturing group. Capturing groups are numbered starting from 1.
|
||||
|
||||
## References and tools
|
||||
|
||||
- [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)
|
||||
- [RegExplained](https://leaverou.github.io/regexplained/)
|
32
src/tools/regex-memo/regex-memo.vue
Normal file
32
src/tools/regex-memo/regex-memo.vue
Normal file
|
@ -0,0 +1,32 @@
|
|||
<script setup lang="ts">
|
||||
import { useThemeVars } from 'naive-ui';
|
||||
import Memo from './regex-memo.content.md';
|
||||
|
||||
const themeVars = useThemeVars();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Memo />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
::v-deep(pre) {
|
||||
margin: 0;
|
||||
padding: 15px 22px;
|
||||
background-color: v-bind('themeVars.cardColor');
|
||||
border-radius: 4px;
|
||||
overflow: auto;
|
||||
}
|
||||
::v-deep(table) {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
::v-deep(table), ::v-deep(td), ::v-deep(th) {
|
||||
border: 1px solid v-bind('themeVars.textColor1');
|
||||
padding: 5px;
|
||||
}
|
||||
::v-deep(a) {
|
||||
color: v-bind('themeVars.textColor1');
|
||||
}
|
||||
</style>
|
12
src/tools/regex-tester/index.ts
Normal file
12
src/tools/regex-tester/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { Language } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'Regex Tester',
|
||||
path: '/regex-tester',
|
||||
description: 'Test your regular expressions with sample text.',
|
||||
keywords: ['regex', 'tester', 'sample', 'expression'],
|
||||
component: () => import('./regex-tester.vue'),
|
||||
icon: Language,
|
||||
createdAt: new Date('2024-09-20'),
|
||||
});
|
106
src/tools/regex-tester/regex-tester.service.test.ts
Normal file
106
src/tools/regex-tester/regex-tester.service.test.ts
Normal file
|
@ -0,0 +1,106 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { matchRegex } from './regex-tester.service';
|
||||
|
||||
const regexesData = [
|
||||
{
|
||||
regex: '',
|
||||
text: '',
|
||||
flags: '',
|
||||
result: [],
|
||||
},
|
||||
{
|
||||
regex: '.*',
|
||||
text: '',
|
||||
flags: '',
|
||||
result: [],
|
||||
},
|
||||
{
|
||||
regex: '',
|
||||
text: 'aaa',
|
||||
flags: '',
|
||||
result: [],
|
||||
},
|
||||
{
|
||||
regex: 'a',
|
||||
text: 'baaa',
|
||||
flags: '',
|
||||
result: [
|
||||
{
|
||||
captures: [],
|
||||
groups: [],
|
||||
index: 1,
|
||||
value: 'a',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
regex: '(.)(?<g>r)',
|
||||
text: 'azertyr',
|
||||
flags: 'g',
|
||||
result: [
|
||||
{
|
||||
captures: [
|
||||
{
|
||||
end: 3,
|
||||
name: '1',
|
||||
start: 2,
|
||||
value: 'e',
|
||||
},
|
||||
{
|
||||
end: 4,
|
||||
name: '2',
|
||||
start: 3,
|
||||
value: 'r',
|
||||
},
|
||||
],
|
||||
groups: [
|
||||
{
|
||||
end: 4,
|
||||
name: 'g',
|
||||
start: 3,
|
||||
value: 'r',
|
||||
},
|
||||
],
|
||||
index: 2,
|
||||
value: 'er',
|
||||
},
|
||||
{
|
||||
captures: [
|
||||
{
|
||||
end: 6,
|
||||
name: '1',
|
||||
start: 5,
|
||||
value: 'y',
|
||||
},
|
||||
{
|
||||
end: 7,
|
||||
name: '2',
|
||||
start: 6,
|
||||
value: 'r',
|
||||
},
|
||||
],
|
||||
groups: [
|
||||
{
|
||||
end: 7,
|
||||
name: 'g',
|
||||
start: 6,
|
||||
value: 'r',
|
||||
},
|
||||
],
|
||||
index: 5,
|
||||
value: 'yr',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
describe('regex-tester', () => {
|
||||
for (const reg of regexesData) {
|
||||
const { regex, text, flags, result: expected_result } = reg;
|
||||
it(`Should matchRegex("${regex}","${text}","${flags}") return correct result`, async () => {
|
||||
const result = matchRegex(regex, text, `${flags}d`);
|
||||
|
||||
expect(result).to.deep.equal(expected_result);
|
||||
});
|
||||
}
|
||||
});
|
61
src/tools/regex-tester/regex-tester.service.ts
Normal file
61
src/tools/regex-tester/regex-tester.service.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
interface RegExpGroupIndices {
|
||||
[name: string]: [number, number]
|
||||
}
|
||||
interface RegExpIndices extends Array<[number, number]> {
|
||||
groups: RegExpGroupIndices
|
||||
}
|
||||
interface RegExpExecArrayWithIndices extends RegExpExecArray {
|
||||
indices: RegExpIndices
|
||||
}
|
||||
interface GroupCapture {
|
||||
name: string
|
||||
value: string
|
||||
start: number
|
||||
end: number
|
||||
};
|
||||
|
||||
export function matchRegex(regex: string, text: string, flags: string) {
|
||||
// if (regex === '' || text === '') {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
let lastIndex = -1;
|
||||
const re = new RegExp(regex, flags);
|
||||
const results = [];
|
||||
let match = re.exec(text) as RegExpExecArrayWithIndices;
|
||||
while (match !== null) {
|
||||
if (re.lastIndex === lastIndex || match[0] === '') {
|
||||
break;
|
||||
}
|
||||
const indices = match.indices;
|
||||
const captures: Array<GroupCapture> = [];
|
||||
Object.entries(match).forEach(([captureName, captureValue]) => {
|
||||
if (captureName !== '0' && captureName.match(/\d+/)) {
|
||||
captures.push({
|
||||
name: captureName,
|
||||
value: captureValue,
|
||||
start: indices[Number(captureName)][0],
|
||||
end: indices[Number(captureName)][1],
|
||||
});
|
||||
}
|
||||
});
|
||||
const groups: Array<GroupCapture> = [];
|
||||
Object.entries(match.groups || {}).forEach(([groupName, groupValue]) => {
|
||||
groups.push({
|
||||
name: groupName,
|
||||
value: groupValue,
|
||||
start: indices.groups[groupName][0],
|
||||
end: indices.groups[groupName][1],
|
||||
});
|
||||
});
|
||||
results.push({
|
||||
index: match.index,
|
||||
value: match[0],
|
||||
captures,
|
||||
groups,
|
||||
});
|
||||
lastIndex = re.lastIndex;
|
||||
match = re.exec(text) as RegExpExecArrayWithIndices;
|
||||
}
|
||||
return results;
|
||||
}
|
193
src/tools/regex-tester/regex-tester.vue
Normal file
193
src/tools/regex-tester/regex-tester.vue
Normal file
|
@ -0,0 +1,193 @@
|
|||
<script setup lang="ts">
|
||||
import RandExp from 'randexp';
|
||||
import { render } from '@regexper/render';
|
||||
import type { ShadowRootExpose } from 'vue-shadow-dom';
|
||||
import { matchRegex } from './regex-tester.service';
|
||||
import { useValidation } from '@/composable/validation';
|
||||
import { useQueryParamOrStorage } from '@/composable/queryParams';
|
||||
|
||||
const regex = useQueryParamOrStorage({ name: 'regex', storageName: 'regex-tester:regex', defaultValue: '' });
|
||||
const text = ref('');
|
||||
const global = ref(true);
|
||||
const ignoreCase = ref(false);
|
||||
const multiline = ref(false);
|
||||
const dotAll = ref(true);
|
||||
const unicode = ref(true);
|
||||
const unicodeSets = ref(false);
|
||||
const visualizerSVG = ref<ShadowRootExpose>();
|
||||
|
||||
const regexValidation = useValidation({
|
||||
source: regex,
|
||||
rules: [
|
||||
{
|
||||
message: 'Invalid regex: {0}',
|
||||
validator: value => new RegExp(value),
|
||||
getErrorMessage: (value) => {
|
||||
const _ = new RegExp(value);
|
||||
return '';
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
const results = computed(() => {
|
||||
let flags = 'd';
|
||||
if (global.value) {
|
||||
flags += 'g';
|
||||
}
|
||||
if (ignoreCase.value) {
|
||||
flags += 'i';
|
||||
}
|
||||
if (multiline.value) {
|
||||
flags += 'm';
|
||||
}
|
||||
if (dotAll.value) {
|
||||
flags += 's';
|
||||
}
|
||||
if (unicode.value) {
|
||||
flags += 'u';
|
||||
}
|
||||
else if (unicodeSets.value) {
|
||||
flags += 'v';
|
||||
}
|
||||
|
||||
try {
|
||||
return matchRegex(regex.value, text.value, flags);
|
||||
}
|
||||
catch (_) {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
const sample = computed(() => {
|
||||
try {
|
||||
const randexp = new RandExp(new RegExp(regex.value.replace(/\(\?\<[^\>]*\>/g, '(?:')));
|
||||
return randexp.gen();
|
||||
}
|
||||
catch (_) {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
watchEffect(
|
||||
async () => {
|
||||
const regexValue = regex.value;
|
||||
// shadow root is required:
|
||||
// @regexper/render append a <defs><style> that broke svg transparency of icons in the whole site
|
||||
const visualizer = visualizerSVG.value?.shadow_root;
|
||||
if (visualizer) {
|
||||
while (visualizer.lastChild) {
|
||||
visualizer.removeChild(visualizer.lastChild);
|
||||
}
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
try {
|
||||
await render(regexValue, svg);
|
||||
}
|
||||
catch (_) {
|
||||
}
|
||||
visualizer.appendChild(svg);
|
||||
}
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div max-w-600px>
|
||||
<c-card title="Regex" mb-1>
|
||||
<c-input-text
|
||||
v-model:value="regex"
|
||||
label="Regex to test:"
|
||||
placeholder="Put the regex to test"
|
||||
multiline
|
||||
rows="3"
|
||||
:validation="regexValidation"
|
||||
/>
|
||||
<router-link target="_blank" to="/regex-memo" mb-1 mt-1>
|
||||
See Regular Expression Cheatsheet
|
||||
</router-link>
|
||||
<n-space>
|
||||
<n-checkbox v-model:checked="global">
|
||||
<span title="Global search">Global search. (<code>g</code>)</span>
|
||||
</n-checkbox>
|
||||
<n-checkbox v-model:checked="ignoreCase">
|
||||
<span title="Case-insensitive search">Case-insensitive search. (<code>i</code>)</span>
|
||||
</n-checkbox>
|
||||
<n-checkbox v-model:checked="multiline">
|
||||
<span title="Allows ^ and $ to match next to newline characters.">Multiline(<code>m</code>)</span>
|
||||
</n-checkbox>
|
||||
<n-checkbox v-model:checked="dotAll">
|
||||
<span title="Allows . to match newline characters.">Singleline(<code>s</code>)</span>
|
||||
</n-checkbox>
|
||||
<n-checkbox v-model:checked="unicode">
|
||||
<span title="Unicode; treat a pattern as a sequence of Unicode code points.">Unicode(<code>u</code>)</span>
|
||||
</n-checkbox>
|
||||
<n-checkbox v-model:checked="unicodeSets">
|
||||
<span title="An upgrade to the u mode with more Unicode features.">Unicode Sets (<code>v</code>)</span>
|
||||
</n-checkbox>
|
||||
</n-space>
|
||||
|
||||
<n-divider />
|
||||
|
||||
<c-input-text
|
||||
v-model:value="text"
|
||||
label="Text to match:"
|
||||
placeholder="Put the text to match"
|
||||
multiline
|
||||
rows="5"
|
||||
/>
|
||||
</c-card>
|
||||
|
||||
<c-card title="Matches" mb-1 mt-3>
|
||||
<n-table v-if="results?.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
Index in text
|
||||
</th>
|
||||
<th scope="col">
|
||||
Value
|
||||
</th>
|
||||
<th scope="col">
|
||||
Captures
|
||||
</th>
|
||||
<th scope="col">
|
||||
Groups
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="match of results" :key="match.index">
|
||||
<td>{{ match.index }}</td>
|
||||
<td>{{ match.value }}</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li v-for="capture in match.captures" :key="capture.name">
|
||||
"{{ capture.name }}" = {{ capture.value }} [{{ capture.start }} - {{ capture.end }}]
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li v-for="group in match.groups" :key="group.name">
|
||||
"{{ group.name }}" = {{ group.value }} [{{ group.start }} - {{ group.end }}]
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
<c-alert v-else>
|
||||
No match
|
||||
</c-alert>
|
||||
</c-card>
|
||||
|
||||
<c-card title="Sample matching text" mt-3>
|
||||
<pre style="white-space: pre-wrap; word-break: break-all;">{{ sample }}</pre>
|
||||
</c-card>
|
||||
|
||||
<c-card title="Regex Diagram" style="overflow-x: scroll;" mt-3>
|
||||
<shadow-root ref="visualizerSVG">
|
||||
 
|
||||
</shadow-root>
|
||||
</c-card>
|
||||
</div>
|
||||
</template>
|
|
@ -20,7 +20,7 @@ export function createToken({
|
|||
withLowercase ? 'abcdefghijklmopqrstuvwxyz' : '',
|
||||
withNumbers ? '0123456789' : '',
|
||||
withSymbols ? '.,;:!?./-"\'#{([-|\\@)]=}*+' : '',
|
||||
].join(''); ;
|
||||
].join('');
|
||||
|
||||
return shuffleString(allAlphabet.repeat(length)).substring(0, length);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ export const useToolStore = defineStore('tools', () => {
|
|||
|
||||
return ({
|
||||
...tool,
|
||||
path: tool.path,
|
||||
name: t(`tools.${toolI18nKey}.title`, tool.name),
|
||||
description: t(`tools.${toolI18nKey}.description`, tool.description),
|
||||
category: t(`tools.categories.${tool.category.toLowerCase()}`, tool.category),
|
||||
|
@ -23,8 +24,9 @@ export const useToolStore = defineStore('tools', () => {
|
|||
const toolsByCategory = computed<ToolCategory[]>(() => {
|
||||
return _.chain(tools.value)
|
||||
.groupBy('category')
|
||||
.map((components, name) => ({
|
||||
.map((components, name, path) => ({
|
||||
name,
|
||||
path,
|
||||
components,
|
||||
}))
|
||||
.value();
|
||||
|
@ -32,7 +34,7 @@ export const useToolStore = defineStore('tools', () => {
|
|||
|
||||
const favoriteTools = computed(() => {
|
||||
return favoriteToolsName.value
|
||||
.map(favoriteName => tools.value.find(({ name }) => name === favoriteName))
|
||||
.map(favoriteName => tools.value.find(({ name, path }) => name === favoriteName || path === favoriteName))
|
||||
.filter(Boolean) as ToolWithCategory[]; // cast because .filter(Boolean) does not remove undefined from type
|
||||
});
|
||||
|
||||
|
@ -43,15 +45,23 @@ export const useToolStore = defineStore('tools', () => {
|
|||
newTools: computed(() => tools.value.filter(({ isNew }) => isNew)),
|
||||
|
||||
addToolToFavorites({ tool }: { tool: MaybeRef<Tool> }) {
|
||||
favoriteToolsName.value.push(get(tool).name);
|
||||
const toolPath = get(tool).path;
|
||||
if (toolPath) {
|
||||
favoriteToolsName.value.push(toolPath);
|
||||
}
|
||||
},
|
||||
|
||||
removeToolFromFavorites({ tool }: { tool: MaybeRef<Tool> }) {
|
||||
favoriteToolsName.value = favoriteToolsName.value.filter(name => get(tool).name !== name);
|
||||
favoriteToolsName.value = favoriteToolsName.value.filter(name => get(tool).name !== name && get(tool).path !== name);
|
||||
},
|
||||
|
||||
isToolFavorite({ tool }: { tool: MaybeRef<Tool> }) {
|
||||
return favoriteToolsName.value.includes(get(tool).name);
|
||||
return favoriteToolsName.value.includes(get(tool).name)
|
||||
|| favoriteToolsName.value.includes(get(tool).path);
|
||||
},
|
||||
|
||||
updateFavoriteTools(newOrder: ToolWithCategory[]) {
|
||||
favoriteToolsName.value = newOrder.map(tool => tool.path);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
|
@ -23,7 +23,7 @@ const decodeInput = ref('Hello%20world%20%3A)');
|
|||
const decodeOutput = computed(() => withDefaultOnError(() => decodeURIComponent(decodeInput.value), ''));
|
||||
|
||||
const decodeValidation = useValidation({
|
||||
source: encodeInput,
|
||||
source: decodeInput,
|
||||
rules: [
|
||||
{
|
||||
validator: value => isNotThrowing(() => decodeURIComponent(value)),
|
||||
|
|
12
src/tools/xml-to-json/index.ts
Normal file
12
src/tools/xml-to-json/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { Braces } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'XML to JSON',
|
||||
path: '/xml-to-json',
|
||||
description: 'Convert XML to JSON',
|
||||
keywords: ['xml', 'json'],
|
||||
component: () => import('./xml-to-json.vue'),
|
||||
icon: Braces,
|
||||
createdAt: new Date('2024-08-09'),
|
||||
});
|
32
src/tools/xml-to-json/xml-to-json.vue
Normal file
32
src/tools/xml-to-json/xml-to-json.vue
Normal file
|
@ -0,0 +1,32 @@
|
|||
<script setup lang="ts">
|
||||
import convert from 'xml-js';
|
||||
import { isValidXML } from '../xml-formatter/xml-formatter.service';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import type { UseValidationRule } from '@/composable/validation';
|
||||
|
||||
const defaultValue = '<a x="1.234" y="It\'s"/>';
|
||||
function transformer(value: string) {
|
||||
return withDefaultOnError(() => {
|
||||
return JSON.stringify(convert.xml2js(value, { compact: true }), null, 2);
|
||||
}, '');
|
||||
}
|
||||
|
||||
const rules: UseValidationRule<string>[] = [
|
||||
{
|
||||
validator: isValidXML,
|
||||
message: 'Provided XML is not valid.',
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<format-transformer
|
||||
input-label="Your XML content"
|
||||
:input-default="defaultValue"
|
||||
input-placeholder="Paste your XML content here..."
|
||||
output-label="Converted JSON"
|
||||
output-language="json"
|
||||
:transformer="transformer"
|
||||
:input-validation-rules="rules"
|
||||
/>
|
||||
</template>
|
|
@ -28,4 +28,53 @@ test.describe('Tool - Yaml to json', () => {
|
|||
`.trim(),
|
||||
);
|
||||
});
|
||||
|
||||
test('Yaml is parsed with merge key and output correct json', async ({ page }) => {
|
||||
await page.getByTestId('input').fill(`
|
||||
default: &default
|
||||
name: ''
|
||||
age: 0
|
||||
|
||||
person:
|
||||
*default
|
||||
|
||||
persons:
|
||||
- <<: *default
|
||||
age: 1
|
||||
- <<: *default
|
||||
name: John
|
||||
- { age: 3, <<: *default }
|
||||
|
||||
`);
|
||||
|
||||
const generatedJson = await page.getByTestId('area-content').innerText();
|
||||
|
||||
expect(generatedJson.trim()).toEqual(
|
||||
`
|
||||
{
|
||||
"default": {
|
||||
"name": "",
|
||||
"age": 0
|
||||
},
|
||||
"person": {
|
||||
"name": "",
|
||||
"age": 0
|
||||
},
|
||||
"persons": [
|
||||
{
|
||||
"name": "",
|
||||
"age": 1
|
||||
},
|
||||
{
|
||||
"name": "John",
|
||||
"age": 0
|
||||
},
|
||||
{
|
||||
"age": 3,
|
||||
"name": ""
|
||||
}
|
||||
]
|
||||
}`.trim(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@ import { withDefaultOnError } from '@/utils/defaults';
|
|||
|
||||
function transformer(value: string) {
|
||||
return withDefaultOnError(() => {
|
||||
const obj = parseYaml(value);
|
||||
const obj = parseYaml(value, { merge: true });
|
||||
return obj ? JSON.stringify(obj, null, 3) : '';
|
||||
}, '');
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ const props = withDefaults(
|
|||
autosize?: boolean
|
||||
autofocus?: boolean
|
||||
monospace?: boolean
|
||||
pasteHtml?: boolean
|
||||
}>(),
|
||||
{
|
||||
value: '',
|
||||
|
@ -58,13 +59,14 @@ const props = withDefaults(
|
|||
autosize: false,
|
||||
autofocus: false,
|
||||
monospace: false,
|
||||
pasteHtml: false,
|
||||
},
|
||||
);
|
||||
const emit = defineEmits(['update:value']);
|
||||
const value = useVModel(props, 'value', emit);
|
||||
const showPassword = ref(false);
|
||||
|
||||
const { id, placeholder, label, validationRules, labelPosition, labelWidth, labelAlign, autosize, readonly, disabled, clearable, type, multiline, rows, rawText, autofocus, monospace } = toRefs(props);
|
||||
const { id, placeholder, label, validationRules, labelPosition, labelWidth, labelAlign, autosize, readonly, disabled, clearable, type, multiline, rows, rawText, autofocus, monospace, pasteHtml } = toRefs(props);
|
||||
|
||||
const validation
|
||||
= props.validation
|
||||
|
@ -81,6 +83,28 @@ const textareaRef = ref<HTMLTextAreaElement>();
|
|||
const inputRef = ref<HTMLInputElement>();
|
||||
const inputWrapperRef = ref<HTMLElement>();
|
||||
|
||||
interface HTMLElementWithValue {
|
||||
value?: string
|
||||
}
|
||||
|
||||
function onPasteInputHtml(evt: ClipboardEvent) {
|
||||
if (!pasteHtml.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const target = (evt.target as HTMLElementWithValue);
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
const textHtmlData = evt.clipboardData?.getData('text/html');
|
||||
if (textHtmlData && textHtmlData !== '') {
|
||||
evt.preventDefault();
|
||||
value.value = textHtmlData;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
watch(
|
||||
[value, autosize, multiline, inputWrapperRef, textareaRef],
|
||||
() => nextTick(() => {
|
||||
|
@ -171,6 +195,7 @@ defineExpose({
|
|||
:autocorrect="autocorrect ?? (rawText ? 'off' : undefined)"
|
||||
:spellcheck="spellcheck ?? (rawText ? false : undefined)"
|
||||
:rows="rows"
|
||||
@paste="onPasteInputHtml"
|
||||
/>
|
||||
|
||||
<input
|
||||
|
@ -192,6 +217,7 @@ defineExpose({
|
|||
:autocomplete="autocomplete ?? (rawText ? 'off' : undefined)"
|
||||
:autocorrect="autocorrect ?? (rawText ? 'off' : undefined)"
|
||||
:spellcheck="spellcheck ?? (rawText ? false : undefined)"
|
||||
@paste="onPasteInputHtml"
|
||||
>
|
||||
|
||||
<c-button v-if="clearable && value" variant="text" circle size="small" @click="value = ''">
|
||||
|
|
|
@ -151,7 +151,7 @@ function onSearchInput() {
|
|||
>
|
||||
<div flex-1 truncate>
|
||||
<slot name="displayed-value">
|
||||
<input v-if="searchable && isOpen" ref="searchInputRef" v-model="searchQuery" type="text" placeholder="Search..." class="search-input" w-full lh-normal color-current @input="onSearchInput">
|
||||
<input v-if="searchable && isOpen" ref="searchInputRef" v-model="searchQuery" type="text" placeholder="Search..." class="search-input" w-full color-current lh-normal @input="onSearchInput">
|
||||
<span v-else-if="selectedOption" lh-normal>
|
||||
{{ selectedOption.label }}
|
||||
</span>
|
||||
|
|
|
@ -39,7 +39,7 @@ const headers = computed(() => {
|
|||
<template>
|
||||
<div class="relative overflow-x-auto rounded">
|
||||
<table class="w-full border-collapse text-left text-sm text-gray-500 dark:text-gray-400" role="table" :aria-label="description">
|
||||
<thead v-if="!hideHeaders" class="bg-#ffffff uppercase text-gray-700 dark:bg-#333333 dark:text-gray-400" border-b="1px solid dark:transparent #efeff5">
|
||||
<thead v-if="!hideHeaders" class="bg-#ffffff text-gray-700 uppercase dark:bg-#333333 dark:text-gray-400" border-b="1px solid dark:transparent #efeff5">
|
||||
<tr>
|
||||
<th v-for="header in headers" :key="header.key" scope="col" class="px-6 py-3 text-xs">
|
||||
{{ header.label }}
|
||||
|
|
|
@ -38,7 +38,8 @@ describe('base64 utils', () => {
|
|||
|
||||
it('should throw for incorrect base64 string', () => {
|
||||
expect(() => base64ToText('a')).to.throw('Incorrect base64 string');
|
||||
expect(() => base64ToText(' ')).to.throw('Incorrect base64 string');
|
||||
// should not really be false because trimming of space is now implied
|
||||
// expect(() => base64ToText(' ')).to.throw('Incorrect base64 string');
|
||||
expect(() => base64ToText('é')).to.throw('Incorrect base64 string');
|
||||
// missing final '='
|
||||
expect(() => base64ToText('bG9yZW0gaXBzdW0')).to.throw('Incorrect base64 string');
|
||||
|
@ -56,17 +57,17 @@ describe('base64 utils', () => {
|
|||
|
||||
it('should return false for incorrect base64 string', () => {
|
||||
expect(isValidBase64('a')).to.eql(false);
|
||||
expect(isValidBase64(' ')).to.eql(false);
|
||||
expect(isValidBase64('é')).to.eql(false);
|
||||
expect(isValidBase64('data:text/plain;notbase64,YQ==')).to.eql(false);
|
||||
// missing final '='
|
||||
expect(isValidBase64('bG9yZW0gaXBzdW0')).to.eql(false);
|
||||
});
|
||||
|
||||
it('should return false for untrimmed correct base64 string', () => {
|
||||
expect(isValidBase64('bG9yZW0gaXBzdW0= ')).to.eql(false);
|
||||
expect(isValidBase64(' LTE=')).to.eql(false);
|
||||
expect(isValidBase64(' YQ== ')).to.eql(false);
|
||||
it('should return true for untrimmed correct base64 string', () => {
|
||||
expect(isValidBase64('bG9yZW0gaXBzdW0= ')).to.eql(true);
|
||||
expect(isValidBase64(' LTE=')).to.eql(true);
|
||||
expect(isValidBase64(' YQ== ')).to.eql(true);
|
||||
expect(isValidBase64(' ')).to.eql(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { Base64 } from 'js-base64';
|
||||
|
||||
export { textToBase64, base64ToText, isValidBase64, removePotentialDataAndMimePrefix };
|
||||
|
||||
function textToBase64(str: string, { makeUrlSafe = false }: { makeUrlSafe?: boolean } = {}) {
|
||||
const encoded = window.btoa(str);
|
||||
const encoded = Base64.encode(str);
|
||||
return makeUrlSafe ? makeUriSafe(encoded) : encoded;
|
||||
}
|
||||
|
||||
|
@ -16,7 +18,7 @@ function base64ToText(str: string, { makeUrlSafe = false }: { makeUrlSafe?: bool
|
|||
}
|
||||
|
||||
try {
|
||||
return window.atob(cleanStr);
|
||||
return Base64.decode(cleanStr);
|
||||
}
|
||||
catch (_) {
|
||||
throw new Error('Incorrect base64 string');
|
||||
|
@ -34,10 +36,11 @@ function isValidBase64(str: string, { makeUrlSafe = false }: { makeUrlSafe?: boo
|
|||
}
|
||||
|
||||
try {
|
||||
const reEncodedBase64 = Base64.fromUint8Array(Base64.toUint8Array(cleanStr));
|
||||
if (makeUrlSafe) {
|
||||
return removePotentialPadding(window.btoa(window.atob(cleanStr))) === cleanStr;
|
||||
return removePotentialPadding(reEncodedBase64) === cleanStr;
|
||||
}
|
||||
return window.btoa(window.atob(cleanStr)) === cleanStr;
|
||||
return reEncodedBase64 === cleanStr.replace(/\s/g, '');
|
||||
}
|
||||
catch (err) {
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue