Compare commits

...

259 commits

Author SHA1 Message Date
Corentin Thomasset
07eea0f484
refactor(sponsors): removed sponsor banners (#1553)
Some checks failed
ci / ci (push) Has been cancelled
E2E tests / test (1/3) (push) Has been cancelled
E2E tests / test (2/3) (push) Has been cancelled
E2E tests / test (3/3) (push) Has been cancelled
2025-04-06 23:41:40 +02:00
Corentin Thomasset
a4ab7db9e4
fix(c-input-text): set minimum height for input field (#1552) 2025-04-06 23:16:09 +02:00
Corentin THOMASSET
08d977b8cd
feat(sponsor): added sponsor banner (#1422) 2024-12-14 12:15:18 +01:00
Corentin THOMASSET
63fbd3b45c
fix(locales): update license from MIT to GPL-3.0 in language files (#1419) 2024-12-11 19:33:24 +00:00
Corentin THOMASSET
b47d132839
refactor(sponsor): removed sponsor banner and related configurations (#1405) 2024-11-29 23:06:39 +00:00
gitmotion
0b1b98f93e
feat(favorites) drag-and-drop favorites section (#1360) 2024-10-25 22:42:12 +02:00
gitmotion
ea8c4ed077
fix(icons,branding): swap twitter to X (#1369) 2024-10-25 20:17:08 +02:00
gitmotion
ae1363937b
fix(FavoriteButton): pass tool path to favorite button (#1368) 2024-10-25 16:27:14 +00:00
gitmotion
c7b80fbc78
fix(readme): refresh stale contributors graph (#1364) 2024-10-25 07:44:17 +00:00
gitmotion
131497322d
feat(html-wysiwyg-editor) h3 fix (#1363) 2024-10-24 22:44:36 +00:00
Luu Van Loi
f836666417
fix(yaml-to-json): allow merge key to be parsed (#1359)
* fix(yaml-to-json): allow merge key to be parsed

* correct e2e tests

---------

Co-authored-by: lvluu <loi.van.luu@mgm-tp.com>
2024-10-24 10:20:51 +00:00
Knu753n
aa8cba96de
feat(i18n): added Norwegian language (#1337) 2024-10-24 10:19:13 +00:00
Corentin Thomasset
5732483fc2
chore(version): release 2024.10.22-7ca5933 2024-10-22 10:25:36 +02:00
Corentin Thomasset
bd184d934d
docs(changelog): update changelog for 2024.10.22-7ca5933 2024-10-22 10:25:36 +02:00
sharevb
7ca5933178
fix(favorites): store favorites regardless of languages (#1202)
Fix #1110
2024-10-22 10:21:29 +02:00
Corentin THOMASSET
f962c416a3
chore(sponsors): fern sponsor banners (#1314)
* chore(sponsors): readme banner

* chore(sponsors): app sponsor
2024-10-03 00:01:09 +02:00
Corentin THOMASSET
1c35ac3704
docs(author): updated author links (#1316) 2024-09-27 12:49:11 +00:00
Corentin Thomasset
72517002f3
refactor(regex-tester): better description 2024-09-27 10:40:56 +02:00
sharevb
f5c4ab19bc
feat(new tool): Regex Tester (and Cheatsheet) (#1030)
* feat(new tool): Regex Tester

Fix https://github.com/CorentinTh/it-tools/issues/1007, https://github.com/CorentinTh/it-tools/issues/991, https://github.com/CorentinTh/it-tools/issues/936, https://github.com/CorentinTh/it-tools/issues/761, https://github.com/CorentinTh/it-tools/issues/649
https://github.com/CorentinTh/it-tools/issues/644, https://github.com/CorentinTh/it-tools/issues/554
https://github.com/CorentinTh/it-tools/issues/308

* fix: refactor to service + add regex diagram + ui enhancements

* fix: update queryParams

* fix: deps

* fix: svg style bug in @regexper/render

@regexper/render use a stylesheet in svg that cause bugs in whole site. So add regexper in a shadow root

* feat(new tool): added Regex Cheatsheet

* Update src/tools/regex-memo/index.ts

* Update src/tools/regex-tester/index.ts

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2024-09-20 18:39:40 +00:00
Corentin THOMASSET
67094980c9
chore(readme): updated logos (#1294) 2024-09-13 18:56:32 +00:00
sharevb
87984e2081
feat(new tool): Markdown to HTML (#916)
* feat(new tool): Markdown to HTML

Fix partially #538

* feat: add print button

* Update src/tools/markdown-to-html/index.ts

* Update src/tools/markdown-to-html/markdown-to-html.vue

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2024-08-25 20:57:07 +00:00
Corentin THOMASSET
318fb6efb9
feat(new-tool): add email normalizer (#1243) 2024-08-15 13:29:58 +00:00
sharevb
f1a5489e21
feat(new tools): JSON to XML and XML to JSON (#1231)
* feat(new tool): JSON <> XML

Fix https://github.com/CorentinTh/it-tools/issues/314

* Update src/tools/xml-to-json/index.ts

* Update src/tools/json-to-xml/index.ts

* Update src/tools/json-to-xml/index.ts

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2024-08-09 20:11:39 +00:00
Diego Fabricio
e1b4f9aafe
feat(lorem-ipsum): add button to refresh text lorem-ipsum (#1213)
Co-authored-by: Diego Guzmán <diego.guzman@caces.gob.ec>
2024-08-07 09:22:08 +02:00
sharevb
76a19d218d
fix(emoji-picker): debounced search input (#1181)
* fix(Emoji picker): fix lags

Fix #1176 using debounced ref

* chore: fix strange corepack message

Fix corepack claiming strange thing : UsageError: This project is configured to use yarn because /home/runner/work/it-tools/it-tools/package.json has a "packageManager" field
2024-07-11 17:06:17 +02:00
code2933
b430baef40
fix(format-transformer): set overflow for output area width (#787) 2024-05-27 18:16:24 +02:00
sharevb
dd4b7e687b
fix(jwt-parser): prevent UI overflow on small screen (#1095)
Fix #1045
2024-05-27 11:59:05 +02:00
sharevb
30144aa3f5
feat(base64): Base64 enhancements (#905)
* fix(base64): use js-base64 to handle non ascii text

Use js-base64 to handle non ascii text and ignore whitespaces
Fix #879 and #409

* fix(base64): use js-base64 to handle non ascii text

Use js-base64 to handle non ascii text and ignore whitespaces
Fix #879 and #409

* feat(base64 file converter): add a filename and extension fields

Add filename and extension (auto filled if data url) to allow downloading with right extension and filename
Fix #788

* feat(base64 file converter): add a preview image

Fix #594. Taken from #595 (thanks @SAF2k)
2024-05-20 22:13:55 +02:00
Corentin Thomasset
e876d03608
chore(version): release 2024.05.13-a0bc346 2024-05-13 10:54:18 +02:00
Corentin Thomasset
81cf6b5483
docs(changelog): update changelog for 2024.05.13-a0bc346 2024-05-13 10:54:18 +02:00
Corentin THOMASSET
a0bc3468b2
chore(issues): prevent empty issues (#1078) 2024-05-13 08:44:04 +00:00
Corentin THOMASSET
5a7b0f9636
chore(issues): removed old issue templates (#1077) 2024-05-13 08:11:47 +00:00
Corentin Thomasset
b59942ad9f
chore(node): upgraded node version in CI workflows 2024-05-10 13:26:36 +02:00
Corentin Thomasset
38d568798c
chore(version): release 2024.05.10-33e5294 2024-05-10 12:08:16 +02:00
Corentin Thomasset
9dfd347edf
docs(changelog): update changelog for 2024.05.10-33e5294 2024-05-10 12:08:15 +02:00
Corentin Thomasset
33e5294a94
refactor(lint): removed extra semi 2024-05-10 12:07:50 +02:00
Corentin Thomasset
2852c30e1f
chore(issues): improved issues template 2024-05-10 12:05:35 +02:00
Corentin Thomasset
124284278f refactor(auto-imports): regen auto imports 2024-05-10 11:41:48 +02:00
Corentin THOMASSET
a7992340f7
chore(issues): improved bug issue template (#1046) 2024-05-10 09:28:45 +00:00
steffenrapp
2c2fb216e3
feat(i18n): added German translation (#1038)
* feat(i18n): German translation

* more

* more

* more

* rest
2024-05-10 10:57:42 +02:00
Christopher Conley
221ddfa75c
fix(language): English language cleanup (#1036)
Fix possessive vs. contraction form of "it," clarification, and some general cleanup
2024-05-05 18:49:31 +02:00
Pavel Gordon
cb5b462e11
fix(url-encoder, validation): typo in validation of url-encoder.vue #1024 2024-04-29 11:58:08 +02:00
sharevb
9eac9cb2a9
fix(integer base converter): support bigint (#872) 2024-04-22 08:45:51 +02:00
sharevb
23f82d956a
fix(bcrypt tool): allow salt rounds up to 100 (#987)
* fix(bcrypt tool): allow salt rounds up to 100

Previously max salt rounds was 10

* chore(github workflows): ci and e2e tests: try updating to node 20
2024-04-15 09:43:12 +02:00
sharevb
d3b32cc14e
feat(new tool): Outlook Safelink Decoder (#911)
* feat(new tool): Outlook Safelink Decoder

Fix #897

* Use native URL parsing

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>

* Update src/tools/safelink-decoder/index.ts

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2024-03-11 10:19:32 +00:00
sharevb
fe349ad69b
feat(new tool): ascii art generator (#886)
* feat(new tool): ascii art generator

Fix #829 ; Text ASCII Art Generator (using figlet)

* fix: make fonts list searchable

* refactor(ascii-generator): updated tool definition

* refactor(ascii-generator): equilibrate ui

---------

Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2024-03-03 10:37:09 +00:00
Corentin THOMASSET
a07806cd15
refactor(home): lightened tool cards (#882) 2024-02-12 13:31:21 +00:00
Corentin THOMASSET
10e56b35bb
refactor(home): removed n-grid to prevent layout shift (#881) 2024-02-12 09:30:41 +00:00
Corentin THOMASSET
dc0461595f
feat(i18n): get locales on build (#880) 2024-02-11 00:33:52 +01:00
David Nguyen
079aa2164c
feat(i18n): added vi tools translations (#876)
* Update Vietnamese translations in vi.yml file

* Add Vietnamese translations for various tools
2024-02-05 10:09:07 +00:00
QingFeng
9c6b12225e
feat(i18n): added zh tools translations (#874) 2024-02-05 11:06:36 +01:00
Corentin THOMASSET
7f5fa00147
feat(i18n): added missing locale files in tools (#863) 2024-02-01 17:05:05 +00:00
hieudt-2054
1334bff30a
feat(i18n): added vietnamese language (#859) 2024-02-01 14:47:09 +01:00
Corentin THOMASSET
95698cb938
refactor(i18n): added locales per tool (#861) 2024-02-01 14:05:54 +01:00
Raúl Mora
85b50bb8f0
feat(i18n): added spanish language (#854)
* spanish

translation

* Create es.yaml
2024-01-31 10:10:21 +00:00
Marcelo Gonçalves
c65ffb6e75
feat(i18n): added portuguese language (#813) 2024-01-31 11:03:54 +01:00
Nikitin Roman
693f362e15
feat(i18n): added ukrainian language (#827)
Added Ukrainian language
2024-01-31 11:01:56 +01:00
Isaiah
fc06f01b34
feat(new-tool): yaml formater (#779)
* validating if yaml is correct and collecting format options

* Formatting yaml, sorting keys and changing indent size.

* Removed unused format options

* Fixed lint errors

* Installed types for js-yaml

* Removed legacy routing and added tool creation date

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>

* Using existing yaml package instead of js-yaml

* Update src/tools/yaml-viewer/index.ts

---------

Co-authored-by: Isaiah <66272034+isaiah-j@users.noreply.github.com>
Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2024-01-31 09:58:53 +00:00
hieudt-2054
c46207f1bb
feat(new-tool): added unicode conversion utilities (#858)
* feat: add Text to Unicode tool

* Update src/tools/text-to-unicode/index.ts

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2024-01-31 09:55:18 +00:00
Corentin Thomasset
670f735501
chore(version): release 2023.12.21-5ed3693 2023-12-21 08:45:28 +01:00
Corentin Thomasset
a29ad66809
docs(changelog): update changelog for 2023.12.21-5ed3693 2023-12-21 08:45:27 +01:00
Markus Blaschke
5ed36935c7
fix(jwt-parser): jwt claim array support (#799)
fixes support of claim array values (was shown "[Object]" before)

Signed-off-by: Markus Blaschke <mblaschke82@gmail.com>
2023-12-12 14:04:19 +01:00
Isaiah
80e46c9292
fix(camera-recorder): stop camera on navigation (#782)
* Stopping camera when user switches to another page

* Missing ;
2023-11-29 13:58:07 +01:00
Richard "EpicKitty" Bowey
7a70dbbe0c
fix(doc): updated create new tool command in readme (#762) 2023-11-22 20:27:46 +01:00
lzb16
2e56641398
feat(i18n): improve chinese i18n (#757) 2023-11-16 18:27:51 +01:00
lzb16
a1037cf8f1
feat(i18n): add tooltip and favoriteButton i18n (#756) 2023-11-16 08:20:42 +00:00
renovate[bot]
0fe9a20329
chore(deps): switched from oui to oui-data for mac address lookup (#693)
* fix(deps): update dependency oui to v13

* chore(deps): switched from oui to oui-data for mac address lookup

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-11-14 23:44:23 +00:00
renovate[bot]
2e396d8776
chore(deps): update unocss monorepo to ^0.57.0 (#638)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-15 00:19:09 +01:00
Corentin THOMASSET
bd3edcb528
refactor(about, i18n): improved i18n dx with markdown (#753) 2023-11-14 23:15:41 +00:00
Corentin THOMASSET
de1ee69ef9
refactor(token, i18n): complete fr translation (#752) 2023-11-14 23:14:05 +00:00
Gary
8f99eb6017
feat(i18n): add Chinese translation base (#718)
* Create zh_CN.yml

* rename

* Update zh.yml

* Update zh.yml

* Update zh.yml

* Update zh.yml

* Update zh.yml
2023-11-15 00:09:36 +01:00
Corentin THOMASSET
38586caab7
refactor(uuid generator): uuid version picker (#751) 2023-11-13 21:38:01 +00:00
Corentin THOMASSET
043e4f0a08
fix(base64-file-converter): fix downloading of index.html content without data preambula (#750)
* fix(base64-file-converter): fix downloading of index.html content without data preambula

* feat(base64-file-converter): infer mime type from base64 signature

---------

Co-authored-by: akharlov <harl_aa@skbkontur.ru>
2023-11-13 10:44:23 +00:00
Corentin THOMASSET
ca43a25569
refactor(case converter): no split on lowercase, uppercase and mocking case (#748) 2023-11-13 00:00:55 +00:00
Corentin THOMASSET
7fe47b3be4
refactor(ui): replaced legacy n-upload with c-file-upload (#747) 2023-11-13 00:56:51 +01:00
Corentin THOMASSET
16ffe6b5c9
refactor(token): added password in token generator keywords (#746) 2023-11-12 22:54:13 +00:00
Corentin THOMASSET
478192065e
feat(new tool): pdf signature checker (#745) 2023-11-12 22:22:41 +00:00
Corentin THOMASSET
205e360400
fix(docker): rollback armv7 in docker releases (#741) 2023-11-09 13:33:19 +00:00
Steltek
821cbea2bf
fix(eta): corrected example (#737) 2023-11-08 19:56:58 +01:00
Oceansdeep7
093ff311fd
refactor(bcrypt): fix input label align (#721)
Co-authored-by: robin.li <robin.li@webeye.com>
2023-11-07 09:10:52 +01:00
Corentin THOMASSET
e07e2ae5bc
feat(new tool): numeronym generator (#729) 2023-11-05 21:59:31 +00:00
Corentin THOMASSET
fe1de8c5c9
chore(docker): added armv7 plateform for docker releases (#722) 2023-11-03 08:06:11 +00:00
Corentin Thomasset
b2614990e3
chore(version): release 2023.11.02-7d94e11 2023-11-02 09:11:26 +01:00
Corentin Thomasset
79646375f3
docs(changelog): update changelog for 2023.11.02-7d94e11 2023-11-02 09:11:26 +01:00
Andrii Bratanin
7d94e11cee
fix(dockerfile): revert replacement of nginx image with non-privileged one (#716)
Fixes https://github.com/CorentinTh/it-tools/issues/714
2023-11-02 09:10:13 +01:00
swishkin
e87f4b1837
refactor(math-evaluator): improved description
Improved description.
2023-11-01 23:07:51 +01:00
Corentin THOMASSET
e86fd96ae3
feat(i18n): language selector (#710) 2023-11-01 15:38:19 +01:00
Corentin THOMASSET
58de8970f5
refactor(math-evaluator): improved search and UX (#713)
* refactor(math-evaluator): added keywords for search

* refactor(math-evaluator): improved input
2023-11-01 14:23:46 +00:00
Corentin THOMASSET
02b0d0d1a1
fix(encryption): alert on decryption error (#711)
* update(c-alert): Add variant 'error'

* fix(encryption): Alert decryption error (#652)

* feat(c-alert): added title

* refactor(composable): mutualized computedCatch

---------

Co-authored-by: code2933 <code2933@outlook.com>
2023-11-01 10:11:51 +00:00
Corentin Thomasset
4d5a67d96d
chore(version): release 2023.11.01-e164afb 2023-11-01 10:02:22 +01:00
Corentin Thomasset
8174db9cf3
docs(changelog): update changelog for 2023.11.01-e164afb 2023-11-01 10:02:22 +01:00
Corentin THOMASSET
e164afb664
chore(deps): clean unused dependencies (#709)
* chore(deps): removed unused dep randombytes

* chore(deps): removed unused dep c8

* chore(deps): updated dep naive-ui
2023-10-31 21:00:23 +00:00
Corentin THOMASSET
d0136962b9
feat(command-palette): clear prompt on palette close (#708) 2023-10-31 19:27:21 +00:00
Corentin THOMASSET
015c673e09
refactor(ui): better ui demo preview menu (#664) 2023-10-31 17:49:36 +00:00
Corentin Thomasset
99b1eb944d
feat(command-palette): added about page in command palette 2023-10-31 18:26:16 +01:00
Istvan Olah
cc3425dc77
feat(new tool): random MAC address generator (#657)
* #521 Random MAC address generator

* refactor(mac-address-generator): improved ux

* refactor(mac-address-generator): improved ux

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2023-10-31 11:34:24 +00:00
Corentin THOMASSET
681f7bf644
feat(case-converter): added mocking case (#705) 2023-10-31 09:52:01 +00:00
Corentin THOMASSET
f5eb7a8c49
feat(date-converter): added excel date time format (#704) 2023-10-31 08:59:35 +00:00
Corentin THOMASSET
abb8335041
refactor(color-converter): improved color-converter UX (#701) 2023-10-31 07:32:44 +00:00
Corentin THOMASSET
020e9cbe41
refactor(docker): improved docker config (#700) 2023-10-30 17:11:16 +00:00
莫颓
02e68d3f56
feat(i18n): token generator (#688) 2023-10-23 09:17:08 +02:00
莫颓
00562ed5e8
feat(i18n): home page (#687)
(cherry picked from commit 9d39826078ceb929a5ca3b577f9f39449303c289)
2023-10-23 09:14:34 +02:00
renovate[bot]
4365226d01
chore(deps): update docker/setup-qemu-action action to v3 (#627)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-22 10:30:26 +02:00
renovate[bot]
57ecda1623
chore(deps): update docker/setup-buildx-action action to v3 (#626)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-22 10:30:16 +02:00
renovate[bot]
d8d7a3b9ab
chore(deps): update docker/login-action action to v3 (#625)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-22 10:30:04 +02:00
renovate[bot]
d36b18f193
chore(deps): update docker/build-push-action action to v5 (#624)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-22 10:29:05 +02:00
renovate[bot]
eea9f91276
chore(deps): update dependency node to v18.18.2 (#674)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-22 10:26:05 +02:00
莫颓
ebb4ec4165
feat(i18n): support for i18n in .ts files (#683)
(cherry picked from commit 732313bfc32a514ef064ca0f90304ff05e2e7ef3)
2023-10-22 10:23:00 +02:00
莫颓
84a4a646f6
feat(i18n): tool card (#682)
(cherry picked from commit 1d0a3904f72ab24364beda034d17cf6de9b5e959)
2023-10-22 08:21:10 +00:00
莫颓
a2b53c2e38
feat(i18n): about page (#680)
(cherry picked from commit 605b84c16e0eec1a16e6133203e7810a68447607)

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2023-10-22 08:15:39 +00:00
莫颓
35563b8457
feat(i18n): 404 page (#679) 2023-10-22 10:07:43 +02:00
Sellar
720201aa7b
fix(deps): fix issue on slugify (#593) (#673) 2023-10-18 09:23:34 +02:00
Corentin THOMASSET
b2ad4f7a27
feat(new tool): text to ascii converter (#669) 2023-10-15 22:57:47 +00:00
Corentin Thomasset
b408df82c1
refactor(c-table): added description on c-table for accessibility 2023-10-15 23:41:55 +02:00
Corentin THOMASSET
88b881880c
refactor(ci): reduced timeout in e2e (#666) 2023-10-14 22:48:18 +00:00
Corentin THOMASSET
ee4c853b9f
refactor(ui): new c-table ui component (#665) 2023-10-14 22:45:14 +00:00
Corentin THOMASSET
cbf58fdd28
refactor(ui): removed n-page-header component in user-agent parser (#663) 2023-10-14 23:01:32 +02:00
Corentin THOMASSET
a757a5155a
refactor(ui): removed n-p components in about page (#662) 2023-10-14 18:37:26 +02:00
Corentin THOMASSET
025f556023
refactor(ui): switched naive tooltip components to custom ones (#661) 2023-10-14 16:24:54 +00:00
renovate[bot]
2d2dffb14a
chore(deps): update dependency node to v18.18.0 (#636)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-04 11:46:33 +02:00
Corentin THOMASSET
5c4d775e2d
feat(new tool): ULID generator (#623) 2023-09-11 22:57:42 +00:00
Corentin THOMASSET
557b30426f
doc(readme): added contributors list (#622) 2023-09-11 20:59:07 +00:00
renovate[bot]
4972159aa7
chore(deps): update actions/checkout action to v4 (#613)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-11 22:42:33 +02:00
renovate[bot]
e371ef702e
fix(deps): update dependency monaco-editor to ^0.43.0 (#620)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-11 22:40:42 +02:00
Simon Bordeyne
0eedce69a6
feat(new tool): add wifi qr code generator (#599)
* (feat: new tool): add wifi qr code generator

* Update src/tools/wifi-qr-code-generator/wifi-qr-code-generator.vue

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>

* Update src/tools/wifi-qr-code-generator/index.ts

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>

* remove naive UI grid

* Update src/tools/wifi-qr-code-generator/index.ts

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2023-09-06 07:46:40 +00:00
Mark Townsend
8a30b6bdb3
refactor(spelling): minor corrections to phrasing/spelling (#596)
* Minor corrections to phrasing/spelling.

* Corrected 'millennia'.

* Corrected tests.

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2023-09-04 14:51:04 +02:00
Corentin THOMASSET
233d5565f6
refactor(i18n): merge tools scoped locales with global ones (#612) 2023-09-03 20:07:45 +00:00
Corentin THOMASSET
7ab9204e96
refactor(c-key-value-list): got rid of table for layout (#611) 2023-09-03 16:12:22 +00:00
renovate[bot]
c7d4562d3b
fix(deps): update dependency sql-formatter to v13 (#606)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-03 16:51:12 +02:00
Corentin THOMASSET
18dd1400bd
refactor(CI): run e2e against built app and no longer vercel (#610) 2023-09-03 14:28:19 +00:00
renovate[bot]
f035f485c0
chore(deps): update dependency unplugin-icons to ^0.17.0 (#609)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-03 16:16:01 +02:00
Anton Mosich
e18bae1fca
refactor(bcrypt): fix typo (#604) 2023-09-01 16:30:51 +02:00
renovate[bot]
d1dff428d8
chore(deps): update dependency @intlify/unplugin-vue-i18n to ^0.13.0 (#597)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-01 10:14:50 +02:00
Corentin THOMASSET
3a63837d3d
feat(new tool): iban validation and parser (#591) 2023-08-27 18:12:31 +00:00
Corentin THOMASSET
81bfe57cb8
feat(new tool): text diff and comparator (#588)
* feat(new tool): text diff and comparator

* chore(ci): increased memory in CI
2023-08-26 16:43:47 +02:00
renovate[bot]
a9cd91ca9c
chore(deps): update dependency @antfu/eslint-config to ^0.41.0 (#585)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-26 16:28:31 +02:00
Corentin THOMASSET
06c35472d3
doc(hosting): added cloudron in the other hosting solutions section (#589) 2023-08-26 14:18:12 +00:00
renovate[bot]
f3e14fc18f
chore(deps): update dependency typescript to ~5.2.0 (#587)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-26 16:17:19 +02:00
Corentin Thomasset
2274766a8f
chore(version): release 2023.08.21-6f93cba 2023-08-22 01:02:24 +02:00
Corentin Thomasset
a346175d24
docs(changelog): update changelog for 2023.08.21-6f93cba 2023-08-22 01:02:24 +02:00
Corentin THOMASSET
6f93cba3da
feat(copy): support legacy copy to clipboard for older browser (#581) 2023-08-21 23:00:20 +00:00
renovate[bot]
76b2761d62
chore(deps): switched to fucking typescript v5 (#501)
* chore(deps): update dependency typescript to v5

* chore(deps): switched to fucking typescript v5

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-08-21 19:57:59 +00:00
renovate[bot]
6ff9a01cc8
chore(deps): update dependency @antfu/eslint-config to ^0.40.0 (#552)
* chore(deps): update dependency @antfu/eslint-config to ^0.40.0

* chore(deps): updated eslint

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-08-21 18:27:08 +00:00
renovate[bot]
a2b9b157e5
chore(deps): update dependency prettier to v3 (#564)
* chore(deps): update dependency prettier to v3

* chore(deps): updated prettier

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-08-21 18:02:54 +00:00
renovate[bot]
144f86e2dc
chore(deps): removed @typescript-eslint/parser (#563)
* chore(deps): update dependency @typescript-eslint/parser to v6

* chore(deps): removed @typescript-eslint/parser

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-08-21 17:18:04 +00:00
renovate[bot]
0f1f6590c5
chore(deps): removed ts-pattern (#565)
* fix(deps): update dependency ts-pattern to v5

* chore(deps): removed ts-pattern

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-08-21 17:06:09 +00:00
renovate[bot]
2bcb77a9f9
fix(deps): update dependency sql-formatter to v12 (#520)
* fix(deps): update dependency sql-formatter to v12

* fix(sql-prettify): corrected types

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-08-21 18:34:15 +02:00
Corentin THOMASSET
c58d6e3423
feat(new tool): string obfuscator (#575) 2023-08-16 21:43:45 +00:00
Corentin Thomasset
f235dcd6c1
chore(version): release 2023.08.16-9bd4ad4 2023-08-16 14:19:08 +02:00
Corentin Thomasset
ba2c589f0f
docs(changelog): update changelog for 2023.08.16-9bd4ad4 2023-08-16 14:19:08 +02:00
renovate[bot]
9bd4ad4dfd
chore(deps): update dependency vitest to ^0.34.0 (#562)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-10 16:15:18 +02:00
renovate[bot]
5e12991bcd
fix(deps): update dependency uuid to v9 (#566)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-10 15:12:27 +02:00
renovate[bot]
65a9474078
chore(deps): update dependency node to v18.17.1 (#560)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-10 01:10:53 +02:00
renovate[bot]
85cc7a8447
chore(deps): update dependency unocss to ^0.55.0 (#561)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-09 22:31:31 +00:00
renovate[bot]
4268e255de
chore(deps): update dependency @unocss/eslint-config to ^0.55.0 (#553)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-09 22:22:15 +00:00
renovate[bot]
d1c888019b
chore(deps): update dependency @intlify/unplugin-vue-i18n to ^0.12.0 (#526)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-10 00:11:59 +02:00
renovate[bot]
7924456cec
fix(deps): update dependency mathjs to v11 (#519)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-10 00:11:30 +02:00
renovate[bot]
99bc84c37e
chore(deps): update docker/login-action action to v2 (#512)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-10 00:10:31 +02:00
renovate[bot]
ea0f27cf4c
fix(deps): update dependency @vueuse/router to v10 (#516)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-10 00:10:19 +02:00
renovate[bot]
cd5a503fc0
chore(deps): update dependency jsdom to v22 (#499)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-10 00:09:39 +02:00
Corentin THOMASSET
86e964a274
fix(copy): prevent shorthand copy if source is present in useCopy (#559)
* fix(copy): prevent shorthand copy if source is present in useCopy

* refactor(copy): normalized copy usage
2023-08-09 22:07:44 +00:00
Marvin
7b6232a151
feat(Case Converter): Add lowercase and uppercase (#534)
* feat(case converter): add uppercase and lowercase

* (case converter) correctly use stripRegexp

* style: lint fix

* feat(ui): added c-select in the ui lib (#550)

* feat(ui): added c-select in the ui lib

* refactor(ui): switched n-select to c-select

* feat(new tool): emoji picker (#551)

* chore(deps): update dependency @vitejs/plugin-vue to v4 (#496)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @vitejs/plugin-vue-jsx to v3 (#497)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* refactor(case converter): using nocase to convert to upper and lower case

* refactor(case converter): config based case changes

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-09 23:45:21 +02:00
Corentin THOMASSET
56d74d07a8
fix(c-lib): hide component library shortcut link in non-dev (#557) 2023-08-09 20:58:15 +00:00
Corentin THOMASSET
e5d0ba7073
fix(emoji picker): fix copy button (#556) 2023-08-09 20:54:49 +00:00
renovate[bot]
1a602365be
chore(deps): update dependency @vitejs/plugin-vue-jsx to v3 (#497)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-08 22:25:59 +02:00
renovate[bot]
a2494219a8
chore(deps): update dependency @vitejs/plugin-vue to v4 (#496)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-08 22:25:59 +02:00
Corentin THOMASSET
93f7cf0e98
feat(new tool): emoji picker (#551) 2023-08-08 22:25:59 +02:00
Corentin THOMASSET
dfa1ba8554
feat(ui): added c-select in the ui lib (#550)
* feat(ui): added c-select in the ui lib

* refactor(ui): switched n-select to c-select
2023-08-07 15:30:00 +00:00
renovate[bot]
6498c9b0fa
chore(deps): update dependency vite-plugin-pwa to ^0.16.0 (#488)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-05 16:29:58 +02:00
renovate[bot]
f40d7ecddf
chore(deps): update dependency vite to v4 (#503)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-29 20:35:23 +02:00
Corentin THOMASSET
2e28c5073e
chore(ci): e2e against vercel deployement (#518) 2023-06-29 20:27:35 +02:00
renovate[bot]
d12dd40841
fix(deps): update dependency @vueuse/head to v1 (#515)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-29 20:20:28 +02:00
Corentin THOMASSET
cf382b5a10
chore(e2e): execute e2e against built app (#511) 2023-06-29 18:48:51 +02:00
renovate[bot]
01525838e0
chore(deps): update github/codeql-action action to v2 (#513)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-29 08:57:10 +02:00
renovate[bot]
38cb61da4d
chore(deps): update node.js to v18 (#514)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-28 08:35:45 +02:00
Corentin THOMASSET
354aed6e6f
chore(deps): switched from vite-plugin-md to vite-plugin-vue-markdown (#510) 2023-06-27 18:39:20 +00:00
renovate[bot]
6b8682fd23
chore(deps): update dependency workbox-window to v7 (#509)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-27 20:29:41 +02:00
renovate[bot]
9e8349dbc4
chore(deps): update dependency vite-svg-loader to v4 (#508)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-27 20:13:06 +02:00
renovate[bot]
f44050742d
chore(deps): update dependency typescript to ~4.9.0 (#481)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-27 20:08:12 +02:00
renovate[bot]
b0d9a3e6c7
chore(deps): update dependency vue-tsc to ^0.40.0 (#490)
* chore(deps): update dependency vue-tsc to ^0.40.0

* chore(deps): upgraded vue-tsc dependency

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-06-27 17:59:05 +00:00
Corentin THOMASSET
30f88fc6a8
refactor(navbar): consistent spacing in navbar buttons (#507) 2023-06-27 16:47:32 +00:00
Corentin THOMASSET
72c98a3c5e
refactor(ui): remove n-text (#506) 2023-06-25 13:49:43 +00:00
Corentin THOMASSET
05ea545475
refactor(ui): replaced some n-input to c-input (#505) 2023-06-25 13:00:50 +00:00
Corentin THOMASSET
5c3bebfe62
chore(deps): updated unplugin-auto-import (#504) 2023-06-25 09:45:56 +00:00
renovate[bot]
8df7cd0f19
chore(deps): removed start-server-and-test dependency
* chore(deps): update dependency start-server-and-test to v2

* chore(deps): removed start-server-and-test dependency

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-06-25 08:34:36 +00:00
Corentin THOMASSET
a9c7b89193
feat(new-tool): password strength analyzer (#502) 2023-06-25 08:26:29 +00:00
renovate[bot]
6bda2caa04
chore(deps): update dependency c8 to v8 (#498)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-25 10:02:46 +02:00
renovate[bot]
994a1c3401
chore(deps): update dependency @types/jsdom to v21 (#495)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-24 18:55:46 +02:00
renovate[bot]
05edaf423c
chore(deps): update node.js to v16.20.1 (#491)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-24 18:54:36 +02:00
renovate[bot]
8c72e692a7
fix(deps): update dependency country-code-lookup to ^0.1.0 (#493)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-24 18:49:54 +02:00
renovate[bot]
cec9dea9e0
fix(deps): update dependency @vueuse/head to ^0.9.0 (#492)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-24 18:48:42 +02:00
renovate[bot]
49eacea195
chore(deps): update dependency vitest to ^0.32.0 (#489)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-24 18:47:57 +02:00
renovate[bot]
3f7d469e9f
chore(deps): update actions/checkout action to v3 (#494)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-24 18:46:01 +02:00
renovate[bot]
5f2190887d
chore(deps): update dependency unplugin-vue-components to ^0.25.0 (#484)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-23 22:19:08 +02:00
renovate[bot]
6cb0845336
chore(deps): update dependency unplugin-auto-import to ^0.16.0 (#483)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-23 22:18:44 +02:00
Corentin Thomasset
12d9e5d377
fix(i18n): fallback for demo i18n 2023-06-23 21:57:08 +02:00
Corentin Thomasset
e29b258e90 feat(new-tool): yaml to toml 2023-06-23 21:47:23 +02:00
Corentin Thomasset
ea50a3fc65 feat(new-tool): json to toml 2023-06-23 21:47:23 +02:00
Corentin Thomasset
746e5bdccc feat(new-tool): toml to yaml 2023-06-23 21:47:23 +02:00
Corentin Thomasset
c7d4f112c0 feat(new-tool): toml to json 2023-06-23 21:47:23 +02:00
Marvin
9125dcf9c6
refactor(json-viewer): input monospace font (#485) 2023-06-23 19:38:34 +00:00
renovate[bot]
38710dce56
chore(deps): update dependency unocss to ^0.53.0 (#482)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-23 21:30:45 +02:00
renovate[bot]
282cfc4c4b
chore(deps): update dependency @unocss/eslint-config to ^0.53.0 (#478)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-23 16:59:18 +02:00
Marvin
ba4876d0d5
refacor(transformers): use monospace font for JSON and SQL text areas (#476)
* feat(c-input): Add monospace prop

* feat: use monospace input for json and sql inputs
2023-06-23 16:51:52 +02:00
renovate[bot]
363c2e47e6
chore(deps): added renovate.json (#477)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-23 16:49:03 +02:00
Marvin
9526ed8324
fix(typos): fixed more typos & uppercase JSON (#475)
* fix(About): typo

* uppercase json & typos
2023-06-23 15:23:47 +02:00
Marvin
7068610438
fix(about): typos and wording (#474)
* fix(About): typos and wording

* Update src/pages/About.vue

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2023-06-21 19:45:48 +00:00
Corentin THOMASSET
847323ccba
docs(ide): updated vscode extensions settings (#472) 2023-06-19 21:49:40 +00:00
Corentin THOMASSET
1b038c7826
chore(i18n): tool scoped locales (#471) 2023-06-19 21:14:44 +00:00
Corentin Thomasset
ec4c533718
feat(command-palette): random tool action 2023-06-19 21:51:25 +02:00
Seb
63045951e1
feat(config): allow app to run in a subfolder via BASE_URL (#461)
* fix: allow hosting in subfolder via BASE_URL

* Import baseUrl from config

* Revert "Import baseUrl from config"

This reverts commit 73c867ebc8.

* feat(config): fallback baseUrl to /

* feat(config): fallback baseUrl to /

---------

Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-06-19 18:42:29 +02:00
Corentin THOMASSET
c4cec9e18f
fix(mime-types): typos (#470) 2023-06-19 16:09:03 +00:00
Corentin THOMASSET
bcb98b359c
refactor(search): command palette design (#463) 2023-06-19 00:35:50 +02:00
Corentin Thomasset
732da08157 chore(wysiwyg-editor): update tiptap dependencies 2023-06-19 00:08:07 +02:00
Seb
b9406a492d
feat(new-tool): percentage calculator (#456)
* feat(new tool): percentage calculator

* Apply suggestions from code review

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2023-06-18 18:24:39 +02:00
Corentin Thomasset
69f0bd079f
feat(new-tool): json to csv converter 2023-06-18 18:10:06 +02:00
Corentin Thomasset
4cbd7ac145 fix(sonar): took down minor sonar warning 2023-06-18 14:56:52 +02:00
Corentin Thomasset
ebfb872fae chore(i18n): setup i18n plugin config 2023-06-18 14:33:58 +02:00
jmmanzano
a6bbeaebd8
feat(new tool): xml formatter (#457)
* feat(new tool): xml formatter

* feat(xml-formatter): added happy path e2e tests

* refactor(xml-formatter): improved unit tests

* refactor(xml-formatter): add better suitable icon

* feat(xml-formatter): added happy path e2e tests

* feat(xml-formatter): registered xml as syntax highlighter

* chore(auto-import): removed unused NSpace

---------

Co-authored-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2023-06-18 10:27:26 +00:00
myztillx
f771e7a99f
feat(chmod-calculator): added symbolic representation (#455) 2023-06-18 11:01:54 +02:00
Seb
cf7b1f000a
feat(enhancement): use system dark mode (#458)
* Use prefers-color-scheme

* Remove theme store
2023-06-18 10:59:22 +02:00
Corentin Thomasset
1e2a35b892 refactor(c-input-text): force usage of props with default 2023-06-11 21:27:40 +02:00
Corentin Thomasset
45c2474279 refactor(naming): prevent auto import conflicts for git memo 2023-06-10 17:37:38 +02:00
Corentin Thomasset
fe61f0f2f2 refactor(imports): removed unnecessary imports to vue 2023-06-10 17:24:10 +02:00
David Nguyen
93799af83c
chore(config): netlify deployment support (#443)
* Create netlify.toml

* Update netlify.toml

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
2023-06-10 17:02:08 +02:00
Corentin Thomasset
962a6d6ec4 chore(ci): shard e2e tests 2023-06-10 16:59:54 +02:00
Corentin Thomasset
d2956b66fe feat(phone-parser): searchable country code select 2023-06-10 16:43:03 +02:00
DawnElixir
105b21badc
fix(readme): typo
Fix readme typo
2023-05-31 22:55:44 +02:00
Corentin Thomasset
33c9b6643f chore(lint): switched to a better lint config 2023-05-28 23:29:14 +02:00
Corentin Thomasset
4d2b037dbe refactor(ui): removed all n-space 2023-05-27 17:53:13 +02:00
Corentin Thomasset
34d8e5ce2c
feat(new tool): camera screenshot and recorder 2023-05-17 00:34:10 +02:00
Corentin Thomasset
8515c24264 chors(deps): updated vueuse dependency version 2023-05-15 17:21:59 +02:00
cgoIT
0b20f1c16a
feat(base64-string-converter): switch to encode and decode url safe base64 strings (#392)
* feat(base64-string-converter): switch to encode and decode url safe

* feat(base64-string-converter): changes based on review comments, use config object instead of boolean argument.

* feat(base64-string-converter): fix validation, add option to watch additional refs for changes which interfere with validation rules
2023-05-15 14:35:44 +02:00
cgoIT
8c92d56318
fix(ipv4-range-expander): calculate correct for ip addresses where the first octet is lower than 128 (#405) 2023-05-15 10:23:16 +02:00
Corentin Thomasset
7aed9c56fd fix(ipv4-converter): removed readonly on input 2023-05-15 10:00:55 +02:00
Corentin Thomasset
f7fc779e63 refactor(ui): replaced some n-input with c-input-text 2023-05-15 01:31:22 +02:00
Corentin Thomasset
b3b6b7c46b
chore(version): release 2023.05.14-77f2efc 2023-05-14 22:48:20 +02:00
Corentin Thomasset
141c12455e
docs(changelog): update changelog for 2023.05.14-77f2efc 2023-05-14 22:48:20 +02:00
Corentin Thomasset
77f2efc0b9 refactor(ui): replaced some n-input with c-input-text 2023-05-14 22:30:23 +02:00
Corentin Thomasset
aad8d84e13 ui-lib(new-component): added text input component in the c-lib 2023-05-14 22:30:23 +02:00
Corentin Thomasset
401f13f7e3 ui-lib(button): size variants 2023-05-14 22:30:23 +02:00
Corentin THOMASSET
edae4c6915 chore(issues): updated new tool request issue template 2023-05-13 22:09:55 +02:00
Corentin Thomasset
a43c546e34
fix(phone-parser): use default country code 2023-05-07 13:25:33 +02:00
cgoIT
83a7b3bae9
feat(list-converter): a small converter who deals with column based data and do some stuff with it (#387)
* feat(list-converter): a small converter who deals with column based data and do some stuff with it

* Update src/tools/list-converter/index.ts

* Update src/tools/list-converter/index.ts

* Update src/tools/list-converter/index.ts

---------

Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>

fix(list-format): fix e2e
2023-05-07 13:25:25 +02:00
Corentin Thomasset
ce3150c65d feat(new tool): phone parser and normalizer 2023-05-02 13:57:39 +02:00
Corentin Thomasset
3f6c8f0edd
fix(home): prevent weird blue border on card 2023-05-01 13:44:30 +02:00
Corentin Thomasset
daf2cf0285
chore(version): release 2023.04.23-92bd835 2023-04-23 22:44:35 +02:00
Corentin Thomasset
b7aaea1b58
docs(changelog): update changelog for 2023.04.23-92bd835 2023-04-23 22:44:35 +02:00
Corentin Thomasset
92bd83536f feat(ui-lib): demo pages for c-lib components 2023-04-23 22:43:06 +02:00
Corentin Thomasset
e88c1d5f2c fix(ts): cleaned legacy typechecking warning 2023-04-23 17:11:04 +02:00
Corentin Thomasset
362f2fa280 feat(new-tool): diff of two json objects 2023-04-23 15:24:20 +02:00
Corentin Thomasset
61ece2387f
refactor(ui-lib): prevent c-button to shrink 2023-04-20 21:03:20 +02:00
Corentin Thomasset
f080933d2a refactor(ui): replaced naive ui cards with custom ones 2023-04-20 20:57:38 +02:00
Corentin Thomasset
bb32513bd3
refactor(clean): removed unused lodash import 2023-04-19 22:58:07 +02:00
Corentin Thomasset
c311e3824d fix(mac-address-lookup): added copy handler on button click 2023-04-19 22:56:50 +02:00
Corentin Thomasset
74073f5038 refactor(clean): removed useless br tags 2023-04-19 22:50:02 +02:00
Corentin Thomasset
c45bce36f9 refactor(ui): getting ride of naive ui buttons 2023-04-19 22:33:22 +02:00
cgoIT
df989e24b3
feat(ipv4-range-expander): expands a given IPv4 start and end address to a valid IPv4 subnet (#366)
* feat(ipv4-range-expander): expands a given IPv4 start and end address to a valid IPv4 subnet

* feat(ipv4-range-expander): remove old component copyable-ip-like.vue

* feat(ipv4-range-expander): fix sonar findings

* feat(ipv4-range-expander): changes due to review

* feat(ipv4-range-expander): only show n-alert if both ipv4 addresses are valid
2023-04-19 20:30:45 +02:00
Corentin Thomasset
6d2202597c feat(date converter): auto focus main input 2023-04-19 13:07:24 +02:00
446 changed files with 26714 additions and 10516 deletions

5
.dockerignore Normal file
View file

@ -0,0 +1,5 @@
node_modules
playwright-report
coverage
dist
test-results

View file

@ -22,7 +22,9 @@
"createGlobalState": true,
"createInjectionState": true,
"createReactiveFn": true,
"createReusableTemplate": true,
"createSharedComposable": true,
"createTemplatePromise": true,
"createUnrefFn": true,
"customRef": true,
"debouncedRef": true,
@ -42,9 +44,6 @@
"isReactive": true,
"isReadonly": true,
"isRef": true,
"logicAnd": true,
"logicNot": true,
"logicOr": true,
"makeDestructurable": true,
"markRaw": true,
"nextTick": true,
@ -107,6 +106,19 @@
"unrefElement": true,
"until": true,
"useActiveElement": true,
"useAnimate": true,
"useArrayDifference": true,
"useArrayEvery": true,
"useArrayFilter": true,
"useArrayFind": true,
"useArrayFindIndex": true,
"useArrayFindLast": true,
"useArrayIncludes": true,
"useArrayJoin": true,
"useArrayMap": true,
"useArrayReduce": true,
"useArraySome": true,
"useArrayUnique": true,
"useAsyncQueue": true,
"useAsyncState": true,
"useAttrs": true,
@ -117,8 +129,8 @@
"useBroadcastChannel": true,
"useBrowserLocation": true,
"useCached": true,
"useClamp": true,
"useClipboard": true,
"useCloned": true,
"useColorMode": true,
"useConfirmDialog": true,
"useCounter": true,
@ -160,6 +172,7 @@
"useFullscreen": true,
"useGamepad": true,
"useGeolocation": true,
"useI18n": true,
"useIdle": true,
"useImage": true,
"useInfiniteScroll": true,
@ -192,12 +205,18 @@
"useOnline": true,
"usePageLeave": true,
"useParallax": true,
"useParentElement": true,
"usePerformanceObserver": true,
"usePermission": true,
"usePointer": true,
"usePointerLock": true,
"usePointerSwipe": true,
"usePreferredColorScheme": true,
"usePreferredContrast": true,
"usePreferredDark": true,
"usePreferredLanguages": true,
"usePreferredReducedMotion": true,
"usePrevious": true,
"useRafFn": true,
"useRefHistory": true,
"useResizeObserver": true,
@ -211,14 +230,17 @@
"useSessionStorage": true,
"useShare": true,
"useSlots": true,
"useSorted": true,
"useSpeechRecognition": true,
"useSpeechSynthesis": true,
"useStepper": true,
"useStorage": true,
"useStorageAsync": true,
"useStyleTag": true,
"useSupported": true,
"useSwipe": true,
"useTemplateRefsList": true,
"useTextDirection": true,
"useTextSelection": true,
"useTextareaAutosize": true,
"useThrottle": true,
@ -230,6 +252,8 @@
"useTimeoutPoll": true,
"useTimestamp": true,
"useTitle": true,
"useToNumber": true,
"useToString": true,
"useToggle": true,
"useTransition": true,
"useUrlSearchParams": true,
@ -250,8 +274,10 @@
"watchArray": true,
"watchAtMost": true,
"watchDebounced": true,
"watchDeep": true,
"watchEffect": true,
"watchIgnorable": true,
"watchImmediate": true,
"watchOnce": true,
"watchPausable": true,
"watchPostEffect": true,
@ -259,6 +285,7 @@
"watchThrottled": true,
"watchTriggerable": true,
"watchWithFilter": true,
"whenever": true
"whenever": true,
"toValue": true
}
}

View file

@ -1,39 +1,21 @@
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution');
/**
* @type {import('eslint').Linter.Config}
*/
module.exports = {
root: true,
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'plugin:vue/vue3-recommended',
'@vue/eslint-config-typescript/recommended',
'@vue/eslint-config-prettier',
'plugin:import/recommended',
'./.eslintrc-auto-import.json',
'@unocss',
],
extends: ['@antfu', './.eslintrc-auto-import.json', '@unocss'],
settings: {
'import/resolver': { typescript: { project: './tsconfig.app.json' } },
},
env: {
'vue/setup-compiler-macros': true,
},
rules: {
'vue/multi-word-component-names': ['off'],
'prettier/prettier': ['error'],
'import/no-duplicates': ['error', { considerQueryString: true }],
'import/order': ['error', { groups: [['builtin', 'external', 'internal']] }],
'import/extensions': [
'error',
'ignorePackages',
{
js: 'never',
ts: 'never',
tsx: 'never',
},
],
'import/no-unresolved': ['error', { ignore: ['^virtual:'] }],
'curly': ['error', 'all'],
'@typescript-eslint/semi': ['error', 'always'],
'@typescript-eslint/no-use-before-define': ['error', { allowNamedExports: true, functions: false }],
'vue/no-empty-component-block': ['error'],
'no-restricted-imports': ['error', {
paths: [{
name: '@vueuse/core',
importNames: ['useClipboard'],
message: 'Please use local useCopy from src/composable/copy.ts instead of useClipboard.',
}],
}],
},
};

View file

@ -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
View 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
View file

@ -0,0 +1 @@
blank_issues_enabled: false

View 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

View file

@ -1,19 +0,0 @@
---
name: New tool request
about: Suggest a new tool idea
title: '[NEW TOOL]'
labels: new tool
assignees: CorentinTh
---
**Which tool is impacted?**
Example: the 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.

View file

@ -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.

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
.github/logo-white.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
.github/logo.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

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

View file

@ -11,11 +11,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- run: corepack enable
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 20
cache: 'pnpm'
- name: Install dependencies
@ -27,5 +27,8 @@ jobs:
- name: Run unit test
run: pnpm test
- name: Type check
run: pnpm typecheck
- name: Build the app
run: pnpm build

View file

@ -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@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
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@v1
# 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@v1

View file

@ -12,7 +12,7 @@ jobs:
outputs:
should_run: ${{ steps.should_run.outputs.should_run }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- name: print latest_commit
run: echo ${{ github.sha }}
@ -28,11 +28,11 @@ jobs:
if: ${{ needs.check_date.outputs.should_run != 'false' }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- run: corepack enable
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 20
cache: 'pnpm'
- name: Install dependencies
@ -54,29 +54,29 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile

47
.github/workflows/e2e-tests.yml vendored Normal file
View file

@ -0,0 +1,47 @@
name: E2E tests
on:
pull_request:
push:
branches:
- main
jobs:
test:
timeout-minutes: 10
runs-on: ubuntu-latest
strategy:
matrix:
shard: [1/3, 2/3, 3/3]
steps:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- run: corepack enable
- uses: actions/setup-node@v3
with:
node-version: 20
cache: 'pnpm'
- name: Get Playwright version
id: playwright-version
run: echo "PLAYWRIGHT_VERSION=$(jq -r .dependencies.playwright package.json)" >> "$GITHUB_OUTPUT"
- name: Install dependencies
run: pnpm install
- name: Build app
run: pnpm build
- name: Restore Playwright browsers from cache
uses: actions/cache@v3
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.PLAYWRIGHT_VERSION }}-${{ hashFiles('**/playwright.config.ts') }}
restore-keys: |
${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.PLAYWRIGHT_VERSION }}-
${{ runner.os }}-playwright-
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps
- name: Run Playwright tests
run: pnpm run test:e2e --shard=${{ matrix.shard }}

View file

@ -1,23 +0,0 @@
name: E2E tests
on:
pull_request:
push:
branches:
- main
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: corepack enable
- uses: actions/setup-node@v3
with:
node-version: 16
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps
- name: Run Playwright tests
run: pnpm exec playwright test

View file

@ -13,29 +13,29 @@ jobs:
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
@ -55,13 +55,13 @@ jobs:
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- run: corepack enable
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 20
cache: 'pnpm'
- name: Install dependencies

2
.gitignore vendored
View file

@ -31,3 +31,5 @@ coverage
/test-results/
/playwright-report/
/playwright/.cache/
# Webkit with playwright creates a salt file
salt

2
.nvmrc
View file

@ -1 +1 @@
16.14.2
18.18.2

View file

@ -1,3 +1,3 @@
{
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin", "dbaeumer.vscode-eslint"]
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin", "dbaeumer.vscode-eslint", "lokalise.i18n-ally"]
}

View file

@ -2,51 +2,420 @@
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)
- **new tool**: pdf signature checker (#745) (4781920)
- **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)
- **base64-file-converter**: fix downloading of index.html content without data preambula (#750) (043e4f0)
- **docker**: rollback armv7 in docker releases (#741) (205e360)
- **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)
- **case converter**: no split on lowercase, uppercase and mocking case (#748) (ca43a25)
- **ui**: replaced legacy n-upload with c-file-upload (#747) (7fe47b3)
- **token**: added password in token generator keywords (#746) (16ffe6b)
- **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)
## 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)
- **case-converter**: added mocking case (#705) (681f7bf)
- **date-converter**: added excel date time format (#704) (f5eb7a8)
- **i18n**: token generator (#688) (02e68d3)
- **i18n**: home page (#687) (00562ed)
- **i18n**: support for i18n in .ts files (#683) (ebb4ec4)
- **i18n**: tool card (#682) (84a4a64)
- **i18n**: about page (#680) (a2b53c2)
- **i18n**: 404 page (#679) (35563b8)
- **new tool**: text to ascii converter (#669) (b2ad4f7)
- **new tool**: ULID generator (#623) (5c4d775)
- **new tool**: add wifi qr code generator (#599) (0eedce6)
- **new tool**: iban validation and parser (#591) (3a63837)
- **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)
- **c-table**: added description on c-table for accessibility (b408df8)
- **ci**: reduced timeout in e2e (#666) (88b8818)
- **ui**: new c-table ui component (#665) (ee4c853)
- **ui**: removed n-page-header component in user-agent parser (#663) (cbf58fd)
- **ui**: removed n-p components in about page (#662) (a757a51)
- **ui**: switched naive tooltip components to custom ones (#661) (025f556)
- **spelling**: minor corrections to phrasing/spelling (#596) (8a30b6b)
- **i18n**: merge tools scoped locales with global ones (#612) (233d556)
- **c-key-value-list**: got rid of table for layout (#611) (7ab9204)
- **CI**: run e2e against built app and no longer vercel (#610) (18dd140)
- **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)
- **deps**: update docker/login-action action to v3 (#625) (d8d7a3b)
- **deps**: update docker/build-push-action action to v5 (#624) (d36b18f)
- **deps**: update dependency node to v18.18.2 (#674) (eea9f91)
- **deps**: update dependency node to v18.18.0 (#636) (2d2dffb)
- **deps**: update actions/checkout action to v4 (#613) (4972159)
- **deps**: update dependency unplugin-icons to ^0.17.0 (#609) (f035f48)
- **deps**: update dependency @intlify/unplugin-vue-i18n to ^0.13.0 (#597) (d1dff42)
- **deps**: update dependency @antfu/eslint-config to ^0.41.0 (#585) (a9cd91c)
- **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)
- **deps**: removed @typescript-eslint/parser (#563) (144f86e)
- **deps**: removed ts-pattern (#565) (0f1f659)
## 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)
- **new-tool**: password strength analyzer (#502) (a9c7b89)
- **new-tool**: yaml to toml (e29b258)
- **new-tool**: json to toml (ea50a3f)
- **new-tool**: toml to yaml (746e5bd)
- **new-tool**: toml to json (c7d4f11)
- **command-palette**: random tool action (ec4c533)
- **config**: allow app to run in a subfolder via BASE_URL (#461) (6304595)
- **new-tool**: percentage calculator (#456) (b9406a4)
- **new-tool**: json to csv converter (69f0bd0)
- **new tool**: xml formatter (#457) (a6bbeae)
- **chmod-calculator**: added symbolic representation (#455) (f771e7a)
- **enhancement**: use system dark mode (#458) (cf7b1f0)
- **phone-parser**: searchable country code select (d2956b6)
- **new tool**: camera screenshot and recorder (34d8e5c)
- **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)
- **copy**: prevent shorthand copy if source is present in useCopy (#559) (86e964a)
- **c-lib**: hide component library shortcut link in non-dev (#557) (56d74d0)
- **emoji picker**: fix copy button (#556) (e5d0ba7)
- **deps**: update dependency @vueuse/head to v1 (#515) (d12dd40)
- **deps**: update dependency country-code-lookup to ^0.1.0 (#493) (8c72e69)
- **deps**: update dependency @vueuse/head to ^0.9.0 (#492) (cec9dea)
- **i18n**: fallback for demo i18n (12d9e5d)
- **typos**: fixed more typos & uppercase JSON (#475) (9526ed8)
- **about**: typos and wording (#474) (7068610)
- **mime-types**: typos (#470) (c4cec9e)
- **sonar**: took down minor sonar warning (4cbd7ac)
- **readme**: typo (105b21b)
- **ipv4-range-expander**: calculate correct for ip addresses where the first octet is lower than 128 (#405) (8c92d56)
- **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)
- **json-viewer**: input monospace font (#485) (9125dcf)
- **search**: command palette design (#463) (bcb98b3)
- **c-input-text**: force usage of props with default (1e2a35b)
- **naming**: prevent auto import conflicts for git memo (45c2474)
- **imports**: removed unnecessary imports to vue (fe61f0f)
- **ui**: removed all n-space (4d2b037)
- **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)
- **deps**: update dependency @unocss/eslint-config to ^0.55.0 (#553) (4268e25)
- **deps**: update dependency @intlify/unplugin-vue-i18n to ^0.12.0 (#526) (d1c8880)
- **deps**: update docker/login-action action to v2 (#512) (99bc84c)
- **deps**: update dependency jsdom to v22 (#499) (cd5a503)
- **deps**: update dependency @vitejs/plugin-vue-jsx to v3 (#497) (1a60236)
- **deps**: update dependency @vitejs/plugin-vue to v4 (#496) (a249421)
- **deps**: update dependency vite-plugin-pwa to ^0.16.0 (#488) (6498c9b)
- **deps**: update dependency vite to v4 (#503) (f40d7ec)
- **ci**: e2e against vercel deployement (#518) (2e28c50)
- **e2e**: execute e2e against built app (#511) (cf382b5)
- **deps**: update github/codeql-action action to v2 (#513) (0152583)
- **deps**: update node.js to v18 (#514) (38cb61d)
- **deps**: switched from vite-plugin-md to vite-plugin-vue-markdown (#510) (354aed6)
- **deps**: update dependency workbox-window to v7 (#509) (6b8682f)
- **deps**: update dependency vite-svg-loader to v4 (#508) (9e8349d)
- **deps**: update dependency typescript to ~4.9.0 (#481) (f440507)
- **deps**: update dependency vue-tsc to ^0.40.0 (#490) (b0d9a3e)
- **deps**: updated unplugin-auto-import (#504) (5c3bebf)
- **deps**: removed start-server-and-test dependency (8df7cd0)
- **deps**: update dependency c8 to v8 (#498) (6bda2ca)
- **deps**: update dependency @types/jsdom to v21 (#495) (994a1c3)
- **deps**: update node.js to v16.20.1 (#491) (05edaf4)
- **deps**: update dependency vitest to ^0.32.0 (#489) (49eacea)
- **deps**: update actions/checkout action to v3 (#494) (3f7d469)
- **deps**: update dependency unplugin-vue-components to ^0.25.0 (#484) (5f21908)
- **deps**: update dependency unplugin-auto-import to ^0.16.0 (#483) (6cb0845)
- **deps**: update dependency unocss to ^0.53.0 (#482) (38710dc)
- **deps**: update dependency @unocss/eslint-config to ^0.53.0 (#478) (282cfc4)
- **deps**: added renovate.json (#477) (363c2e4)
- **i18n**: tool scoped locales (#471) (1b038c7)
- **wysiwyg-editor**: update tiptap dependencies (732da08)
- **i18n**: setup i18n plugin config (ebfb872)
- **config**: netlify deployment support (#443) (93799af)
- **ci**: shard e2e tests (962a6d6)
- **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)
- **clean**: removed useless br tags (74073f5)
- **ui**: getting ride of naive ui buttons (c45bce3)
## 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)

View file

@ -1,9 +1,12 @@
# build stage
FROM node:lts-alpine AS build-stage
# Set environment variables for non-interactive npm installs
ENV NPM_CONFIG_LOGLEVEL warn
ENV CI true
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm i --frozen-lockfile
COPY . .
RUN npm install -g pnpm
RUN pnpm i --frozen-lockfile
RUN pnpm build
# production stage

View file

@ -1,4 +1,8 @@
![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).
@ -6,7 +10,7 @@ Useful tools for developer and people working in IT. [Have a look !](https://it-
Please check the [issues](https://github.com/CorentinTh/it-tools/issues) to see if some feature listed to be implemented.
You have an idea of a tool? Submit a [feature request](https://github.com/CorentinTh/it-tools/issues/new?assignees=corentinth&labels=&template=feature_request.md&title=)!
You have an idea of a tool? Submit a [feature request](https://github.com/CorentinTh/it-tools/issues/new/choose)!
## Self host
@ -26,6 +30,7 @@ docker run -d --name it-tools --restart unless-stopped -p 8080:80 ghcr.io/corent
**Other solutions:**
- [Cloudron](https://www.cloudron.io/store/tech.ittools.cloudron.html)
- [Tipi](https://www.runtipi.io/docs/apps-available)
- [Unraid](https://unraid.net/community/apps?q=it-tools)
@ -33,7 +38,25 @@ docker run -d --name it-tools --restart unless-stopped -p 8080:80 ghcr.io/corent
### Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
[VSCode](https://code.visualstudio.com/) with the following extensions:
- [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur)
- [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
- [i18n Ally](https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally)
with the following settings:
```json
{
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"i18n-ally.localesPaths": ["locales", "src/tools/*/locales"],
"i18n-ally.keystyle": "nested"
}
```
### Type Support for `.vue` Imports in TS
@ -81,17 +104,25 @@ pnpm lint
To create a new tool, there is a script that generate the boilerplate of the new tool, simply run:
```sh
pnpm run script:create-new-tool my-tool-name
pnpm run script:create:tool my-tool-name
```
It will create a directory in `src/tools` with the correct files, and a the import in `src/tools/index.ts`. You will just need to add the inported tool in the proper category and develop the tool.
It will create a directory in `src/tools` with the correct files, and a the import in `src/tools/index.ts`. You will just need to add the imported tool in the proper category and develop the tool.
## Contributors
Big thanks to all the people who have already contributed!
[![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).
Contributor graph is generated using [contrib.rocks](https://contrib.rocks/preview?repo=corentinth/it-tools).
<a href="https://www.producthunt.com/posts/it-tools?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-it&#0045;tools" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=345793&theme=light" alt="IT&#0032;Tools - Collection&#0032;of&#0032;handy&#0032;online&#0032;tools&#0032;for&#0032;devs&#0044;&#0032;with&#0032;great&#0032;UX | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
<a href="https://www.producthunt.com/posts/it-tools?utm_source=badge-top-post-badge&utm_medium=badge&utm_souce=badge-it&#0045;tools" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=345793&theme=light&period=daily" alt="IT&#0032;Tools - Collection&#0032;of&#0032;handy&#0032;online&#0032;tools&#0032;for&#0032;devs&#0044;&#0032;with&#0032;great&#0032;UX | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>

View file

@ -0,0 +1,6 @@
---
to: src/ui/<%= h.changeCase.param(name) %>/<%= h.changeCase.param(name) %>.demo.vue
---
<template>
<<%= h.changeCase.param(name) %> />
</template>

View file

@ -0,0 +1,13 @@
---
to: src/ui/<%= h.changeCase.param(name) %>/<%= h.changeCase.param(name) %>.vue
---
<script lang="ts" setup>
const props = withDefaults(defineProps<{ prop?: string }>(), { prop: '' });
const { prop } = toRefs(props);
</script>
<template>
<div>
{{ prop }}
</div>
</template>

354
auto-imports.d.ts vendored
View file

@ -19,7 +19,9 @@ declare global {
const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate']
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise']
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
const customRef: typeof import('vue')['customRef']
const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
@ -39,9 +41,6 @@ declare global {
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const logicAnd: typeof import('@vueuse/core')['logicAnd']
const logicNot: typeof import('@vueuse/core')['logicNot']
const logicOr: typeof import('@vueuse/core')['logicOr']
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
@ -94,6 +93,7 @@ declare global {
const toReactive: typeof import('@vueuse/core')['toReactive']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toValue: typeof import('vue')['toValue']
const triggerRef: typeof import('vue')['triggerRef']
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount']
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount']
@ -104,6 +104,19 @@ declare global {
const unrefElement: typeof import('@vueuse/core')['unrefElement']
const until: typeof import('@vueuse/core')['until']
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
const useAnimate: typeof import('@vueuse/core')['useAnimate']
const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference']
const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery']
const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter']
const useArrayFind: typeof import('@vueuse/core')['useArrayFind']
const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex']
const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast']
const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes']
const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin']
const useArrayMap: typeof import('@vueuse/core')['useArrayMap']
const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce']
const useArraySome: typeof import('@vueuse/core')['useArraySome']
const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique']
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
const useAttrs: typeof import('vue')['useAttrs']
@ -114,8 +127,8 @@ declare global {
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
const useCached: typeof import('@vueuse/core')['useCached']
const useClamp: typeof import('@vueuse/core')['useClamp']
const useClipboard: typeof import('@vueuse/core')['useClipboard']
const useCloned: typeof import('@vueuse/core')['useCloned']
const useColorMode: typeof import('@vueuse/core')['useColorMode']
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
const useCounter: typeof import('@vueuse/core')['useCounter']
@ -157,6 +170,7 @@ declare global {
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
const useGamepad: typeof import('@vueuse/core')['useGamepad']
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
const useI18n: typeof import('vue-i18n')['useI18n']
const useIdle: typeof import('@vueuse/core')['useIdle']
const useImage: typeof import('@vueuse/core')['useImage']
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
@ -189,12 +203,18 @@ declare global {
const useOnline: typeof import('@vueuse/core')['useOnline']
const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
const useParallax: typeof import('@vueuse/core')['useParallax']
const useParentElement: typeof import('@vueuse/core')['useParentElement']
const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver']
const usePermission: typeof import('@vueuse/core')['usePermission']
const usePointer: typeof import('@vueuse/core')['usePointer']
const usePointerLock: typeof import('@vueuse/core')['usePointerLock']
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
const usePrevious: typeof import('@vueuse/core')['usePrevious']
const useRafFn: typeof import('@vueuse/core')['useRafFn']
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
@ -208,14 +228,17 @@ declare global {
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
const useShare: typeof import('@vueuse/core')['useShare']
const useSlots: typeof import('vue')['useSlots']
const useSorted: typeof import('@vueuse/core')['useSorted']
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
const useStepper: typeof import('@vueuse/core')['useStepper']
const useStorage: typeof import('@vueuse/core')['useStorage']
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
const useSupported: typeof import('@vueuse/core')['useSupported']
const useSwipe: typeof import('@vueuse/core')['useSwipe']
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
const useTextDirection: typeof import('@vueuse/core')['useTextDirection']
const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize']
const useThrottle: typeof import('@vueuse/core')['useThrottle']
@ -227,6 +250,8 @@ declare global {
const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll']
const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
const useTitle: typeof import('@vueuse/core')['useTitle']
const useToNumber: typeof import('@vueuse/core')['useToNumber']
const useToString: typeof import('@vueuse/core')['useToString']
const useToggle: typeof import('@vueuse/core')['useToggle']
const useTransition: typeof import('@vueuse/core')['useTransition']
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
@ -247,8 +272,10 @@ declare global {
const watchArray: typeof import('@vueuse/core')['watchArray']
const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
const watchDebounced: typeof import('@vueuse/core')['watchDebounced']
const watchDeep: typeof import('@vueuse/core')['watchDeep']
const watchEffect: typeof import('vue')['watchEffect']
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
const watchImmediate: typeof import('@vueuse/core')['watchImmediate']
const watchOnce: typeof import('@vueuse/core')['watchOnce']
const watchPausable: typeof import('@vueuse/core')['watchPausable']
const watchPostEffect: typeof import('vue')['watchPostEffect']
@ -282,7 +309,9 @@ declare module 'vue' {
readonly createGlobalState: UnwrapRef<typeof import('@vueuse/core')['createGlobalState']>
readonly createInjectionState: UnwrapRef<typeof import('@vueuse/core')['createInjectionState']>
readonly createReactiveFn: UnwrapRef<typeof import('@vueuse/core')['createReactiveFn']>
readonly createReusableTemplate: UnwrapRef<typeof import('@vueuse/core')['createReusableTemplate']>
readonly createSharedComposable: UnwrapRef<typeof import('@vueuse/core')['createSharedComposable']>
readonly createTemplatePromise: UnwrapRef<typeof import('@vueuse/core')['createTemplatePromise']>
readonly createUnrefFn: UnwrapRef<typeof import('@vueuse/core')['createUnrefFn']>
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
readonly debouncedRef: UnwrapRef<typeof import('@vueuse/core')['debouncedRef']>
@ -302,9 +331,6 @@ declare module 'vue' {
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly logicAnd: UnwrapRef<typeof import('@vueuse/core')['logicAnd']>
readonly logicNot: UnwrapRef<typeof import('@vueuse/core')['logicNot']>
readonly logicOr: UnwrapRef<typeof import('@vueuse/core')['logicOr']>
readonly makeDestructurable: UnwrapRef<typeof import('@vueuse/core')['makeDestructurable']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
@ -357,6 +383,7 @@ declare module 'vue' {
readonly toReactive: UnwrapRef<typeof import('@vueuse/core')['toReactive']>
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly tryOnBeforeMount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeMount']>
readonly tryOnBeforeUnmount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeUnmount']>
@ -367,6 +394,19 @@ declare module 'vue' {
readonly unrefElement: UnwrapRef<typeof import('@vueuse/core')['unrefElement']>
readonly until: UnwrapRef<typeof import('@vueuse/core')['until']>
readonly useActiveElement: UnwrapRef<typeof import('@vueuse/core')['useActiveElement']>
readonly useAnimate: UnwrapRef<typeof import('@vueuse/core')['useAnimate']>
readonly useArrayDifference: UnwrapRef<typeof import('@vueuse/core')['useArrayDifference']>
readonly useArrayEvery: UnwrapRef<typeof import('@vueuse/core')['useArrayEvery']>
readonly useArrayFilter: UnwrapRef<typeof import('@vueuse/core')['useArrayFilter']>
readonly useArrayFind: UnwrapRef<typeof import('@vueuse/core')['useArrayFind']>
readonly useArrayFindIndex: UnwrapRef<typeof import('@vueuse/core')['useArrayFindIndex']>
readonly useArrayFindLast: UnwrapRef<typeof import('@vueuse/core')['useArrayFindLast']>
readonly useArrayIncludes: UnwrapRef<typeof import('@vueuse/core')['useArrayIncludes']>
readonly useArrayJoin: UnwrapRef<typeof import('@vueuse/core')['useArrayJoin']>
readonly useArrayMap: UnwrapRef<typeof import('@vueuse/core')['useArrayMap']>
readonly useArrayReduce: UnwrapRef<typeof import('@vueuse/core')['useArrayReduce']>
readonly useArraySome: UnwrapRef<typeof import('@vueuse/core')['useArraySome']>
readonly useArrayUnique: UnwrapRef<typeof import('@vueuse/core')['useArrayUnique']>
readonly useAsyncQueue: UnwrapRef<typeof import('@vueuse/core')['useAsyncQueue']>
readonly useAsyncState: UnwrapRef<typeof import('@vueuse/core')['useAsyncState']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
@ -377,8 +417,8 @@ declare module 'vue' {
readonly useBroadcastChannel: UnwrapRef<typeof import('@vueuse/core')['useBroadcastChannel']>
readonly useBrowserLocation: UnwrapRef<typeof import('@vueuse/core')['useBrowserLocation']>
readonly useCached: UnwrapRef<typeof import('@vueuse/core')['useCached']>
readonly useClamp: UnwrapRef<typeof import('@vueuse/core')['useClamp']>
readonly useClipboard: UnwrapRef<typeof import('@vueuse/core')['useClipboard']>
readonly useCloned: UnwrapRef<typeof import('@vueuse/core')['useCloned']>
readonly useColorMode: UnwrapRef<typeof import('@vueuse/core')['useColorMode']>
readonly useConfirmDialog: UnwrapRef<typeof import('@vueuse/core')['useConfirmDialog']>
readonly useCounter: UnwrapRef<typeof import('@vueuse/core')['useCounter']>
@ -420,6 +460,7 @@ declare module 'vue' {
readonly useFullscreen: UnwrapRef<typeof import('@vueuse/core')['useFullscreen']>
readonly useGamepad: UnwrapRef<typeof import('@vueuse/core')['useGamepad']>
readonly useGeolocation: UnwrapRef<typeof import('@vueuse/core')['useGeolocation']>
readonly useI18n: UnwrapRef<typeof import('vue-i18n')['useI18n']>
readonly useIdle: UnwrapRef<typeof import('@vueuse/core')['useIdle']>
readonly useImage: UnwrapRef<typeof import('@vueuse/core')['useImage']>
readonly useInfiniteScroll: UnwrapRef<typeof import('@vueuse/core')['useInfiniteScroll']>
@ -452,12 +493,18 @@ declare module 'vue' {
readonly useOnline: UnwrapRef<typeof import('@vueuse/core')['useOnline']>
readonly usePageLeave: UnwrapRef<typeof import('@vueuse/core')['usePageLeave']>
readonly useParallax: UnwrapRef<typeof import('@vueuse/core')['useParallax']>
readonly useParentElement: UnwrapRef<typeof import('@vueuse/core')['useParentElement']>
readonly usePerformanceObserver: UnwrapRef<typeof import('@vueuse/core')['usePerformanceObserver']>
readonly usePermission: UnwrapRef<typeof import('@vueuse/core')['usePermission']>
readonly usePointer: UnwrapRef<typeof import('@vueuse/core')['usePointer']>
readonly usePointerLock: UnwrapRef<typeof import('@vueuse/core')['usePointerLock']>
readonly usePointerSwipe: UnwrapRef<typeof import('@vueuse/core')['usePointerSwipe']>
readonly usePreferredColorScheme: UnwrapRef<typeof import('@vueuse/core')['usePreferredColorScheme']>
readonly usePreferredContrast: UnwrapRef<typeof import('@vueuse/core')['usePreferredContrast']>
readonly usePreferredDark: UnwrapRef<typeof import('@vueuse/core')['usePreferredDark']>
readonly usePreferredLanguages: UnwrapRef<typeof import('@vueuse/core')['usePreferredLanguages']>
readonly usePreferredReducedMotion: UnwrapRef<typeof import('@vueuse/core')['usePreferredReducedMotion']>
readonly usePrevious: UnwrapRef<typeof import('@vueuse/core')['usePrevious']>
readonly useRafFn: UnwrapRef<typeof import('@vueuse/core')['useRafFn']>
readonly useRefHistory: UnwrapRef<typeof import('@vueuse/core')['useRefHistory']>
readonly useResizeObserver: UnwrapRef<typeof import('@vueuse/core')['useResizeObserver']>
@ -471,14 +518,17 @@ declare module 'vue' {
readonly useSessionStorage: UnwrapRef<typeof import('@vueuse/core')['useSessionStorage']>
readonly useShare: UnwrapRef<typeof import('@vueuse/core')['useShare']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly useSorted: UnwrapRef<typeof import('@vueuse/core')['useSorted']>
readonly useSpeechRecognition: UnwrapRef<typeof import('@vueuse/core')['useSpeechRecognition']>
readonly useSpeechSynthesis: UnwrapRef<typeof import('@vueuse/core')['useSpeechSynthesis']>
readonly useStepper: UnwrapRef<typeof import('@vueuse/core')['useStepper']>
readonly useStorage: UnwrapRef<typeof import('@vueuse/core')['useStorage']>
readonly useStorageAsync: UnwrapRef<typeof import('@vueuse/core')['useStorageAsync']>
readonly useStyleTag: UnwrapRef<typeof import('@vueuse/core')['useStyleTag']>
readonly useSupported: UnwrapRef<typeof import('@vueuse/core')['useSupported']>
readonly useSwipe: UnwrapRef<typeof import('@vueuse/core')['useSwipe']>
readonly useTemplateRefsList: UnwrapRef<typeof import('@vueuse/core')['useTemplateRefsList']>
readonly useTextDirection: UnwrapRef<typeof import('@vueuse/core')['useTextDirection']>
readonly useTextSelection: UnwrapRef<typeof import('@vueuse/core')['useTextSelection']>
readonly useTextareaAutosize: UnwrapRef<typeof import('@vueuse/core')['useTextareaAutosize']>
readonly useThrottle: UnwrapRef<typeof import('@vueuse/core')['useThrottle']>
@ -490,6 +540,8 @@ declare module 'vue' {
readonly useTimeoutPoll: UnwrapRef<typeof import('@vueuse/core')['useTimeoutPoll']>
readonly useTimestamp: UnwrapRef<typeof import('@vueuse/core')['useTimestamp']>
readonly useTitle: UnwrapRef<typeof import('@vueuse/core')['useTitle']>
readonly useToNumber: UnwrapRef<typeof import('@vueuse/core')['useToNumber']>
readonly useToString: UnwrapRef<typeof import('@vueuse/core')['useToString']>
readonly useToggle: UnwrapRef<typeof import('@vueuse/core')['useToggle']>
readonly useTransition: UnwrapRef<typeof import('@vueuse/core')['useTransition']>
readonly useUrlSearchParams: UnwrapRef<typeof import('@vueuse/core')['useUrlSearchParams']>
@ -510,8 +562,294 @@ declare module 'vue' {
readonly watchArray: UnwrapRef<typeof import('@vueuse/core')['watchArray']>
readonly watchAtMost: UnwrapRef<typeof import('@vueuse/core')['watchAtMost']>
readonly watchDebounced: UnwrapRef<typeof import('@vueuse/core')['watchDebounced']>
readonly watchDeep: UnwrapRef<typeof import('@vueuse/core')['watchDeep']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchIgnorable: UnwrapRef<typeof import('@vueuse/core')['watchIgnorable']>
readonly watchImmediate: UnwrapRef<typeof import('@vueuse/core')['watchImmediate']>
readonly watchOnce: UnwrapRef<typeof import('@vueuse/core')['watchOnce']>
readonly watchPausable: UnwrapRef<typeof import('@vueuse/core')['watchPausable']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
readonly watchThrottled: UnwrapRef<typeof import('@vueuse/core')['watchThrottled']>
readonly watchTriggerable: UnwrapRef<typeof import('@vueuse/core')['watchTriggerable']>
readonly watchWithFilter: UnwrapRef<typeof import('@vueuse/core')['watchWithFilter']>
readonly whenever: UnwrapRef<typeof import('@vueuse/core')['whenever']>
}
}
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
readonly computed: UnwrapRef<typeof import('vue')['computed']>
readonly computedAsync: UnwrapRef<typeof import('@vueuse/core')['computedAsync']>
readonly computedEager: UnwrapRef<typeof import('@vueuse/core')['computedEager']>
readonly computedInject: UnwrapRef<typeof import('@vueuse/core')['computedInject']>
readonly computedWithControl: UnwrapRef<typeof import('@vueuse/core')['computedWithControl']>
readonly controlledComputed: UnwrapRef<typeof import('@vueuse/core')['controlledComputed']>
readonly controlledRef: UnwrapRef<typeof import('@vueuse/core')['controlledRef']>
readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
readonly createEventHook: UnwrapRef<typeof import('@vueuse/core')['createEventHook']>
readonly createGlobalState: UnwrapRef<typeof import('@vueuse/core')['createGlobalState']>
readonly createInjectionState: UnwrapRef<typeof import('@vueuse/core')['createInjectionState']>
readonly createReactiveFn: UnwrapRef<typeof import('@vueuse/core')['createReactiveFn']>
readonly createReusableTemplate: UnwrapRef<typeof import('@vueuse/core')['createReusableTemplate']>
readonly createSharedComposable: UnwrapRef<typeof import('@vueuse/core')['createSharedComposable']>
readonly createTemplatePromise: UnwrapRef<typeof import('@vueuse/core')['createTemplatePromise']>
readonly createUnrefFn: UnwrapRef<typeof import('@vueuse/core')['createUnrefFn']>
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
readonly debouncedRef: UnwrapRef<typeof import('@vueuse/core')['debouncedRef']>
readonly debouncedWatch: UnwrapRef<typeof import('@vueuse/core')['debouncedWatch']>
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
readonly eagerComputed: UnwrapRef<typeof import('@vueuse/core')['eagerComputed']>
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
readonly extendRef: UnwrapRef<typeof import('@vueuse/core')['extendRef']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly h: UnwrapRef<typeof import('vue')['h']>
readonly ignorableWatch: UnwrapRef<typeof import('@vueuse/core')['ignorableWatch']>
readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly isDefined: UnwrapRef<typeof import('@vueuse/core')['isDefined']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly makeDestructurable: UnwrapRef<typeof import('@vueuse/core')['makeDestructurable']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
readonly onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']>
readonly onBeforeRouteUpdate: UnwrapRef<typeof import('vue-router')['onBeforeRouteUpdate']>
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
readonly onClickOutside: UnwrapRef<typeof import('@vueuse/core')['onClickOutside']>
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
readonly onKeyStroke: UnwrapRef<typeof import('@vueuse/core')['onKeyStroke']>
readonly onLongPress: UnwrapRef<typeof import('@vueuse/core')['onLongPress']>
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
readonly onStartTyping: UnwrapRef<typeof import('@vueuse/core')['onStartTyping']>
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
readonly pausableWatch: UnwrapRef<typeof import('@vueuse/core')['pausableWatch']>
readonly provide: UnwrapRef<typeof import('vue')['provide']>
readonly reactify: UnwrapRef<typeof import('@vueuse/core')['reactify']>
readonly reactifyObject: UnwrapRef<typeof import('@vueuse/core')['reactifyObject']>
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
readonly reactiveComputed: UnwrapRef<typeof import('@vueuse/core')['reactiveComputed']>
readonly reactiveOmit: UnwrapRef<typeof import('@vueuse/core')['reactiveOmit']>
readonly reactivePick: UnwrapRef<typeof import('@vueuse/core')['reactivePick']>
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly refAutoReset: UnwrapRef<typeof import('@vueuse/core')['refAutoReset']>
readonly refDebounced: UnwrapRef<typeof import('@vueuse/core')['refDebounced']>
readonly refDefault: UnwrapRef<typeof import('@vueuse/core')['refDefault']>
readonly refThrottled: UnwrapRef<typeof import('@vueuse/core')['refThrottled']>
readonly refWithControl: UnwrapRef<typeof import('@vueuse/core')['refWithControl']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly resolveRef: UnwrapRef<typeof import('@vueuse/core')['resolveRef']>
readonly resolveUnref: UnwrapRef<typeof import('@vueuse/core')['resolveUnref']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
readonly syncRef: UnwrapRef<typeof import('@vueuse/core')['syncRef']>
readonly syncRefs: UnwrapRef<typeof import('@vueuse/core')['syncRefs']>
readonly templateRef: UnwrapRef<typeof import('@vueuse/core')['templateRef']>
readonly throttledRef: UnwrapRef<typeof import('@vueuse/core')['throttledRef']>
readonly throttledWatch: UnwrapRef<typeof import('@vueuse/core')['throttledWatch']>
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
readonly toReactive: UnwrapRef<typeof import('@vueuse/core')['toReactive']>
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly tryOnBeforeMount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeMount']>
readonly tryOnBeforeUnmount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeUnmount']>
readonly tryOnMounted: UnwrapRef<typeof import('@vueuse/core')['tryOnMounted']>
readonly tryOnScopeDispose: UnwrapRef<typeof import('@vueuse/core')['tryOnScopeDispose']>
readonly tryOnUnmounted: UnwrapRef<typeof import('@vueuse/core')['tryOnUnmounted']>
readonly unref: UnwrapRef<typeof import('vue')['unref']>
readonly unrefElement: UnwrapRef<typeof import('@vueuse/core')['unrefElement']>
readonly until: UnwrapRef<typeof import('@vueuse/core')['until']>
readonly useActiveElement: UnwrapRef<typeof import('@vueuse/core')['useActiveElement']>
readonly useAnimate: UnwrapRef<typeof import('@vueuse/core')['useAnimate']>
readonly useArrayDifference: UnwrapRef<typeof import('@vueuse/core')['useArrayDifference']>
readonly useArrayEvery: UnwrapRef<typeof import('@vueuse/core')['useArrayEvery']>
readonly useArrayFilter: UnwrapRef<typeof import('@vueuse/core')['useArrayFilter']>
readonly useArrayFind: UnwrapRef<typeof import('@vueuse/core')['useArrayFind']>
readonly useArrayFindIndex: UnwrapRef<typeof import('@vueuse/core')['useArrayFindIndex']>
readonly useArrayFindLast: UnwrapRef<typeof import('@vueuse/core')['useArrayFindLast']>
readonly useArrayIncludes: UnwrapRef<typeof import('@vueuse/core')['useArrayIncludes']>
readonly useArrayJoin: UnwrapRef<typeof import('@vueuse/core')['useArrayJoin']>
readonly useArrayMap: UnwrapRef<typeof import('@vueuse/core')['useArrayMap']>
readonly useArrayReduce: UnwrapRef<typeof import('@vueuse/core')['useArrayReduce']>
readonly useArraySome: UnwrapRef<typeof import('@vueuse/core')['useArraySome']>
readonly useArrayUnique: UnwrapRef<typeof import('@vueuse/core')['useArrayUnique']>
readonly useAsyncQueue: UnwrapRef<typeof import('@vueuse/core')['useAsyncQueue']>
readonly useAsyncState: UnwrapRef<typeof import('@vueuse/core')['useAsyncState']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useBase64: UnwrapRef<typeof import('@vueuse/core')['useBase64']>
readonly useBattery: UnwrapRef<typeof import('@vueuse/core')['useBattery']>
readonly useBluetooth: UnwrapRef<typeof import('@vueuse/core')['useBluetooth']>
readonly useBreakpoints: UnwrapRef<typeof import('@vueuse/core')['useBreakpoints']>
readonly useBroadcastChannel: UnwrapRef<typeof import('@vueuse/core')['useBroadcastChannel']>
readonly useBrowserLocation: UnwrapRef<typeof import('@vueuse/core')['useBrowserLocation']>
readonly useCached: UnwrapRef<typeof import('@vueuse/core')['useCached']>
readonly useClipboard: UnwrapRef<typeof import('@vueuse/core')['useClipboard']>
readonly useCloned: UnwrapRef<typeof import('@vueuse/core')['useCloned']>
readonly useColorMode: UnwrapRef<typeof import('@vueuse/core')['useColorMode']>
readonly useConfirmDialog: UnwrapRef<typeof import('@vueuse/core')['useConfirmDialog']>
readonly useCounter: UnwrapRef<typeof import('@vueuse/core')['useCounter']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVar: UnwrapRef<typeof import('@vueuse/core')['useCssVar']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useCurrentElement: UnwrapRef<typeof import('@vueuse/core')['useCurrentElement']>
readonly useCycleList: UnwrapRef<typeof import('@vueuse/core')['useCycleList']>
readonly useDark: UnwrapRef<typeof import('@vueuse/core')['useDark']>
readonly useDateFormat: UnwrapRef<typeof import('@vueuse/core')['useDateFormat']>
readonly useDebounce: UnwrapRef<typeof import('@vueuse/core')['useDebounce']>
readonly useDebounceFn: UnwrapRef<typeof import('@vueuse/core')['useDebounceFn']>
readonly useDebouncedRefHistory: UnwrapRef<typeof import('@vueuse/core')['useDebouncedRefHistory']>
readonly useDeviceMotion: UnwrapRef<typeof import('@vueuse/core')['useDeviceMotion']>
readonly useDeviceOrientation: UnwrapRef<typeof import('@vueuse/core')['useDeviceOrientation']>
readonly useDevicePixelRatio: UnwrapRef<typeof import('@vueuse/core')['useDevicePixelRatio']>
readonly useDevicesList: UnwrapRef<typeof import('@vueuse/core')['useDevicesList']>
readonly useDialog: UnwrapRef<typeof import('naive-ui')['useDialog']>
readonly useDisplayMedia: UnwrapRef<typeof import('@vueuse/core')['useDisplayMedia']>
readonly useDocumentVisibility: UnwrapRef<typeof import('@vueuse/core')['useDocumentVisibility']>
readonly useDraggable: UnwrapRef<typeof import('@vueuse/core')['useDraggable']>
readonly useDropZone: UnwrapRef<typeof import('@vueuse/core')['useDropZone']>
readonly useElementBounding: UnwrapRef<typeof import('@vueuse/core')['useElementBounding']>
readonly useElementByPoint: UnwrapRef<typeof import('@vueuse/core')['useElementByPoint']>
readonly useElementHover: UnwrapRef<typeof import('@vueuse/core')['useElementHover']>
readonly useElementSize: UnwrapRef<typeof import('@vueuse/core')['useElementSize']>
readonly useElementVisibility: UnwrapRef<typeof import('@vueuse/core')['useElementVisibility']>
readonly useEventBus: UnwrapRef<typeof import('@vueuse/core')['useEventBus']>
readonly useEventListener: UnwrapRef<typeof import('@vueuse/core')['useEventListener']>
readonly useEventSource: UnwrapRef<typeof import('@vueuse/core')['useEventSource']>
readonly useEyeDropper: UnwrapRef<typeof import('@vueuse/core')['useEyeDropper']>
readonly useFavicon: UnwrapRef<typeof import('@vueuse/core')['useFavicon']>
readonly useFetch: UnwrapRef<typeof import('@vueuse/core')['useFetch']>
readonly useFileDialog: UnwrapRef<typeof import('@vueuse/core')['useFileDialog']>
readonly useFileSystemAccess: UnwrapRef<typeof import('@vueuse/core')['useFileSystemAccess']>
readonly useFocus: UnwrapRef<typeof import('@vueuse/core')['useFocus']>
readonly useFocusWithin: UnwrapRef<typeof import('@vueuse/core')['useFocusWithin']>
readonly useFps: UnwrapRef<typeof import('@vueuse/core')['useFps']>
readonly useFullscreen: UnwrapRef<typeof import('@vueuse/core')['useFullscreen']>
readonly useGamepad: UnwrapRef<typeof import('@vueuse/core')['useGamepad']>
readonly useGeolocation: UnwrapRef<typeof import('@vueuse/core')['useGeolocation']>
readonly useI18n: UnwrapRef<typeof import('vue-i18n')['useI18n']>
readonly useIdle: UnwrapRef<typeof import('@vueuse/core')['useIdle']>
readonly useImage: UnwrapRef<typeof import('@vueuse/core')['useImage']>
readonly useInfiniteScroll: UnwrapRef<typeof import('@vueuse/core')['useInfiniteScroll']>
readonly useIntersectionObserver: UnwrapRef<typeof import('@vueuse/core')['useIntersectionObserver']>
readonly useInterval: UnwrapRef<typeof import('@vueuse/core')['useInterval']>
readonly useIntervalFn: UnwrapRef<typeof import('@vueuse/core')['useIntervalFn']>
readonly useKeyModifier: UnwrapRef<typeof import('@vueuse/core')['useKeyModifier']>
readonly useLastChanged: UnwrapRef<typeof import('@vueuse/core')['useLastChanged']>
readonly useLink: UnwrapRef<typeof import('vue-router')['useLink']>
readonly useLoadingBar: UnwrapRef<typeof import('naive-ui')['useLoadingBar']>
readonly useLocalStorage: UnwrapRef<typeof import('@vueuse/core')['useLocalStorage']>
readonly useMagicKeys: UnwrapRef<typeof import('@vueuse/core')['useMagicKeys']>
readonly useManualRefHistory: UnwrapRef<typeof import('@vueuse/core')['useManualRefHistory']>
readonly useMediaControls: UnwrapRef<typeof import('@vueuse/core')['useMediaControls']>
readonly useMediaQuery: UnwrapRef<typeof import('@vueuse/core')['useMediaQuery']>
readonly useMemoize: UnwrapRef<typeof import('@vueuse/core')['useMemoize']>
readonly useMemory: UnwrapRef<typeof import('@vueuse/core')['useMemory']>
readonly useMessage: UnwrapRef<typeof import('naive-ui')['useMessage']>
readonly useMounted: UnwrapRef<typeof import('@vueuse/core')['useMounted']>
readonly useMouse: UnwrapRef<typeof import('@vueuse/core')['useMouse']>
readonly useMouseInElement: UnwrapRef<typeof import('@vueuse/core')['useMouseInElement']>
readonly useMousePressed: UnwrapRef<typeof import('@vueuse/core')['useMousePressed']>
readonly useMutationObserver: UnwrapRef<typeof import('@vueuse/core')['useMutationObserver']>
readonly useNavigatorLanguage: UnwrapRef<typeof import('@vueuse/core')['useNavigatorLanguage']>
readonly useNetwork: UnwrapRef<typeof import('@vueuse/core')['useNetwork']>
readonly useNotification: UnwrapRef<typeof import('naive-ui')['useNotification']>
readonly useNow: UnwrapRef<typeof import('@vueuse/core')['useNow']>
readonly useObjectUrl: UnwrapRef<typeof import('@vueuse/core')['useObjectUrl']>
readonly useOffsetPagination: UnwrapRef<typeof import('@vueuse/core')['useOffsetPagination']>
readonly useOnline: UnwrapRef<typeof import('@vueuse/core')['useOnline']>
readonly usePageLeave: UnwrapRef<typeof import('@vueuse/core')['usePageLeave']>
readonly useParallax: UnwrapRef<typeof import('@vueuse/core')['useParallax']>
readonly useParentElement: UnwrapRef<typeof import('@vueuse/core')['useParentElement']>
readonly usePerformanceObserver: UnwrapRef<typeof import('@vueuse/core')['usePerformanceObserver']>
readonly usePermission: UnwrapRef<typeof import('@vueuse/core')['usePermission']>
readonly usePointer: UnwrapRef<typeof import('@vueuse/core')['usePointer']>
readonly usePointerLock: UnwrapRef<typeof import('@vueuse/core')['usePointerLock']>
readonly usePointerSwipe: UnwrapRef<typeof import('@vueuse/core')['usePointerSwipe']>
readonly usePreferredColorScheme: UnwrapRef<typeof import('@vueuse/core')['usePreferredColorScheme']>
readonly usePreferredContrast: UnwrapRef<typeof import('@vueuse/core')['usePreferredContrast']>
readonly usePreferredDark: UnwrapRef<typeof import('@vueuse/core')['usePreferredDark']>
readonly usePreferredLanguages: UnwrapRef<typeof import('@vueuse/core')['usePreferredLanguages']>
readonly usePreferredReducedMotion: UnwrapRef<typeof import('@vueuse/core')['usePreferredReducedMotion']>
readonly usePrevious: UnwrapRef<typeof import('@vueuse/core')['usePrevious']>
readonly useRafFn: UnwrapRef<typeof import('@vueuse/core')['useRafFn']>
readonly useRefHistory: UnwrapRef<typeof import('@vueuse/core')['useRefHistory']>
readonly useResizeObserver: UnwrapRef<typeof import('@vueuse/core')['useResizeObserver']>
readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>
readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']>
readonly useScreenOrientation: UnwrapRef<typeof import('@vueuse/core')['useScreenOrientation']>
readonly useScreenSafeArea: UnwrapRef<typeof import('@vueuse/core')['useScreenSafeArea']>
readonly useScriptTag: UnwrapRef<typeof import('@vueuse/core')['useScriptTag']>
readonly useScroll: UnwrapRef<typeof import('@vueuse/core')['useScroll']>
readonly useScrollLock: UnwrapRef<typeof import('@vueuse/core')['useScrollLock']>
readonly useSessionStorage: UnwrapRef<typeof import('@vueuse/core')['useSessionStorage']>
readonly useShare: UnwrapRef<typeof import('@vueuse/core')['useShare']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly useSorted: UnwrapRef<typeof import('@vueuse/core')['useSorted']>
readonly useSpeechRecognition: UnwrapRef<typeof import('@vueuse/core')['useSpeechRecognition']>
readonly useSpeechSynthesis: UnwrapRef<typeof import('@vueuse/core')['useSpeechSynthesis']>
readonly useStepper: UnwrapRef<typeof import('@vueuse/core')['useStepper']>
readonly useStorage: UnwrapRef<typeof import('@vueuse/core')['useStorage']>
readonly useStorageAsync: UnwrapRef<typeof import('@vueuse/core')['useStorageAsync']>
readonly useStyleTag: UnwrapRef<typeof import('@vueuse/core')['useStyleTag']>
readonly useSupported: UnwrapRef<typeof import('@vueuse/core')['useSupported']>
readonly useSwipe: UnwrapRef<typeof import('@vueuse/core')['useSwipe']>
readonly useTemplateRefsList: UnwrapRef<typeof import('@vueuse/core')['useTemplateRefsList']>
readonly useTextDirection: UnwrapRef<typeof import('@vueuse/core')['useTextDirection']>
readonly useTextSelection: UnwrapRef<typeof import('@vueuse/core')['useTextSelection']>
readonly useTextareaAutosize: UnwrapRef<typeof import('@vueuse/core')['useTextareaAutosize']>
readonly useThrottle: UnwrapRef<typeof import('@vueuse/core')['useThrottle']>
readonly useThrottleFn: UnwrapRef<typeof import('@vueuse/core')['useThrottleFn']>
readonly useThrottledRefHistory: UnwrapRef<typeof import('@vueuse/core')['useThrottledRefHistory']>
readonly useTimeAgo: UnwrapRef<typeof import('@vueuse/core')['useTimeAgo']>
readonly useTimeout: UnwrapRef<typeof import('@vueuse/core')['useTimeout']>
readonly useTimeoutFn: UnwrapRef<typeof import('@vueuse/core')['useTimeoutFn']>
readonly useTimeoutPoll: UnwrapRef<typeof import('@vueuse/core')['useTimeoutPoll']>
readonly useTimestamp: UnwrapRef<typeof import('@vueuse/core')['useTimestamp']>
readonly useTitle: UnwrapRef<typeof import('@vueuse/core')['useTitle']>
readonly useToNumber: UnwrapRef<typeof import('@vueuse/core')['useToNumber']>
readonly useToString: UnwrapRef<typeof import('@vueuse/core')['useToString']>
readonly useToggle: UnwrapRef<typeof import('@vueuse/core')['useToggle']>
readonly useTransition: UnwrapRef<typeof import('@vueuse/core')['useTransition']>
readonly useUrlSearchParams: UnwrapRef<typeof import('@vueuse/core')['useUrlSearchParams']>
readonly useUserMedia: UnwrapRef<typeof import('@vueuse/core')['useUserMedia']>
readonly useVModel: UnwrapRef<typeof import('@vueuse/core')['useVModel']>
readonly useVModels: UnwrapRef<typeof import('@vueuse/core')['useVModels']>
readonly useVibrate: UnwrapRef<typeof import('@vueuse/core')['useVibrate']>
readonly useVirtualList: UnwrapRef<typeof import('@vueuse/core')['useVirtualList']>
readonly useWakeLock: UnwrapRef<typeof import('@vueuse/core')['useWakeLock']>
readonly useWebNotification: UnwrapRef<typeof import('@vueuse/core')['useWebNotification']>
readonly useWebSocket: UnwrapRef<typeof import('@vueuse/core')['useWebSocket']>
readonly useWebWorker: UnwrapRef<typeof import('@vueuse/core')['useWebWorker']>
readonly useWebWorkerFn: UnwrapRef<typeof import('@vueuse/core')['useWebWorkerFn']>
readonly useWindowFocus: UnwrapRef<typeof import('@vueuse/core')['useWindowFocus']>
readonly useWindowScroll: UnwrapRef<typeof import('@vueuse/core')['useWindowScroll']>
readonly useWindowSize: UnwrapRef<typeof import('@vueuse/core')['useWindowSize']>
readonly watch: UnwrapRef<typeof import('vue')['watch']>
readonly watchArray: UnwrapRef<typeof import('@vueuse/core')['watchArray']>
readonly watchAtMost: UnwrapRef<typeof import('@vueuse/core')['watchAtMost']>
readonly watchDebounced: UnwrapRef<typeof import('@vueuse/core')['watchDebounced']>
readonly watchDeep: UnwrapRef<typeof import('@vueuse/core')['watchDeep']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchIgnorable: UnwrapRef<typeof import('@vueuse/core')['watchIgnorable']>
readonly watchImmediate: UnwrapRef<typeof import('@vueuse/core')['watchImmediate']>
readonly watchOnce: UnwrapRef<typeof import('@vueuse/core')['watchOnce']>
readonly watchPausable: UnwrapRef<typeof import('@vueuse/core')['watchPausable']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>

192
components.d.ts vendored
View file

@ -9,65 +9,187 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
'404.page': typeof import('./src/pages/404.page.vue')['default']
About: typeof import('./src/pages/About.vue')['default']
App: typeof import('./src/App.vue')['default']
AsciiTextDrawer: typeof import('./src/tools/ascii-text-drawer/ascii-text-drawer.vue')['default']
'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
Base64StringConverter: typeof import('./src/tools/base64-string-converter/base64-string-converter.vue')['default']
BasicAuthGenerator: typeof import('./src/tools/basic-auth-generator/basic-auth-generator.vue')['default']
Bcrypt: typeof import('./src/tools/bcrypt/bcrypt.vue')['default']
BenchmarkBuilder: typeof import('./src/tools/benchmark-builder/benchmark-builder.vue')['default']
Bip39Generator: typeof import('./src/tools/bip39-generator/bip39-generator.vue')['default']
CAlert: typeof import('./src/ui/c-alert/c-alert.vue')['default']
'CAlert.demo': typeof import('./src/ui/c-alert/c-alert.demo.vue')['default']
CameraRecorder: typeof import('./src/tools/camera-recorder/camera-recorder.vue')['default']
CaseConverter: typeof import('./src/tools/case-converter/case-converter.vue')['default']
CButton: typeof import('./src/ui/c-button/c-button.vue')['default']
'CButton.demo': typeof import('./src/ui/c-button/c-button.demo.vue')['default']
CButtonsSelect: typeof import('./src/ui/c-buttons-select/c-buttons-select.vue')['default']
'CButtonsSelect.demo': typeof import('./src/ui/c-buttons-select/c-buttons-select.demo.vue')['default']
CCard: typeof import('./src/ui/c-card/c-card.vue')['default']
'CCard.demo': typeof import('./src/ui/c-card/c-card.demo.vue')['default']
CCollapse: typeof import('./src/ui/c-collapse/c-collapse.vue')['default']
'CCollapse.demo': typeof import('./src/ui/c-collapse/c-collapse.demo.vue')['default']
CDiffEditor: typeof import('./src/ui/c-diff-editor/c-diff-editor.vue')['default']
CFileUpload: typeof import('./src/ui/c-file-upload/c-file-upload.vue')['default']
'CFileUpload.demo': typeof import('./src/ui/c-file-upload/c-file-upload.demo.vue')['default']
ChmodCalculator: typeof import('./src/tools/chmod-calculator/chmod-calculator.vue')['default']
Chronometer: typeof import('./src/tools/chronometer/chronometer.vue')['default']
CInputText: typeof import('./src/ui/c-input-text/c-input-text.vue')['default']
'CInputText.demo': typeof import('./src/ui/c-input-text/c-input-text.demo.vue')['default']
CKeyValueList: typeof import('./src/ui/c-key-value-list/c-key-value-list.vue')['default']
CKeyValueListItem: typeof import('./src/ui/c-key-value-list/c-key-value-list-item.vue')['default']
CLabel: typeof import('./src/ui/c-label/c-label.vue')['default']
CLink: typeof import('./src/ui/c-link/c-link.vue')['default']
'CLink.demo': typeof import('./src/ui/c-link/c-link.demo.vue')['default']
CMarkdown: typeof import('./src/ui/c-markdown/c-markdown.vue')['default']
'CMarkdown.demo': typeof import('./src/ui/c-markdown/c-markdown.demo.vue')['default']
CModal: typeof import('./src/ui/c-modal/c-modal.vue')['default']
'CModal.demo': typeof import('./src/ui/c-modal/c-modal.demo.vue')['default']
CModalValue: typeof import('./src/ui/c-modal-value/c-modal-value.vue')['default']
'CModalValue.demo': typeof import('./src/ui/c-modal-value/c-modal-value.demo.vue')['default']
CollapsibleToolMenu: typeof import('./src/components/CollapsibleToolMenu.vue')['default']
ColorConverter: typeof import('./src/tools/color-converter/color-converter.vue')['default']
ColoredCard: typeof import('./src/components/ColoredCard.vue')['default']
CommandPalette: typeof import('./src/modules/command-palette/command-palette.vue')['default']
CommandPaletteOption: typeof import('./src/modules/command-palette/components/command-palette-option.vue')['default']
CrontabGenerator: typeof import('./src/tools/crontab-generator/crontab-generator.vue')['default']
CSelect: typeof import('./src/ui/c-select/c-select.vue')['default']
'CSelect.demo': typeof import('./src/ui/c-select/c-select.demo.vue')['default']
CTable: typeof import('./src/ui/c-table/c-table.vue')['default']
'CTable.demo': typeof import('./src/ui/c-table/c-table.demo.vue')['default']
CTextCopyable: typeof import('./src/ui/c-text-copyable/c-text-copyable.vue')['default']
'CTextCopyable.demo': typeof import('./src/ui/c-text-copyable/c-text-copyable.demo.vue')['default']
CTooltip: typeof import('./src/ui/c-tooltip/c-tooltip.vue')['default']
'CTooltip.demo': typeof import('./src/ui/c-tooltip/c-tooltip.demo.vue')['default']
DateTimeConverter: typeof import('./src/tools/date-time-converter/date-time-converter.vue')['default']
'DemoHome.page': typeof import('./src/ui/demo/demo-home.page.vue')['default']
DemoWrapper: typeof import('./src/ui/demo/demo-wrapper.vue')['default']
DeviceInformation: typeof import('./src/tools/device-information/device-information.vue')['default']
DiffViewer: typeof import('./src/tools/json-diff/diff-viewer/diff-viewer.vue')['default']
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']
Encryption: typeof import('./src/tools/encryption/encryption.vue')['default']
EtaCalculator: typeof import('./src/tools/eta-calculator/eta-calculator.vue')['default']
FavoriteButton: typeof import('./src/components/FavoriteButton.vue')['default']
FormatTransformer: typeof import('./src/components/FormatTransformer.vue')['default']
GitMemo: typeof import('./src/tools/git-memo/git-memo.vue')['default']
'GitMemo.content': typeof import('./src/tools/git-memo/git-memo.content.md')['default']
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']
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']
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
IconMdiClose: typeof import('~icons/mdi/close')['default']
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
IconMdiEye: typeof import('~icons/mdi/eye')['default']
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
IconMdiSearch: typeof import('~icons/mdi/search')['default']
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default']
Ipv4SubnetCalculator: typeof import('./src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue')['default']
Ipv6UlaGenerator: typeof import('./src/tools/ipv6-ula-generator/ipv6-ula-generator.vue')['default']
JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default']
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']
KeycodeInfo: typeof import('./src/tools/keycode-info/keycode-info.vue')['default']
ListConverter: typeof import('./src/tools/list-converter/list-converter.vue')['default']
LocaleSelector: typeof import('./src/modules/i18n/components/locale-selector.vue')['default']
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']
MenuIconItem: typeof import('./src/components/MenuIconItem.vue')['default']
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
NAlert: typeof import('naive-ui')['NAlert']
NAutoComplete: typeof import('naive-ui')['NAutoComplete']
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']
NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard']
NCheckbox: typeof import('naive-ui')['NCheckbox']
NCode: typeof import('naive-ui')['NCode']
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
NColorPicker: typeof import('naive-ui')['NColorPicker']
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDatePicker: typeof import('naive-ui')['NDatePicker']
NDivider: typeof import('naive-ui')['NDivider']
NDynamicInput: typeof import('naive-ui')['NDynamicInput']
NEllipsis: typeof import('naive-ui')['NEllipsis']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid']
NH1: typeof import('naive-ui')['NH1']
NH2: typeof import('naive-ui')['NH2']
NH3: typeof import('naive-ui')['NH3']
NH4: typeof import('naive-ui')['NH4']
NIcon: typeof import('naive-ui')['NIcon']
NImage: typeof import('naive-ui')['NImage']
NInput: typeof import('naive-ui')['NInput']
NInputGroup: typeof import('naive-ui')['NInputGroup']
NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel']
NInputNumber: typeof import('naive-ui')['NInputNumber']
NLayout: typeof import('naive-ui')['NLayout']
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
NMenu: typeof import('naive-ui')['NMenu']
NP: typeof import('naive-ui')['NP']
NPageHeader: typeof import('naive-ui')['NPageHeader']
NProgress: typeof import('naive-ui')['NProgress']
NResult: typeof import('naive-ui')['NResult']
NScrollbar: typeof import('naive-ui')['NScrollbar']
NSelect: typeof import('naive-ui')['NSelect']
NSlider: typeof import('naive-ui')['NSlider']
NSpace: typeof import('naive-ui')['NSpace']
NStatistic: typeof import('naive-ui')['NStatistic']
NSwitch: typeof import('naive-ui')['NSwitch']
NTable: typeof import('naive-ui')['NTable']
NTag: typeof import('naive-ui')['NTag']
NText: typeof import('naive-ui')['NText']
NTooltip: typeof import('naive-ui')['NTooltip']
NUpload: typeof import('naive-ui')['NUpload']
NUploadDragger: typeof import('naive-ui')['NUploadDragger']
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']
PdfSignatureChecker: typeof import('./src/tools/pdf-signature-checker/pdf-signature-checker.vue')['default']
PdfSignatureDetails: typeof import('./src/tools/pdf-signature-checker/components/pdf-signature-details.vue')['default']
PercentageCalculator: typeof import('./src/tools/percentage-calculator/percentage-calculator.vue')['default']
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']
SearchBar: typeof import('./src/components/SearchBar.vue')['default']
SearchBarItem: typeof import('./src/components/SearchBarItem.vue')['default']
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']
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']
StringObfuscator: typeof import('./src/tools/string-obfuscator/string-obfuscator.vue')['default']
SvgPlaceholderGenerator: typeof import('./src/tools/svg-placeholder-generator/svg-placeholder-generator.vue')['default']
TemperatureConverter: typeof import('./src/tools/temperature-converter/temperature-converter.vue')['default']
TextareaCopyable: typeof import('./src/components/TextareaCopyable.vue')['default']
TextDiff: typeof import('./src/tools/text-diff/text-diff.vue')['default']
TextStatistics: typeof import('./src/tools/text-statistics/text-statistics.vue')['default']
TextToBinary: typeof import('./src/tools/text-to-binary/text-to-binary.vue')['default']
TextToNatoAlphabet: typeof import('./src/tools/text-to-nato-alphabet/text-to-nato-alphabet.vue')['default']
TextToUnicode: typeof import('./src/tools/text-to-unicode/text-to-unicode.vue')['default']
TokenDisplay: typeof import('./src/tools/otp-code-generator-and-validator/token-display.vue')['default']
'TokenGenerator.tool': typeof import('./src/tools/token-generator/token-generator.tool.vue')['default']
TomlToJson: typeof import('./src/tools/toml-to-json/toml-to-json.vue')['default']
TomlToYaml: typeof import('./src/tools/toml-to-yaml/toml-to-yaml.vue')['default']
'Tool.layout': typeof import('./src/layouts/tool.layout.vue')['default']
ToolCard: typeof import('./src/components/ToolCard.vue')['default']
UlidGenerator: typeof import('./src/tools/ulid-generator/ulid-generator.vue')['default']
UrlEncoder: typeof import('./src/tools/url-encoder/url-encoder.vue')['default']
UrlParser: typeof import('./src/tools/url-parser/url-parser.vue')['default']
UserAgentParser: typeof import('./src/tools/user-agent-parser/user-agent-parser.vue')['default']
UserAgentResultCards: typeof import('./src/tools/user-agent-parser/user-agent-result-cards.vue')['default']
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']
}
}

View file

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<link rel="icon" href="favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>IT Tools - Handy online tools for developers</title>
<meta itemprop="name" content="IT Tools - Handy online tools for developers" />
@ -14,13 +14,13 @@
itemprop="description"
content="Collection of handy online tools for developers, with great UX. IT Tools is a free and open-source collection of handy online tools for developers & people working in IT."
/>
<link rel="author" href="/humans.txt" />
<link rel="author" href="humans.txt" />
<link rel="canonical" href="https://it-tools.tech" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#18a058" />
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png" />
<link rel="mask-icon" href="safari-pinned-tab.svg" color="#18a058" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />

456
locales/de.yml Normal file
View 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.

394
locales/en.yml Normal file
View file

@ -0,0 +1,394 @@
home:
categories:
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'
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'
twitterXAccount: 'IT-Tools X account'
thankYou: 'Thank you!'
nav:
github: 'GitHub repository'
githubRepository: 'IT-Tools GitHub repository'
twitterX: 'X account'
twitterXAccount: 'IT Tools X account'
about: 'About IT-Tools'
aboutLabel: 'About'
darkMode: 'Dark mode'
lightMode: 'Light mode'
mode: 'Toggle dark/light mode'
about:
content: >
# About IT-Tools
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 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
IT Tools is made in Vue.js (Vue 3) with the the Naive UI component library and is hosted and continuously deployed by Vercel. Third-party open-source libraries are used in some tools, you may find the complete list in the [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json) file of the repository.
## Found a bug? A tool is missing?
If you need a tool that is currently not present here, and you think can be useful, you are welcome to submit a feature request in the [issues section](https://github.com/CorentinTh/it-tools/issues/new/choose) in the GitHub repository.
And if you found a bug, or something doesn't work as expected, please file a bug report in the [issues section](https://github.com/CorentinTh/it-tools/issues/new/choose) in the GitHub repository.
404:
notFound: '404 Not Found'
sorry: 'Sorry, this page does not seem to exist'
maybe: 'Maybe the cache is doing tricky things, try force-refreshing?'
backHome: 'Back home'
favoriteButton:
remove: 'Remove from favorites'
add: 'Add to favorites'
toolCard:
new: New
search:
label: Search
tools:
categories:
favorite-tools: 'Your favorite tools'
crypto: Crypto
converter: Converter
web: Web
images and videos: 'Images & Videos'
development: Development
network: Network
math: Math
measurement: Measurement
text: Text
data: Data
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.
chronometer:
title: Chronometer
description: Monitor the duration of a thing. Basically a chronometer with simple chronometer features.
token-generator:
title: Token generator
description: Generate random string with the chars you want, uppercase or lowercase letters, numbers and/or symbols.
uppercase: Uppercase (ABC...)
lowercase: Lowercase (abc...)
numbers: Numbers (123...)
symbols: Symbols (!-;...)
length: Length
tokenPlaceholder: 'The token...'
copied: Token copied to the clipboard
button:
copy: Copy
refresh: Refresh
percentage-calculator:
title: Percentage calculator
description: Easily calculate percentages from a value to another value, or from a percentage to a value.
svg-placeholder-generator:
title: SVG placeholder generator
description: Generate svg images to use as a placeholder in your applications.
json-to-csv:
title: JSON to CSV
description: Convert JSON to CSV with automatic header detection.
camera-recorder:
title: Camera recorder
description: Take a picture or record a video from your webcam or camera.
keycode-info:
title: Keycode info
description: Find the javascript keycode, code, location and modifiers of any pressed key.
emoji-picker:
title: Emoji picker
description: Copy and paste emojis easily and get the unicode and code points value of each emoji.
color-converter:
title: Color converter
description: Convert color between the different formats (hex, rgb, hsl and css name)
bcrypt:
title: Bcrypt
description: Hash and compare text string using bcrypt. Bcrypt is a password-hashing function based on the Blowfish cipher.
crontab-generator:
title: Crontab generator
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.
sql-prettify:
title: SQL prettify and format
description: Format and prettify your SQL queries online (it supports various SQL dialects).
benchmark-builder:
title: Benchmark builder
description: Easily compare execution time of tasks with this very simple online benchmark builder.
git-memo:
title: Git cheatsheet
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
description: Make a string url, filename and id safe.
encryption:
title: Encrypt / decrypt text
description: Encrypt clear text and decrypt ciphertext using crypto algorithms like AES, TripleDES, Rabbit or RC4.
random-port-generator:
title: Random port generator
description: Generate random port numbers outside of the range of "known" ports (0-1023).
yaml-prettify:
title: YAML prettify and 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 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
description: Convert Roman numerals to numbers and convert numbers to Roman numerals.
hmac-generator:
title: Hmac generator
description: Computes a hash-based message authentication code (HMAC) using a secret key and your favorite hashing function.
bip39-generator:
title: BIP39 passphrase generator
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 a string, file, or image into its base64 representation.
list-converter:
title: List converter
description: This tool can process column-based data and apply various changes (transpose, add prefix and suffix, reverse list, sort list, lowercase values, truncate values) to each row.
base64-string-converter:
title: Base64 string encoder/decoder
description: Simply encode and decode strings into their base64 representation.
toml-to-yaml:
title: TOML to YAML
description: Parse and convert TOML to YAML.
math-evaluator:
title: Math evaluator
description: A calculator for evaluating mathematical expressions. You can use functions like sqrt, cos, sin, abs, etc.
json-to-yaml-converter:
title: JSON to YAML converter
description: Simply convert JSON to YAML with this online live converter.
url-parser:
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 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
description: Detect and parse Browser, Engine, OS, CPU, and Device type/model from an user-agent string.
numeronym-generator:
title: Numeronym generator
description: A numeronym is a word where a number is used to form an abbreviation. For example, "i18n" is a numeronym of "internationalization" where 18 stands for the number of letters between the first i and the last n in the word.
case-converter:
title: Case converter
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 characters like <,>, &, " and \' with their HTML version)
json-prettify:
title: JSON prettify and 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: 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 file extensions and vice-versa.
toml-to-json:
title: TOML to JSON
description: Parse and convert TOML to JSON.
lorem-ipsum-generator:
title: Lorem ipsum generator
description: Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content
qrcode-generator:
title: QR Code generator
description: Generate and download a QR code for a URL (or just plain text), and customize the background and foreground colors.
wifi-qrcode-generator:
title: WiFi QR Code generator
description: Generate and download QR codes for quick connections to WiFi networks.
xml-formatter:
title: XML formatter
description: Prettify your XML string into a friendly, human-readable format.
temperature-converter:
title: Temperature converter
description: Degrees temperature conversions for Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur, and Rømer.
chmod-calculator:
title: Chmod calculator
description: Compute your chmod permissions and commands with this online chmod calculator.
rsa-key-pair-generator:
title: RSA key pair generator
description: Generate a new random RSA private and public pem certificate key pair.
html-wysiwyg-editor:
title: HTML WYSIWYG editor
description: Online, feature-rich WYSIWYG HTML editor which generates the source code of the content immediately.
yaml-to-toml:
title: YAML to TOML
description: Parse and convert YAML to TOML.
mac-address-generator:
title: MAC address generator
description: Enter the quantity and prefix. MAC addresses will be generated in your chosen case (uppercase or lowercase)
json-diff:
title: JSON diff
description: Compare two JSON objects and get the differences between them.
jwt-parser:
title: JWT parser
description: Parse and decode your JSON Web Token (jwt) and display its content.
date-converter:
title: Date-time converter
description: Convert date and time into the various different formats
phone-parser-and-formatter:
title: Phone parser and formatter
description: Parse, validate and format phone numbers. Get information about the phone number, like the country code, type, etc.
ipv4-subnet-calculator:
title: IPv4 subnet calculator
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.
ipv6-ula-generator:
title: IPv6 ULA generator
description: Generate your own local, non-routable IP addresses for your network according to RFC4193.
hash-text:
title: Hash text
description: 'Hash a text string using the function you need : MD5, SHA1, SHA256, SHA224, SHA512, SHA384, SHA3 or RIPEMD160'
json-to-toml:
title: JSON to TOML
description: Parse and convert JSON to TOML.
device-information:
title: Device information
description: Get information about your current device (screen size, pixel-ratio, user agent, ...)
pdf-signature-checker:
title: PDF signature checker
description: Verify the signatures of a PDF file. A signed PDF file contains one or more signatures that may be used to determine whether the contents of the file have been altered since the file was signed.
json-minify:
title: JSON minify
description: Minify and compress your JSON by removing unnecessary whitespace.
ulid-generator:
title: ULID generator
description: Generate random Universally Unique Lexicographically Sortable Identifier (ULID).
string-obfuscator:
title: String obfuscator
description: Obfuscate a string (like a secret, an IBAN, or a token) to make it shareable and identifiable without revealing its content.
base-converter:
title: Integer base converter
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 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 even an IPv6 representation of it.
text-statistics:
title: Text statistics
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 the NATO phonetic alphabet for oral transmission.
basic-auth-generator:
title: Basic auth generator
description: Generate a base64 basic auth header from a username and password.
text-to-unicode:
title: Text to Unicode
description: Parse and convert text to unicode and vice-versa
ipv4-range-expander:
title: IPv4 range expander
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
description: Compare two texts and see the differences between them.
otp-generator:
title: OTP code generator
description: Generate and validate time-based OTP (one time password) for multi-factor authentication.
url-encoder:
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.

72
locales/es.yml Normal file
View file

@ -0,0 +1,72 @@
home:
categories:
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
uiLib: 'UI Lib'
support: 'Apoyar el desarrollo de IT-Tools'
buyMeACoffee: 'Buy me a coffee'
follow:
title: 'Te gustan las it-tools?'
p1: 'Danos una estrella en'
githubRepository: 'Repositorio de IT-Tools en GitHub'
p2: 'o síguenos en'
twitterXAccount: 'Cuenta de X de IT-Tools'
thankYou: 'Muchas gracias!'
nav:
github: 'Repositorio en github'
githubRepository: 'IT-Tools GitHub repository'
twitterX: 'Cuenta de X'
twitterXAccount: 'Cuenta de X de IT Tools'
about: 'Sobre IT-Tools'
aboutLabel: 'Sobre'
darkMode: 'Modo obscuro'
lightMode: 'Modo claro'
mode: 'Alternar modo oscuro/claro'
about:
content: >
# Sobre IT-Tools
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 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
IT Tools está creado en Vue.js (Vue 3) con la biblioteca de componentes Naive UI y Vercel lo aloja y lo implementa continuamente. En algunas herramientas se utilizan bibliotecas de código abierto de terceros; puede encontrar la lista completa en [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json) archivo del repositorio.
## ¿Encontraste un error? ¿Falta una herramienta?
Si necesita una herramienta que actualmente no está presente aquí y cree que puede ser útil, puede enviar una solicitud de función en el [issues section](https://github.com/CorentinTh/it-tools/issues/new/choose) en el repositorio de GitHub.
Y si encontró un error o algo no funciona como se esperaba, presente un reporte de error en el [issues section](https://github.com/CorentinTh/it-tools/issues/new/choose) en el repositorio de GitHub.
404:
notFound: '404 Not Found'
sorry: 'Lo sentimos, esta página no parece existir'
maybe: 'Tal vez el caché esté haciendo cosas raras, ¿probamos a refrescar forzosamente?'
backHome: 'Back home'
favoriteButton:
remove: 'Quitar de favoritos'
add: 'Añadir a favoritos'
toolCard:
new: Nuevo
search:
label: Buscar
tools:
categories:
favorite-tools: 'Tus herramientas favoritas'
crypto: Crypto
converter: Converter
web: Web
images and videos: 'Images & Videos'
development: Development
network: Network
math: Math
measurement: Measurement
text: Text
data: Data

82
locales/fr.yml Normal file
View file

@ -0,0 +1,82 @@
home:
categories:
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
uiLib: 'UI Lib'
buyMeACoffee: 'Soutenez IT-Tools'
follow:
title: 'Vous aimez it-tools ?'
p1: 'Soutenez-nous avec une star sur'
githubRepository: "le dépôt GitHub d'IT-Tools"
p2: 'ou suivez-nous sur'
twitterXAccount: "le compte X d'IT-Tools"
thankYou: 'Merci !'
nav:
github: 'Dépôt GitHub'
githubRepository: "Dépôt GitHub d'IT-Tools"
twitterX: 'Compte X'
twitterXAccount: "Compte X d'IT-Tools"
about: "À propos d'IT-Tools"
aboutLabel: 'À propos'
darkMode: 'Mode sombre'
lightMode: 'Mode clair'
mode: 'Basculer le mode sombre/clair'
about:
content: >
# À propos de IT-Tools
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 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
IT Tools est fait en Vue.js (Vue 3) avec la bibliothèque de composants Naive UI et est hébergé et déployé en continu par Vercel. Des bibliothèques open-source tierces sont utilisées dans certains outils, vous pouvez trouver la liste complète dans le fichier [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json) du dépôt.
## Vous avez trouvé un bug ? Un outil manque ?
Si vous avez besoin d'un outil qui n'est pas encore présent ici, et que vous pensez qu'il peut être utile, vous êtes invité à soumettre une demande de fonctionnalité dans la [section issue](https://github.com/CorentinTh/it-tools/issues/new/choose) du dépôt GitHub.
404:
notFound: '404 Not Found'
sorry: "Désolé, cette page n'existe pas"
maybe: 'Peut-être que le cache fait des siennes, essayez de forcer le rafraîchissement ?'
backHome: "Retour à l'accueil"
toolCard:
new: Nouveau
search:
label: Rechercher
tools:
categories:
favorite-tools: 'Vos outils favoris'
crypto: Cryptographie
converter: Convertisseur
web: Web
images and videos: 'Images & Vidéos'
development: Développement
network: Réseau
math: Math
measurement: Mesure
text: Texte
data: Données
token-generator:
title: Générateur de token
description: >-
Génère une chaîne aléatoire avec les caractères que vous voulez, lettres
majuscules ou minuscules, chiffres et/ou symboles.
uppercase: Majuscules (ABC...)
lowercase: Minuscules (abc...)
numbers: Chiffres (123...)
symbols: Symboles (!-;...)
button:
copy: Copier
refresh: Rafraichir
copied: Le token a été copié
length: Longueur
tokenPlaceholder: Le token...

394
locales/no.yml Normal file
View 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.

72
locales/pt.yml Normal file
View file

@ -0,0 +1,72 @@
home:
categories:
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'
uiLib: 'Biblioteca de UI'
support: 'Apoie o desenvolvimento do IT Tools'
buyMeACoffee: 'Pague-me um café'
follow:
title: 'Gostou do it-tools?'
p1: 'Dê uma estrela no'
githubRepository: 'repositório do IT-Tools no GitHub'
p2: 'ou siga nossa'
twitterXAccount: 'conta IT-Tools no X'
thankYou: 'Obrigado !'
nav:
github: 'Repositório no GitHub'
githubRepository: 'repositório do IT-Tools no GitHub'
twitterX: 'Conta no X'
twitterXAccount: 'conta do IT Tools no X'
about: 'Sobre o IT-Tools'
aboutLabel: 'Sobre'
darkMode: 'Modo Escuro'
lightMode: 'Modo Claro'
mode: 'Trocar modo escuro/claro'
about:
content: >
# Sobre o IT-Tools
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 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
O IT Tools é feito em Vue.js (Vue 3) com a biblioteca de componentes Naive UI e é hospedado pela Vercel. Bibliotecas de código aberto de terceiros são usadas em algumas ferramentas e você pode encontrar a lista completa no arquivo [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json) do repositório.
## Achou um bug? Está faltando uma ferramenta?
Se você precisa de uma ferramenta que ainda não existe aqui e acha que pode ser útil, seu pedido será bem vindo na [seção de issues](https://github.com/CorentinTh/it-tools/issues/new/choose) no repositório do GitHub.
E se você encontrar um bug ou se algo não funcionar como esperado, por favor registre um relato de bug na [seção de issues](https://github.com/CorentinTh/it-tools/issues/new/choose) no GitHub.
404:
notFound: '404 Não Encontrado'
sorry: 'Desculpe, parece que essa página não existe'
maybe: 'Talvez o cache esteja fazendo bobagem, que tal tentar forçar a atualização?'
backHome: 'Voltar para o início'
favoriteButton:
remove: 'Remover dos favoritos'
add: 'Adicionar aos favoritos'
toolCard:
new: 'Novo'
search:
label: 'Pesquisar'
tools:
categories:
favorite-tools: 'Suas ferramentas favoritas'
crypto: 'Cripto'
converter: 'Conversores'
web: 'Web'
images and videos: 'Imagens & Vídeos'
development: 'Desenvolvimento'
network: 'Rede'
math: 'Matemática'
measurement: 'Medidas'
text: 'Texto'
data: 'Dados'

72
locales/uk.yml Normal file
View file

@ -0,0 +1,72 @@
home:
categories:
newestTools: Найновіші інструменти
favoriteTools: 'Ваші улюблені інструменти'
allTools: 'Усі інструменти'
favoritesDndToolTip: 'Перетягніть і відпустіть, щоб змінити порядок улюблених'
subtitle: 'Зручні інструменти для розробників'
toggleMenu: 'Перемикання меню'
home: Головна
uiLib: 'UI Бібліотека'
support: 'Підтримка розробки IT Tools'
buyMeACoffee: 'Купи мені каву'
follow:
title: 'Вам подобаються інструменти IT?'
p1: 'Додайте нам зірку на'
githubRepository: 'GitHub-репозиторій IT-Tools'
p2: 'або слідкуйте за нами на'
twitterXAccount: 'X-акаунт IT-Tools'
thankYou: 'Дякуємо!'
nav:
github: 'GitHub-репозиторій'
githubRepository: 'GitHub-репозиторій IT-Tools'
twitterX: 'X'
twitterXAccount: 'X-акаунт IT-Tools'
about: 'Про IT-Tools'
aboutLabel: 'Про нас'
darkMode: 'Темний режим'
lightMode: 'Світлий режим'
mode: 'Перемикання темного/світлого режиму'
about:
content: >
# Про IT-Tools
Цей чудовий вебсайт, створений з ❤ [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about), агрегує корисні інструменти для розробників і людей, які працюють в сфері IT. Якщо вам це корисно, будь ласка, поділіться цим з людьми, які, на вашу думку, також можуть знайти його корисним, і не забудьте додати його до закладок у вашій панелі швидкого доступу!
IT Tools є відкритим програмним забезпеченням (під ліцензією GPL-3.0) і безкоштовним, і завжди буде таким, але мені коштує гроші для хостингу і продовження доменного імені. Якщо ви хочете підтримати мою роботу і підтримати мене у додаванні нових інструментів, розгляньте можливість підтримки, [спонсоруючи мене](https://www.buymeacoffee.com/cthmsst).
## Технології
IT Tools виконаний на Vue.js (Vue 3) з використанням бібліотеки компонентів Naive UI і розгортаний за допомогою Vercel. У деяких інструментах використовуються сторонні відкриті бібліотеки, повний список яких ви можете знайти в файлі [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json) репозиторію.
## Знайшли баг? Відсутній інструмент?
Якщо вам потрібен інструмент, якого наразі немає тут, і ви вважаєте, що він може бути корисним, ви можете подати запит на додавання функції в [розділі проблем](https://github.com/CorentinTh/it-tools/issues/new/choose) у репозиторії GitHub.
А якщо ви знайшли баг або щось не працює, як очікувалося, будь ласка, подайте звіт про баг в [розділі проблем](https://github.com/CorentinTh/it-tools/issues/new/choose) у репозиторії GitHub.
404:
notFound: '404 Сторінка не знайдена'
sorry: 'Вибачте, ця сторінка, схоже, не існує'
maybe: 'Можливо, кеш робить хитрощі, спробуйте примусово оновити сторінку?'
backHome: 'Повернутися на головну'
favoriteButton:
remove: 'Вилучити з обраних'
add: 'Додати до обраних'
toolCard:
new: Новий
search:
label: Пошук
tools:
categories:
favorite-tools: 'Ваші улюблені інструменти'
crypto: Крипта
converter: Конвертер
web: Веб
images and videos: 'Зображення та відео'
development: Розробка
network: Мережа
math: Математика
measurement: Вимірювання
text: Текст
data: Дані

383
locales/vi.yml Normal file
View file

@ -0,0 +1,383 @@
home:
categories:
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ủ
uiLib: 'Thư viện UI'
support: 'Hỗ trợ phát triển IT Tools'
buyMeACoffee: 'Ủng hộ tác giả'
follow:
title: 'Bạn thích IT-tools?'
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'
twitterXAccount: 'Tài khoản X IT-Tools'
thankYou: 'Cảm ơn bạn!'
nav:
github: 'Kho GitHub'
githubRepository: 'Kho GitHub 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'
lightMode: 'Chế độ sáng'
mode: 'Chuyển đổi chế độ tối/sáng'
about:
content: >
# Về IT-Tools
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 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ệ
IT Tools được tạo ra bằng Vue.js (Vue 3) với thư viện thành phần Naive UI và được lưu trữ và triển khai liên tục bởi Vercel. Các thư viện mã nguồn mở của bên thứ ba được sử dụng trong một số công cụ, bạn có thể tìm danh sách đầy đủ trong file [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json) của kho lưu trữ.
## Phát hiện lỗi? Một công cụ bị thiếu?
Nếu bạn cần một công cụ hiện không có ở đây, và bạn nghĩ rằng nó có thể hữu ích, bạn được chào đón để gửi một yêu cầu tính năng trong [phần vấn đề](https://github.com/CorentinTh/it-tools/issues/new/choose) trong kho GitHub.
Và nếu bạn phát hiện ra một lỗi, hoặc điều gì đó không hoạt động như mong đợi, xin vui lòng gửi báo cáo lỗi trong [phần vấn đề](https://github.com/CorentinTh/it-tools/issues/new/choose) trong kho GitHub.
404:
notFound: '404 Không Tìm Thấy'
sorry: 'Xin lỗi, trang này dường như không tồn tại'
maybe: 'Lỗi xảy ra có thể do bộ nhớ đệm, hãy (CTRL + F5) để tải lại trang?'
backHome: 'Quay về trang chủ'
favoriteButton:
remove: 'Xóa khỏi mục yêu thích'
add: 'Thêm vào mục yêu thích'
toolCard:
new: Mới
search:
label: Tìm kiếm
tools:
categories:
favorite-tools: 'Công cụ yêu thích của bạn'
crypto: Mã hóa
converter: Chuyển đổi
web: Web
images and videos: 'Hình ảnh & Video'
development: Phát triển
network: Mạng
math: Toán học
measurement: Đo lường
text: Văn bản
data: Dữ liệu
password-strength-analyser:
title: Bộ phân tích độ mạnh mật khẩu
description: Khám phá độ mạnh của mật khẩu của bạn với công cụ phân tích độ mạnh mật khẩu chỉ chạy trên phía máy khách và ước tính thời gian phá mật khẩu.
chronometer:
title: Đồng hồ bấm giờ
description: Giám sát thời gian của một sự việc. Cơ bản là một đồng hồ bấm giờ với các tính năng đơn giản.
token-generator:
title: Trình tạo mã thông báo
description: Tạo chuỗi ngẫu nhiên với các ký tự bạn muốn, chữ hoa hoặc chữ thường, số và/hoặc ký tự đặc biệt.
uppercase: Chữ hoa (ABC...)
lowercase: Chữ thường (abc...)
numbers: Số (123...)
symbols: Ký tự đặc biệt (!-;...)
length: Độ dài
tokenPlaceholder: 'Mã thông báo...'
copied: Mã thông báo đã được sao chép vào clipboard
button:
copy: Sao chép
refresh: Làm mới
percentage-calculator:
title: Máy tính phần trăm
description: Dễ dàng tính toán phần trăm từ một giá trị đến giá trị khác, hoặc từ một phần trăm đến một giá trị.
svg-placeholder-generator:
title: Trình tạo hình ảnh SVG giả định
description: Tạo hình ảnh svg để sử dụng làm giả định trong ứng dụng của bạn.
json-to-csv:
title: Chuyển đổi JSON thành CSV
description: Chuyển đổi JSON thành CSV với việc tự động phát hiện tiêu đề.
camera-recorder:
title: Ghi lại camera
description: Chụp ảnh hoặc quay video từ webcam hoặc máy ảnh của bạn.
keycode-info:
title: Thông tin Keycode
description: Tìm mã keycode, mã, vị trí và các phím điều khiển của bất kỳ phím nào được nhấn.
emoji-picker:
title: Bộ chọn biểu tượng cảm xúc
description: Sao chép và dán biểu tượng cảm xúc một cách dễ dàng và nhận giá trị unicode và mã điểm của mỗi biểu tượng cảm xúc.
color-converter:
title: Trình chuyển đổi màu
description: Chuyển đổi màu giữa các định dạng khác nhau (hex, rgb, hsl và tên css)
bcrypt:
title: Bcrypt
description: Mã hóa và so sánh chuỗi văn bản sử dụng bcrypt. Bcrypt là một hàm mã hóa mật khẩu dựa trên thuật toán Blowfish.
crontab-generator:
title: Trình tạo Crontab
description: Xác thực và tạo crontab và lấy mô tả đọc được của lịch trình cron.
http-status-codes:
title: Mã trạng thái HTTP
description: Danh sách tất cả các mã trạng thái HTTP, tên và ý nghĩa của chúng.
sql-prettify:
title: Định dạng và làm đẹp SQL
description: Định dạng và làm đẹp các truy vấn SQL của bạn trực tuyến (hỗ trợ nhiều ngôn ngữ SQL khác nhau).
benchmark-builder:
title: Trình tạo bảng đánh giá
description: Dễ dàng so sánh thời gian thực thi của các nhiệm vụ với trình tạo bảng đánh giá trực tuyến đơn giản này.
git-memo:
title: Lệnh Git
description: Git là một phần mềm quản lý phiên bản phân tán. Với bảng ghi chú này, bạn sẽ có thể truy cập nhanh vào các lệnh Git phổ biến nhất.
slugify-string:
title: Chuyển đổi chuỗi thành slug
description: Biến đổi chuỗi thành dạng an toàn để sử dụng trong URL, tên file và ID.
encryption:
title: Mã hóa / giải mã văn bản
description: Mã hóa và giải mã văn bản rõ bằng cách sử dụng thuật toán mã hóa như AES, TripleDES, Rabbit hoặc RC4.
random-port-generator:
title: Trình tạo số cổng ngẫu nhiên
description: Tạo số cổng ngẫu nhiên nằm ngoài phạm vi của các cổng "biết được" (0-1023).
yaml-prettify:
title: Định dạng và làm đẹp YAML
description: Định dạng chuỗi YAML của bạn thành một định dạng dễ đọc và thân thiện với con người.
eta-calculator:
title: Máy tính ETA
description: Một máy tính ETA (Thời gian dự kiến đến) để biết thời gian kết thúc xấp xỉ của một nhiệm vụ, ví dụ như thời điểm kết thúc của một quá trình tải xuống.
roman-numeral-converter:
title: Bộ chuyển đổi số La Mã
description: Chuyển đổi số La Mã thành số và chuyển đổi số thành số La Mã.
hmac-generator:
title: Máy tạo HMAC
description: Tính toán mã xác thực thông điệp dựa trên hash (HMAC) sử dụng một khóa bí mật và hàm băm yêu thích của bạn.
bip39-generator:
title: Trình tạo BIP39 passphrase
description: Tạo BIP39 passphrase từ mnemonic hiện có hoặc ngẫu nhiên, hoặc lấy mnemonic từ passphrase.
base64-file-converter:
title: Trình chuyển đổi tệp Base64
description: Chuyển đổi chuỗi, tệp hoặc hình ảnh thành mã Base64.
list-converter:
title: Trình chuyển đổi danh sách
description: Công cụ này có thể xử lý dữ liệu dựa trên cột và áp dụng các thay đổi khác nhau (đảo ngược, thêm tiền tố và hậu tố, đảo danh sách, sắp xếp danh sách, giảm giá trị thành chữ thường, cắt giá trị) cho mỗi hàng.
base64-string-converter:
title: Trình mã hóa/giải mã chuỗi Base64
description: Đơn giản mã hóa và giải mã chuỗi thành mã Base64.
toml-to-yaml:
title: Chuyển đổi TOML thành YAML
description: Phân tích và chuyển đổi TOML thành YAML.
math-evaluator:
title: Trình đánh giá toán học
description: Một máy tính để tính toán biểu thức toán học. Bạn có thể sử dụng các hàm như sqrt, cos, sin, abs, v.v.
json-to-yaml-converter:
title: Chuyển đổi JSON sang YAML
description: Chuyển đổi đơn giản JSON sang YAML với công cụ chuyển đổi trực tuyến này.
url-parser:
title: Trình phân tích URL
description: Phân tích một chuỗi URL để lấy tất cả các phần khác nhau (giao thức, nguồn gốc, tham số, cổng, tên người dùng-mật khẩu, ...)
iban-validator-and-parser:
title: Kiểm tra và phân tích số IBAN
description: Xác thực và phân tích số IBAN. Kiểm tra tính hợp lệ của IBAN và lấy thông tin về quốc gia, BBAN, xem có phải là QR-IBAN và định dạng thân thiện của IBAN.
user-agent-parser:
title: Trình phân tích User-agent
description: Phát hiện và phân tích trình duyệt, engine, hệ điều hành, CPU và kiểu/mô hình thiết bị từ chuỗi user-agent.
numeronym-generator:
title: Trình tạo Numeronym
description: Numeronym là một từ mà một số được sử dụng để tạo thành một từ viết tắt. Ví dụ, "i18n" là một numeronym của "internationalization" trong đó số 18 đại diện cho số chữ cái giữa chữ i đầu tiên và chữ n cuối cùng trong từ.
case-converter:
title: Chuyển đổi chữ hoa/chữ thường
description: Thay đổi kiểu chữ của một chuỗi và chọn giữa các định dạng khác nhau
html-entities:
title: Thay thế các ký tự HTML
description: Thay thế hoặc bỏ thẻ các ký tự HTML (thay thế <,>, &, " và \' thành phiên bản HTML tương ứng)
json-prettify:
title: Định dạng và làm đẹp JSON
description: Định dạng chuỗi JSON của bạn thành một định dạng dễ đọc và thân thiện với con người.
docker-run-to-docker-compose-converter:
title: Chuyển đổi lệnh docker run thành tệp docker-compose
description: Chuyển đổi các lệnh docker run thành tệp docker-compose!
mac-address-lookup:
title: Tra cứu địa chỉ MAC
description: Tìm nhà sản xuất và nhà cung cấp của thiết bị dựa trên địa chỉ MAC.
mime-types:
title: Loại Mime
description: Chuyển đổi loại mime thành phần mở rộng và ngược lại.
toml-to-json:
title: Chuyển đổi TOML thành JSON
description: Phân tích và chuyển đổi TOML thành JSON.
lorem-ipsum-generator:
title: Máy tạo văn bản Lorem ipsum
description: Lorem ipsum là một đoạn văn bản giả được sử dụng phổ biến để thể hiện hình thức của một tài liệu hoặc một kiểu chữ mà không cần dựa vào nội dung có ý nghĩa
qrcode-generator:
title: Tạo mã QR
description: Tạo và tải xuống mã QR cho một URL hoặc chỉ một đoạn văn bản và tùy chỉnh màu nền và màu chữ.
wifi-qrcode-generator:
title: Tạo mã QR WiFi
description: Tạo và tải xuống mã QR để kết nối nhanh đến mạng WiFi.
xml-formatter:
title: Định dạng XML
description: Định dạng chuỗi XML của bạn thành một định dạng dễ đọc và thân thiện với con người.
temperature-converter:
title: Bộ chuyển đổi nhiệt độ
description: Chuyển đổi độ nhiệt độ cho Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Réaumur và Rømer.
chmod-calculator:
title: Máy tính Chmod
description: Tính toán quyền và lệnh chmod của bạn với máy tính Chmod trực tuyến này.
rsa-key-pair-generator:
title: Trình tạo cặp khóa RSA
description: Tạo các chứng chỉ pem khóa riêng tư và khóa công khai RSA ngẫu nhiên mới.
html-wysiwyg-editor:
title: Trình soạn thảo HTML WYSIWYG
description: Trình soạn thảo HTML trực tuyến với trình soạn thảo WYSIWYG đa chức năng, lấy mã nguồn của nội dung ngay lập tức.
yaml-to-toml:
title: YAML sang TOML
description: Phân tích và chuyển đổi YAML sang TOML.
mac-address-generator:
title: Trình tạo địa chỉ MAC
description: Nhập số lượng và tiền tố. Địa chỉ MAC sẽ được tạo ra theo kiểu chữ hoa hoặc chữ thường theo lựa chọn của bạn
json-diff:
title: So sánh JSON
description: So sánh hai đối tượng JSON và lấy ra sự khác biệt giữa chúng.
jwt-parser:
title: Giải mã JWT
description: Giải mã và hiển thị nội dung của JSON Web Token (jwt).
date-converter:
title: Chuyển đổi ngày-tháng
description: Chuyển đổi ngày và thời gian sang các định dạng khác nhau
phone-parser-and-formatter:
title: Trình phân tích và định dạng số điện thoại
description: Phân tích, xác thực và định dạng số điện thoại. Lấy thông tin về số điện thoại, như mã quốc gia, loại, v.v.
ipv4-subnet-calculator:
title: Máy tính mạng con IPv4
description: Phân tích các khối CIDR IPv4 của bạn và nhận thông tin về mạng con của bạn.
og-meta-generator:
title: Trình tạo meta Open Graph
description: Tạo các thẻ meta HTML Open Graph và mạng xã hội cho trang web của bạn.
ipv6-ula-generator:
title: Trình tạo địa chỉ IPv6 ULA
description: Tạo địa chỉ IP cục bộ, không thể định tuyến trên mạng của bạn theo RFC4193.
hash-text:
title: Mã hóa văn bản
description: 'Mã hóa một chuỗi văn bản bằng cách sử dụng các hàm bạn cần: MD5, SHA1, SHA256, SHA224, SHA512, SHA384, SHA3 hoặc RIPEMD160'
json-to-toml:
title: Chuyển đổi JSON sang TOML
description: Phân tích và chuyển đổi JSON sang TOML.
device-information:
title: Thông tin thiết bị
description: Lấy thông tin về thiết bị hiện tại của bạn (kích thước màn hình, tỷ lệ pixel, user agent, ...)
pdf-signature-checker:
title: Kiểm tra chữ ký PDF
description: Xác minh chữ ký của một tệp PDF. Một tệp PDF đã được ký có chứa một hoặc nhiều chữ ký có thể được sử dụng để xác định xem nội dung của tệp đã được thay đổi kể từ khi tệp được ký.
json-minify:
title: Giảm kích thước JSON
description: Giảm kích thước và nén JSON của bạn bằng cách loại bỏ khoảng trắng không cần thiết.
ulid-generator:
title: Tạo ULID
description: Tạo ngẫu nhiên mã định danh duy nhất có thể sắp xếp theo thứ tự từ điển (ULID).
string-obfuscator:
title: Mã hóa chuỗi
description: Mã hóa một chuỗi (như một bí mật, một IBAN hoặc một mã thông báo) để có thể chia sẻ và nhận dạng mà không tiết lộ nội dung.
base-converter:
title: Chuyển đổi cơ số số nguyên
description: Chuyển đổi số giữa các cơ số khác nhau (thập phân, thập lục phân, nhị phân, bát phân, base64, ...)
yaml-to-json-converter:
title: Trình chuyển đổi YAML sang JSON
description: Chuyển đổi YAML sang JSON một cách đơn giản với công cụ chuyển đổi trực tuyến này.
uuid-generator:
title: Trình tạo UUID
description: Một UUID (Universally Unique Identifier) là một số 128 bit được sử dụng để xác định thông tin trong hệ thống máy tính. Số lượng UUID có thể có là 16^32, tương đương với 2^128 hoặc khoảng 3.4x10^38 (rất lớn!).
ipv4-address-converter:
title: Chuyển đổi địa chỉ Ipv4
description: Chuyển đổi địa chỉ ip thành số thập phân, nhị phân, thập lục phân hoặc thậm chí thành ipv6
text-statistics:
title: Thống kê văn bản
description: Lấy thông tin về một văn bản, số ký tự, số từ, kích thước của nó, ...
text-to-nato-alphabet:
title: Chuyển đổi văn bản thành bảng chữ cái NATO
description: Chuyển đổi văn bản thành bảng chữ cái phiên âm NATO để truyền tải bằng miệng.
basic-auth-generator:
title: Tạo mã xác thực cơ bản
description: Tạo một tiêu đề xác thực cơ bản base64 từ tên người dùng và mật khẩu.
text-to-unicode:
title: Chuyển đổi văn bản thành Unicode
description: Phân tích và chuyển đổi văn bản thành Unicode và ngược lại
ipv4-range-expander:
title: Mở rộng dải IPv4
description: Cho một địa chỉ IPv4 bắt đầu và kết thúc, công cụ này tính toán một mạng IPv4 hợp lệ với ký hiệu CIDR của nó.
text-diff:
title: So sánh văn bản
description: So sánh hai văn bản và xem sự khác biệt giữa chúng.
otp-generator:
title: Tạo mã OTP
description: Tạo và xác thực mã OTP (mật khẩu một lần) dựa trên thời gian cho xác thực đa yếu tố.
url-encoder:
title: Mã hóa/giải mã chuỗi định dạng URL
description: Mã hóa thành định dạng URL (còn được gọi là "percent-encoded") hoặc giải mã từ đó.
text-to-binary:
title: Chuyển đổi văn bản thành nhị phân ASCII
description: Chuyển đổi văn bản thành biểu diễn nhị phân ASCII của nó và ngược lại.

390
locales/zh.yml Normal file
View file

@ -0,0 +1,390 @@
home:
categories:
newestTools: '最新工具'
favoriteTools: '我的收藏'
allTools: '全部工具'
favoritesDndToolTip: '拖放重新排列收藏夹'
subtitle: '助力开发人员和 IT 工作者'
toggleMenu: '切换菜单'
home: '主页'
uiLib: 'UI 库'
support: '支持 IT 工具开发'
buyMeACoffee: '赞助'
follow:
title: '关注我们'
p1: '给我们 Star'
githubRepository: 'GitHub 仓库'
p2: '关注我们的'
twitterXAccount: 'IT-Tools X 账号'
thankYou: '感谢您的支持!'
nav:
github: 'GitHub 仓库'
githubRepository: 'GitHub 仓库'
twitterX: 'Twitter 账号'
twitterXAccount: 'IT-Tools X 账号'
about: '关于 IT-Tools'
aboutLabel: '关于'
darkMode: '深色模式'
lightMode: '浅色模式'
mode: '颜色模式'
about:
content: >
# 关于 IT-Tools
IT-Tools 由 [Corentin Thomasset](https://corentin.tech?utm_source=it-tools&utm_medium=about) 用 ❤ 开发,汇集了对开发人员和 IT 从业者有用的工具。如果对您有帮助,请将其分享给您的朋友,并且添加到收藏夹中!
IT-Tools 永久免费且开源GPL-3.0 许可证),但需要资金用于托管和续订域名。如果您想支持我的工作,并鼓励我添加更多工具,请考虑通过 [赞助我](https://www.buymeacoffee.com/cthmsst) 进行支持。
## 技术
IT-Tools 采用 Vue.jsVue 3和 Naive UI 组件库开发,并由 Vercel 托管和持续部署。某些工具使用了第三方开源库,您可以在仓库的 [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json) 文件中找到完整的列表。
## 发现了 Bug缺少工具
如果目前这里没有您需要的工具,并且您认为它可能有用,欢迎在 GitHub 仓库的 [issues](https://github.com/CorentinTh/it-tools/issues/new/choose) 中提交新增功能的请求。
如果您发现了 Bug或者某些功能未能按预期工作请在 GitHub 仓库的 [issues](https://github.com/CorentinTh/it-tools/issues/new/choose) 中提交错误报告。
404:
notFound: '404 页面不存在'
sorry: '抱歉,该页面似乎不存在'
maybe: '也许缓存出现了一些问题,试试强制刷新页面?'
backHome: '返回主页'
favoriteButton:
remove: '取消收藏'
add: '加入收藏'
toolCard:
new: '新'
search:
label: '搜索'
tools:
categories:
favorite-tools: '我的收藏'
crypto: '加密'
converter: '转换器'
web: Web
images and videos: '图片和视频'
development: '开发'
network: '网络'
math: '数学'
measurement: '测量'
text: '文本'
data: '数据'
password-strength-analyser:
title: 密码强度分析仪
description: 使用此密码强度分析器和破解时间估计工具来发现密码的强度。
chronometer:
title: 计时器
description: 监控事物的持续时间。基本上是一种具有简单计时器功能的计时器。
token-generator:
title: Token 生成器
description: 使用您想要的字符、大写或小写字母、数字和/或符号生成随机字符串。
uppercase: '大写 (ABC...)'
lowercase: '小写 (abc...)'
numbers: '数字 (123...)'
symbols: '符号 (!-;...)'
length: '长度'
tokenPlaceholder: '令牌...'
copied: 复制到剪贴板
button:
copy: 复制
refresh: 刷新
percentage-calculator:
title: 百分比计算器
description: 轻松计算从一个值到另一个值的百分比,或从百分比到值的百分比。
svg-placeholder-generator:
title: SVG 占位符生成器
description: 生成 svg 图像以用作应用程序中的占位符。
json-to-csv:
title: JSON 转 CSV
description: 使用自动标头检测将JSON转换为CSV。
camera-recorder:
title: 摄像机记录器
description: 从网络摄像头或照相机拍摄照片或录制视频。
keycode-info:
title: Keycode 信息
description: 查找任何按下的键的javascript键代码、代码、位置和修饰符。
emoji-picker:
title: Emoji 选择器
description: 轻松复制和粘贴Emoji表情符号并获得每个表情符号的unicode和code points值.
color-converter:
title: Color 选择器
description: 在不同格式十六进制、rgb、hsl和css名称之间转换颜色
bcrypt:
title: 加密
description: 使用bcrypt对文本字符串进行哈希和比较。Bcrypt是一个基于Blowfish密码的密码哈希函数。
crontab-generator:
title: Crontab 表达式生成
description: 验证并生成crontab并获取cron调度的可读描述。
http-status-codes:
title: HTTP 状态码
description: 所有HTTP状态的列表对其名称和含义解释。
sql-prettify:
title: SQL 美化和格式化
description: 在线格式化和美化您的 SQL 查询(它支持各种 SQL 方言)。
benchmark-builder:
title: 基准生成器
description: 简单的在线基准构建器可以轻松比较任务的执行时间。
git-memo:
title: Git 备忘录
description: Git是一种去中心化的版本管理软件。使用此备忘单您可以快速访问最常见的git命令.
slugify-string:
title: 打乱字符串
description: 确保字符串 url、文件名和 id 安全。
encryption:
title: 加密/解密文本
description: 使用加密算法如AES、TripleDES、Rabbit或RC4加密和解密文本明文。
random-port-generator:
title: 随机端口生成
description: 生成“已知”端口范围0-1023之外的随机端口号。
yaml-prettify:
title: YAML美化和格式化
description: 将YAML字符串修饰为友好的可读格式。
eta-calculator:
title: ETA 计算器
description: ETA估计到达时间计算器用于知道任务的近似结束时间例如下载的结束时刻。
roman-numeral-converter:
title: 罗马数字转换器
description: 将罗马数字转换为数字,并将数字转换为罗马数字。
hmac-generator:
title: Hmac 生成器
description: 使用密钥和您喜欢的哈希函数计算基于哈希的消息身份验证代码HMAC
bip39-generator:
title: BIP39密码生成器
description: 从现有或随机助记符生成BIP39密码短语或从密码短语获取助记符。
base64-file-converter:
title: Base64 文件转换器
description: 将字符串、文件或图像转换为其 Base64 表示形式。
list-converter:
title: List 转换器
description: 该工具可以处理基于数组的数据,并将各种更改(转置、添加前缀和后缀、反向列表、排序列表、小写值、截断值)应用于每一行。
base64-string-converter:
title: Base64 字符串编码/解码
description: 将字符串编码和解码为其 Base64 格式表示形式即可。
toml-to-yaml:
title: TOML 到 YAML
description: Parse and convert TOML to YAML.
math-evaluator:
title: 数学计算器
description: 计算数学表达式的计算器。您可以使用sqrt、cos、sin、abs等函数。
json-to-yaml-converter:
title: JSON到YAML转换器
description: 在线转换将JSON转换为YAML。
url-parser:
title: Url分析器
description: 解析url字符串以获取所有不同的部分协议、来源、参数、端口、用户名密码…
iban-validator-and-parser:
title: IBAN验证器和解析器
description: 验证和分析IBAN编号。检查IBAN是否有效并获取国家BBAN如果它是QR-IBAN和IBAN友好格式。
user-agent-parser:
title: 用户代理分析器
description: 从用户代理字符串中检测和分析浏览器、引擎、操作系统、CPU和设备类型/型号。
numeronym-generator:
title: 数字名称生成器
description: 数字名是一个用数字构成缩写的词。例如“i18n”是“国际化”的名词其中18表示单词中第一个i和最后一个n之间的字母数。
case-converter:
title: 大小写转换
description: 更改字符串的大小写并在不同格式之间进行选择
html-entities:
title: 转义html实体
description: 转义或unescape html实体将<、>、&、“和\'替换为其html版本
json-prettify:
title: JSON美化和格式化
description: 将JSON字符串修饰为友好的可读格式。
docker-run-to-docker-compose-converter:
title: Docker Run 到 docker-compose 转换器
description: 将 docker run 命令行转换为 docker-compose 文件!
mac-address-lookup:
title: MAC地址查找
description: 通过设备的MAC地址查找设备的供应商和制造商。
mime-types:
title: mime类型
description: 将mime类型转换为扩展反之亦然。
toml-to-json:
title: TOML 到 JSON
description: 解析TOML并将其转换为JSON。
lorem-ipsum-generator:
title: Lorem ipsum生成器
description: Lorem ipsum是一种占位符文本通常用于演示文档或字体的视觉形式而不依赖于有意义的内容
qrcode-generator:
title: 二维码生成器
description: 生成并下载url或文本的QR代码并自定义背景和前景颜色。
wifi-qrcode-generator:
title: WiFi 二维码生成器
description: 生成和下载QR码以快速连接到WiFi网络。
xml-formatter:
title: XML 格式化
description: 将XML字符串修饰为友好的可读格式。
temperature-converter:
title: 温度转换器
description: 开尔文、摄氏度、华氏度、兰金、德莱尔、牛顿、雷奥穆尔和罗默温度度数转换。
chmod-calculator:
title: Chmod 计算器
description: 使用此在线的chmod计算器计算chmod权限和命令。
rsa-key-pair-generator:
title: RSA密钥对生成器
description: 生成新的随机RSA私钥和公钥pem证书。
html-wysiwyg-editor:
title: HTML所见即所得编辑器
description: 在线HTML编辑器具有功能丰富的所见即所得编辑器立即获得内容的源代码。
yaml-to-toml:
title: YAML 到 TOML
description: 解析YAML并将其转换为TOML。
mac-address-generator:
title: MAC 地址生成器
description: 输入数量和前缀。MAC地址将以您选择的大小写大写或小写生成
json-diff:
title: JSON 差异比较
description: 比较两个JSON对象并获得它们之间的差异。
jwt-parser:
title: JWT 解析器
description: 解析和解码JSON Web Tokenjwt并显示其内容。
date-converter:
title: 日期时间转换器
description: 将日期和时间转换为各种不同的格式
phone-parser-and-formatter:
title: 电话分析器和格式化程序
description: 解析、验证和格式化电话号码。获取有关电话号码的信息,如国家/地区代码、类型等。
ipv4-subnet-calculator:
title: IPv4子网计算器
description: 解析IPv4 CIDR块并获取有关子网络的所有所需信息。
og-meta-generator:
title: 开放式图形元生成器
description: 为您的网站生成开放式图形和社交html元标记。
ipv6-ula-generator:
title: IPv6 ULA生成器
description: 根据RFC4193在网络上生成您自己的本地不可路由IP地址。
hash-text:
title: Hash 文本
description: '使用所需的函数哈希文本字符串MD5、SHA1、SHA256、SHA224、SHA512、SHA384、SHA3或RIPEMD160'
json-to-toml:
title: JSON 转 TOML
description: 解析JSON并将其转换为TOML。
device-information:
title: 设备信息
description: 获取有关当前设备的信息(屏幕大小、像素比率、用户代理…)
pdf-signature-checker:
title: PDF签名检查器
description: '验证PDF文件的签名。签名的PDF文件包含一个或多个签名可用于确定文件的内容在签名后是否已被更改。'
json-minify:
title: JSON 压缩
description: 通过删除不必要的空白来缩小和压缩JSON。
ulid-generator:
title: ULID 生成器
description: 生成随机的通用唯一词典可排序标识符ULID
string-obfuscator:
title: 字符串混淆器
description: 混淆字符串如秘密、IBAN 或令牌),使其可共享和可识别,而不泄露其内容。
base-converter:
title: 整数基转换器
description: 在不同的基数十进制、十六进制、二进制、八进制、base64…之间转换数字
yaml-to-json-converter:
title: YAML到JSON转换器
description: 使用此在线转换器将YAML转换为JSON。
uuid-generator:
title: UUIDs 生成器
description: 通用唯一标识符UUID是一个128位数字用于标识计算机系统中的信息。可能的UUID数量为16^32即2^128或约3.4x10^38这是一个很大的数字
ipv4-address-converter:
title: Ipv4地址转换器
description: 在ipv6中将ip地址转换为十进制、二进制、十六进制或事件
text-statistics:
title: 文本统计
description: 获取有关文本、字符数、字数、大小等的信息
text-to-nato-alphabet:
title: 文本转北约字母表
description: 将文本转换为北约拼音字母以进行口头传播。
basic-auth-generator:
title: 基本身份验证生成器
description: 从用户名和密码生成 base64 基本身份验证标头。
text-to-unicode:
title: 文本转 Unicode
description: 解析文本并将其转换为 unicode反之亦然
ipv4-range-expander:
title: IPv4范围扩展器
description: 给定起始和结束IPv4地址此工具使用其CIDR表示法计算有效的IPv4网络。
text-diff:
title: 文本比较
description: 比较两个文本并查看它们之间的差异。
otp-generator:
title: OTP代码生成器
description: 为多因素身份验证生成和验证基于时间的OTP一次性密码
url-encoder:
title: 编码/解码url格式的字符串
description: 编码为url编码格式也称为“百分比编码”或从中解码。
text-to-binary:
title: 文本到 ASCII 二进制
description: 将文本转换为其 ASCII 二进制表示形式,反之亦然。

4
netlify.toml Normal file
View file

@ -0,0 +1,4 @@
[[redirects]]
from = "/*"
to = "/index.html"
status = 200

View file

@ -1,7 +1,15 @@
{
"name": "it-tools",
"version": "2023.4.14-dbad773",
"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,115 +21,133 @@
"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 && vite build",
"build": "vue-tsc --noEmit && NODE_OPTIONS=--max_old_space_size=4096 vite build",
"preview": "vite preview --port 5050",
"test": "npm run test:unit",
"test:unit": "vitest --environment jsdom",
"test:e2e": "playwright test",
"test:e2e:dev": "BASE_URL=http://localhost:5173 NO_WEB_SERVER=true playwright test",
"coverage": "vitest run --coverage",
"typecheck": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
"lint": "eslint src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --ignore-path .gitignore",
"script:create-new-tool": "node scripts/create-tool.mjs",
"script:create:tool": "node scripts/create-tool.mjs",
"script:create:ui": "hygen generator ui-component",
"release": "node ./scripts/release.mjs"
},
"dependencies": {
"@it-tools/bip39": "^0.0.4",
"@it-tools/oggen": "^1.3.0",
"@sindresorhus/slugify": "^2.2.0",
"@tiptap/pm": "2.0.0-beta.220",
"@tiptap/starter-kit": "2.0.0-beta.220",
"@tiptap/vue-3": "2.0.0-beta.220",
"@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/markdown-it": "^13.0.7",
"@vicons/material": "^0.12.0",
"@vicons/tabler": "^0.12.0",
"@vueuse/core": "^8.9.4",
"@vueuse/head": "^0.7.13",
"@vueuse/router": "^9.13.0",
"@vueuse/core": "^10.3.0",
"@vueuse/head": "^1.0.0",
"@vueuse/router": "^10.0.0",
"bcryptjs": "^2.4.3",
"change-case": "^4.1.2",
"colord": "^2.9.3",
"composerize-ts": "^0.6.2",
"country-code-lookup": "^0.1.0",
"cron-validator": "^1.3.1",
"cronstrue": "^2.26.0",
"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",
"fuse.js": "^6.6.2",
"highlight.js": "^11.7.0",
"iarna-toml-esm": "^3.0.5",
"ibantools": "^4.3.3",
"js-base64": "^3.7.6",
"json5": "^2.2.3",
"jwt-decode": "^3.1.2",
"libphonenumber-js": "^1.10.28",
"lodash": "^4.17.21",
"mathjs": "^10.6.4",
"markdown-it": "^14.0.0",
"marked": "^10.0.0",
"mathjs": "^11.9.1",
"mime-types": "^2.1.35",
"naive-ui": "^2.34.3",
"monaco-editor": "^0.43.0",
"naive-ui": "^2.35.0",
"netmask": "^2.0.2",
"node-forge": "^1.3.1",
"oui": "^12.0.52",
"oui-data": "^1.0.10",
"pdf-signature-reader": "^1.4.2",
"pinia": "^2.0.34",
"plausible-tracker": "^0.3.8",
"qrcode": "^1.5.1",
"randombytes": "^2.1.0",
"sql-formatter": "^8.2.0",
"ts-pattern": "^4.2.2",
"randexp": "^0.5.3",
"sql-formatter": "^13.0.0",
"ua-parser-js": "^1.0.35",
"uuid": "^8.3.2",
"vue": "^3.2.47",
"ulid": "^2.3.0",
"unicode-emoji-json": "^0.4.0",
"unplugin-auto-import": "^0.16.4",
"uuid": "^9.0.0",
"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": {
"@antfu/eslint-config": "^0.41.0",
"@iconify-json/mdi": "^1.1.50",
"@intlify/unplugin-vue-i18n": "^2.0.0",
"@playwright/test": "^1.32.3",
"@rushstack/eslint-patch": "^1.2.0",
"@tsconfig/node18": "^18.2.0",
"@types/bcryptjs": "^2.4.2",
"@types/crypto-js": "^4.1.1",
"@types/jsdom": "^16.2.15",
"@types/dompurify": "^3.0.5",
"@types/jsdom": "^21.0.0",
"@types/lodash": "^4.14.192",
"@types/mime-types": "^2.1.1",
"@types/netmask": "^2.0.0",
"@types/node": "^16.18.23",
"@types/node": "^18.15.11",
"@types/node-forge": "^1.3.2",
"@types/prettier": "^2.7.2",
"@types/qrcode": "^1.5.0",
"@types/randombytes": "^2.0.0",
"@types/ua-parser-js": "^0.7.36",
"@types/uuid": "^8.3.4",
"@typescript-eslint/parser": "^5.58.0",
"@unocss/eslint-config": "^0.50.8",
"@vitejs/plugin-vue": "^2.3.4",
"@vitejs/plugin-vue-jsx": "^1.3.10",
"@vue/eslint-config-prettier": "^7.1.0",
"@vue/eslint-config-typescript": "^10.0.0",
"@types/uuid": "^9.0.0",
"@unocss/eslint-config": "^0.57.0",
"@vitejs/plugin-vue": "^4.3.2",
"@vitejs/plugin-vue-jsx": "^3.0.2",
"@vue/compiler-sfc": "^3.2.47",
"@vue/runtime-dom": "^3.3.4",
"@vue/test-utils": "^2.3.2",
"@vue/tsconfig": "^0.1.3",
"c8": "^7.13.0",
"@vue/tsconfig": "^0.4.0",
"consola": "^3.0.2",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-vue": "^8.7.1",
"jsdom": "^19.0.0",
"eslint": "^8.47.0",
"hygen": "^6.2.11",
"jsdom": "^22.0.0",
"less": "^4.1.3",
"prettier": "^2.8.7",
"start-server-and-test": "^1.15.4",
"typescript": "~4.5.5",
"unocss": "^0.50.8",
"unplugin-auto-import": "^0.15.2",
"unplugin-vue-components": "^0.24.1",
"vite": "^2.9.15",
"vite-plugin-md": "^0.12.4",
"vite-plugin-pwa": "^0.11.13",
"vite-svg-loader": "^3.6.0",
"vitest": "^0.13.1",
"vue-tsc": "^0.31.4",
"workbox-window": "^6.5.4",
"prettier": "^3.0.0",
"typescript": "~5.2.0",
"unocss": "^0.65.1",
"unocss-preset-scrollbar": "^0.2.1",
"unplugin-icons": "^0.17.0",
"unplugin-vue-components": "^0.25.0",
"vite": "^4.4.9",
"vite-plugin-pwa": "^0.16.0",
"vite-plugin-vue-markdown": "^0.23.5",
"vite-svg-loader": "^4.0.0",
"vitest": "^0.34.0",
"workbox-window": "^7.0.0",
"zx": "^7.2.1"
}
}

View file

@ -1,31 +1,29 @@
import { defineConfig, devices } from '@playwright/test';
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
const isCI = !!process.env.CI;
const baseUrl = process.env.BASE_URL || 'http://localhost:5050';
const useWebServer = process.env.NO_WEB_SERVER !== 'true';
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './src',
testMatch: /.*\.e2e\.(spec\.)?ts/,
testMatch: /\.e2e\.(spec\.)?ts$/,
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
forbidOnly: isCI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
retries: isCI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
workers: isCI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: 'http://127.0.0.1:3000',
baseURL: baseUrl,
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
@ -51,32 +49,17 @@ export default defineConfig({
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ..devices['Desktop Chrome'], channel: 'chrome' },
// },
],
/* Run your local dev server before starting the tests */
...(useWebServer
&& {
webServer: {
command: 'npm run dev',
url: 'http://127.0.0.1:3000',
reuseExistingServer: !process.env.CI,
command: 'npm run preview',
url: 'http://localhost:5050',
reuseExistingServer: !isCI,
},
}
),
});

16408
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

6
renovate.json Normal file
View file

@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
}

View file

@ -0,0 +1,61 @@
import { existsSync, writeFileSync } from 'node:fs';
import { Glob } from 'bun';
import _ from 'lodash';
async function getPathsFromGlobs({ patterns, onlyFiles = true }) {
const filePaths = [];
for (const pattern of patterns) {
const glob = new Glob(pattern);
for await (const filePath of glob.scan({ onlyFiles, cwd: '.' })) {
filePaths.push(filePath);
}
}
return { filePaths };
}
function getLocaleKey({ filePath }) {
const fileName = filePath.split('/').pop();
return fileName.replace(/\.yml$/, '');
}
async function createMissingLocaleFile({ localeKey }) {
const fileName = `${localeKey}.yml`;
const { filePaths: localesDirs } = await getPathsFromGlobs({
patterns: [
'locales',
'src/tools/*/locales',
],
onlyFiles: false,
});
for (const localesDir of localesDirs) {
const filePath = `${localesDir}/${fileName}`;
if (existsSync(filePath)) {
console.log(`Locale file already exists: ${filePath}`);
continue;
}
console.log(`Creating missing locale file: ${filePath}`);
writeFileSync(filePath, '', 'utf8');
}
}
const { filePaths } = await getPathsFromGlobs({
patterns: [
'locales/*.yml',
'src/tools/*/locales/*.yml',
],
});
await Promise.all(
_.chain(filePaths)
.map(filePath => getLocaleKey({ filePath }))
.uniq()
.map(localeKey => createMissingLocaleFile({ localeKey }))
.value(),
);

View file

@ -29,9 +29,9 @@ createToolFile(
`${toolName}.vue`,
`
<template>
<n-card>
<div>
Lorem ipsum
</n-card>
</div>
</template>
<script setup lang="ts">

View file

@ -1,7 +1,6 @@
<script setup lang="ts">
import { computed } from 'vue';
import { useRoute, RouterView } from 'vue-router';
import { darkTheme, NGlobalStyle, NMessageProvider, NNotificationProvider } from 'naive-ui';
import { RouterView, useRoute } from 'vue-router';
import { NGlobalStyle, NMessageProvider, NNotificationProvider, darkTheme } from 'naive-ui';
import { darkThemeOverrides, lightThemeOverrides } from './themes';
import { layouts } from './layouts';
import { useStyleStore } from './stores/style.store';
@ -12,18 +11,25 @@ const styleStore = useStyleStore();
const theme = computed(() => (styleStore.isDarkTheme ? darkTheme : null));
const themeOverrides = computed(() => (styleStore.isDarkTheme ? darkThemeOverrides : lightThemeOverrides));
const { locale } = useI18n();
syncRef(
locale,
useStorage('locale', locale),
);
</script>
<template>
<n-config-provider :theme="theme" :theme-overrides="themeOverrides">
<n-global-style />
<n-message-provider placement="bottom">
<n-notification-provider placement="bottom-right">
<NGlobalStyle />
<NMessageProvider placement="bottom">
<NNotificationProvider placement="bottom-right">
<component :is="layout">
<router-view />
<RouterView />
</component>
</n-notification-provider>
</n-message-provider>
</NNotificationProvider>
</NMessageProvider>
</n-config-provider>
</template>

View file

@ -1,39 +1,9 @@
<template>
<div v-for="{ name, tools, isCollapsed } of menuOptions" :key="name">
<n-text tag="div" depth="3" class="category-name" @click="toggleCategoryCollapse({ name })">
<n-icon :component="ChevronRight" :class="{ rotated: isCollapsed }" size="16" />
<span>
{{ name }}
</span>
</n-text>
<n-collapse-transition :show="!isCollapsed">
<div class="menu-wrapper">
<div class="toggle-bar" @click="toggleCategoryCollapse({ name })" />
<n-menu
class="menu"
:value="(route.name as string)"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="tools"
:indent="8"
:default-expand-all="true"
/>
</div>
</n-collapse-transition>
</div>
</template>
<script setup lang="ts">
import type { Tool, ToolCategory } from '@/tools/tools.types';
import { ChevronRight } from '@vicons/tabler';
import { useStorage } from '@vueuse/core';
import { useThemeVars } from 'naive-ui';
import { toRefs, computed, h } from 'vue';
import { RouterLink, useRoute } from 'vue-router';
import MenuIconItem from './MenuIconItem.vue';
import type { Tool, ToolCategory } from '@/tools/tools.types';
const props = withDefaults(defineProps<{ toolsByCategory?: ToolCategory[] }>(), { toolsByCategory: () => [] });
const { toolsByCategory } = toRefs(props);
@ -49,8 +19,8 @@ const collapsedCategories = useStorage<Record<string, boolean>>(
{
deep: true,
serializer: {
read: (v) => (v ? JSON.parse(v) : null),
write: (v) => JSON.stringify(v),
read: v => (v ? JSON.parse(v) : null),
write: v => JSON.stringify(v),
},
},
);
@ -61,12 +31,12 @@ function toggleCategoryCollapse({ name }: { name: string }) {
const menuOptions = computed(() =>
toolsByCategory.value.map(({ name, components }) => ({
name: name,
name,
isCollapsed: collapsedCategories.value[name],
tools: components.map((tool) => ({
tools: components.map(tool => ({
label: makeLabel(tool),
icon: makeIcon(tool),
key: tool.name,
key: tool.path,
})),
})),
);
@ -74,27 +44,37 @@ const menuOptions = computed(() =>
const themeVars = useThemeVars();
</script>
<template>
<div v-for="{ name, tools, isCollapsed } of menuOptions" :key="name">
<div ml-6px mt-12px flex cursor-pointer items-center op-60 @click="toggleCategoryCollapse({ name })">
<span :class="{ 'rotate-0': isCollapsed, 'rotate-90': !isCollapsed }" text-16px lh-1 op-50 transition-transform>
<icon-mdi-chevron-right />
</span>
<span ml-8px text-13px>
{{ name }}
</span>
</div>
<n-collapse-transition :show="!isCollapsed">
<div class="menu-wrapper">
<div class="toggle-bar" @click="toggleCategoryCollapse({ name })" />
<n-menu
class="menu"
:value="route.path"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="tools"
:indent="8"
:default-expand-all="true"
/>
</div>
</n-collapse-transition>
</div>
</template>
<style scoped lang="less">
.category-name {
font-size: 0.93em;
padding: 12px 0 0px 0;
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
.n-icon {
transition: transform ease 0.5s;
transform: rotate(90deg);
margin: 0 10px 0 7px;
opacity: 0.5;
&.rotated {
transform: rotate(0deg);
}
}
}
.menu-wrapper {
display: flex;
flex-direction: row;

View file

@ -1,8 +1,13 @@
<script setup lang="ts">
import type { Component } from 'vue';
const props = defineProps<{ icon: Component; title: string }>();
const { icon, title } = toRefs(props);
</script>
<template>
<n-card class="colored-card">
<n-space justify="space-between" align="center">
<c-card class="colored-card">
<n-icon class="icon" size="40" :component="icon" />
</n-space>
<n-h3 class="title">
<n-ellipsis>{{ title }}</n-ellipsis>
</n-h3>
@ -12,16 +17,9 @@
<slot />
</n-ellipsis>
</div>
</n-card>
</c-card>
</template>
<script setup lang="ts">
import { toRefs, type Component } from 'vue';
const props = defineProps<{ icon: Component; title: string }>();
const { icon, title } = toRefs(props);
</script>
<style lang="less" scoped>
.colored-card {
background: rgb(37, 99, 108);

View file

@ -1,25 +1,11 @@
<template>
<n-tooltip trigger="hover">
<template #trigger>
<n-button circle quaternary :type="buttonType" :style="{ opacity: isFavorite ? 1 : 0.2 }" @click="toggleFavorite">
<template #icon>
<n-icon :component="FavoriteFilled" />
</template>
</n-button>
</template>
{{ isFavorite ? 'Remove from favorites' : 'Add to favorites' }}
</n-tooltip>
</template>
<script setup lang="ts">
import { FavoriteFilled } from '@vicons/material';
import { useToolStore } from '@/tools/tools.store';
import type { Tool } from '@/tools/tools.types';
import { computed, toRefs } from 'vue';
const props = defineProps<{ tool: Tool }>();
const toolStore = useToolStore();
const props = defineProps<{ tool: Tool }>();
const { tool } = toRefs(props);
const isFavorite = computed(() => toolStore.isToolFavorite({ tool }));
@ -36,3 +22,17 @@ function toggleFavorite(event: MouseEvent) {
toolStore.addToolToFavorites({ tool });
}
</script>
<template>
<c-tooltip :tooltip="isFavorite ? $t('favoriteButton.remove') : $t('favoriteButton.add') ">
<c-button
variant="text"
circle
:type="buttonType"
:style="{ opacity: isFavorite ? 1 : 0.2 }"
@click="toggleFavorite"
>
<icon-mdi-heart />
</c-button>
</c-tooltip>
</template>

View file

@ -1,36 +1,17 @@
<template>
<n-form-item :label="inputLabel" v-bind="validationAttrs">
<n-input
ref="inputElement"
v-model:value="input"
:placeholder="inputPlaceholder"
type="textarea"
rows="20"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
:input-props="{ 'data-test-id': 'input' }"
/>
</n-form-item>
<n-form-item :label="outputLabel">
<textarea-copyable :value="output" :language="outputLanguage" :follow-height-of="inputElement" />
</n-form-item>
</template>
<script setup lang="ts">
import { useValidation, type UseValidationRule } from '@/composable/validation';
import _ from 'lodash';
import type { UseValidationRule } from '@/composable/validation';
import CInputText from '@/ui/c-input-text/c-input-text.vue';
const props = withDefaults(
defineProps<{
transformer?: (v: string) => string;
inputValidationRules?: UseValidationRule<string>[];
inputLabel?: string;
inputPlaceholder?: string;
inputDefault?: string;
outputLabel?: string;
outputLanguage?: string;
transformer?: (v: string) => string
inputValidationRules?: UseValidationRule<string>[]
inputLabel?: string
inputPlaceholder?: string
inputDefault?: string
outputLabel?: string
outputLanguage?: string
}>(),
{
transformer: _.identity,
@ -43,15 +24,34 @@ const props = withDefaults(
},
);
const { transformer, inputValidationRules, inputLabel, outputLabel, outputLanguage, inputPlaceholder, inputDefault } =
toRefs(props);
const { transformer, inputValidationRules, inputLabel, outputLabel, outputLanguage, inputPlaceholder, inputDefault }
= toRefs(props);
const inputElement = ref();
const inputElement = ref<typeof CInputText>();
const input = ref(inputDefault.value);
const output = computed(() => transformer.value(input.value));
const { attrs: validationAttrs } = useValidation({ source: input, rules: inputValidationRules.value });
</script>
<style scoped></style>
<template>
<CInputText
ref="inputElement"
v-model:value="input"
:placeholder="inputPlaceholder"
:label="inputLabel"
rows="20"
autosize
raw-text
multiline
test-id="input"
:validation-rules="inputValidationRules"
monospace
/>
<div overflow-auto>
<div mb-5px>
{{ outputLabel }}
</div>
<textarea-copyable :value="output" :language="outputLanguage" :follow-height-of="inputElement?.inputWrapperRef" />
</div>
</template>

View file

@ -1,43 +1,23 @@
<template>
<n-input v-model:value="value">
<template #suffix>
<n-tooltip trigger="hover">
<template #trigger>
<n-button quaternary circle @click="onCopyClicked">
<n-icon :component="ContentCopyFilled" />
</n-button>
</template>
{{ tooltipText }}
</n-tooltip>
</template>
</n-input>
</template>
<script setup lang="ts">
import { useVModel, useClipboard } from '@vueuse/core';
import { ContentCopyFilled } from '@vicons/material';
import { ref } from 'vue';
import { useVModel } from '@vueuse/core';
import { useCopy } from '@/composable/copy';
const props = defineProps<{ value: string }>();
const emit = defineEmits(['update:value']);
const value = useVModel(props, 'value', emit);
const tooltipText = ref('Copy to clipboard');
const { copy } = useClipboard({ source: value });
function onCopyClicked() {
copy();
tooltipText.value = 'Copied !';
setTimeout(() => {
tooltipText.value = 'Copy to clipboard';
}, 2000);
}
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
const tooltipText = computed(() => isJustCopied.value ? 'Copied!' : 'Copy to clipboard');
</script>
<style scoped>
::v-deep(.n-input-wrapper) {
padding-right: 5px;
}
</style>
<template>
<c-input-text v-model:value="value">
<template #suffix>
<c-tooltip :tooltip="tooltipText">
<c-button circle variant="text" size="small" @click="copy()">
<icon-mdi-content-copy />
</c-button>
</c-tooltip>
</template>
</c-input-text>
</template>

View file

@ -1,14 +1,6 @@
<template>
<div class="menu-icon-item">
<n-icon :component="tool.icon" />
<div v-if="tool.isNew" class="badge"></div>
</div>
</template>
<script setup lang="ts">
import type { Tool } from '@/tools/tools.types';
import { useThemeVars } from 'naive-ui';
import { toRefs } from 'vue';
import type { Tool } from '@/tools/tools.types';
const props = defineProps<{ tool: Tool }>();
const { tool } = toRefs(props);
@ -16,6 +8,13 @@ const { tool } = toRefs(props);
const theme = useThemeVars();
</script>
<template>
<div class="menu-icon-item">
<n-icon :component="tool.icon" />
<div v-if="tool.isNew" class="badge" />
</div>
</template>
<style lang="less" scoped>
.menu-icon-item {
position: relative;

View file

@ -1,3 +1,11 @@
<script setup lang="ts">
import { useStyleStore } from '@/stores/style.store';
const styleStore = useStyleStore();
const { isMenuCollapsed, isSmallScreen } = toRefs(styleStore);
const siderPosition = computed(() => (isSmallScreen.value ? 'absolute' : 'static'));
</script>
<template>
<n-layout has-sider>
<n-layout-sider
@ -19,15 +27,6 @@
</n-layout>
</template>
<script setup lang="ts">
import { useStyleStore } from '@/stores/style.store';
import { toRefs, computed } from 'vue';
const styleStore = useStyleStore();
const { isMenuCollapsed, isSmallScreen } = toRefs(styleStore);
const siderPosition = computed(() => (isSmallScreen.value ? 'absolute' : 'static'));
</script>
<style lang="less" scoped>
.overlay {
position: absolute;

View file

@ -1,71 +1,51 @@
<template>
<n-tooltip trigger="hover">
<template #trigger>
<n-button
size="large"
circle
quaternary
tag="a"
href="https://github.com/CorentinTh/it-tools"
rel="noopener"
target="_blank"
aria-label="IT-Tools' GitHub repository"
>
<n-icon size="25" :component="BrandGithub" />
</n-button>
</template>
Github repository
</n-tooltip>
<n-tooltip trigger="hover">
<template #trigger>
<n-button
size="large"
circle
quaternary
tag="a"
href="https://twitter.com/ittoolsdottech"
rel="noopener"
target="_blank"
aria-label="IT Tools' Twitter account"
>
<n-icon size="25" :component="BrandTwitter" />
</n-button>
</template>
IT Tools' Twitter account
</n-tooltip>
<router-link to="/about" #="{ navigate, href }" custom>
<n-tooltip trigger="hover">
<template #trigger>
<n-button tag="a" :href="href" circle quaternary size="large" aria-label="About" @click="navigate">
<n-icon size="25" :component="InfoCircle" />
</n-button>
</template>
About
</n-tooltip>
</router-link>
<n-tooltip trigger="hover">
<template #trigger>
<n-button size="large" circle quaternary aria-label="Toggle dark/light mode" @click="isDarkTheme = !isDarkTheme">
<n-icon v-if="isDarkTheme" size="25" :component="Sun" />
<n-icon v-else size="25" :component="Moon" />
</n-button>
</template>
<span v-if="isDarkTheme">Light mode</span>
<span v-else>Dark mode</span>
</n-tooltip>
</template>
<script setup lang="ts">
import { IconBrandGithub, IconBrandX, IconInfoCircle, IconMoon, IconSun } from '@tabler/icons-vue';
import { useStyleStore } from '@/stores/style.store';
import { BrandGithub, BrandTwitter, InfoCircle, Moon, Sun } from '@vicons/tabler';
import { toRefs } from 'vue';
const styleStore = useStyleStore();
const { isDarkTheme } = toRefs(styleStore);
</script>
<template>
<c-tooltip :tooltip="$t('home.nav.github')" position="bottom">
<c-button
circle
variant="text"
href="https://github.com/CorentinTh/it-tools"
target="_blank"
rel="noopener noreferrer"
:aria-label="$t('home.nav.githubRepository')"
>
<n-icon size="25" :component="IconBrandGithub" />
</c-button>
</c-tooltip>
<c-tooltip :tooltip="$t('home.nav.twitterX')" position="bottom">
<c-button
circle
variant="text"
href="https://x.com/ittoolsdottech"
rel="noopener"
target="_blank"
:aria-label="$t('home.nav.twitterXAccount')"
>
<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="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="IconSun" />
<n-icon v-else size="25" :component="IconMoon" />
</c-button>
</c-tooltip>
</template>
<style lang="less" scoped>
.n-button {
&:not(:last-child) {

View file

@ -1,110 +0,0 @@
<script lang="ts" setup>
import { useFuzzySearch } from '@/composable/fuzzySearch';
import { useTracker } from '@/modules/tracker/tracker.services';
import { tools } from '@/tools';
import type { Tool } from '@/tools/tools.types';
import { SearchRound } from '@vicons/material';
import { useMagicKeys, whenever } from '@vueuse/core';
import type { NInput } from 'naive-ui';
import { computed, h, ref } from 'vue';
import { useRouter } from 'vue-router';
import SearchBarItem from './SearchBarItem.vue';
const toolToOption = (tool: Tool) => ({ label: tool.name, value: tool.path, tool });
const router = useRouter();
const { tracker } = useTracker();
const queryString = ref('');
const inputEl = ref<HTMLElement>();
const displayDropDown = ref(true);
const isMac = computed(() => window.navigator.userAgent.toLowerCase().includes('mac'));
const options = computed(() => {
if (queryString.value === '') {
return tools.map(toolToOption);
}
return searchResult.value.map(toolToOption);
});
const { searchResult } = useFuzzySearch({
search: queryString,
data: tools,
options: { keys: [{ name: 'name', weight: 2 }, 'description', 'keywords'] },
});
const keys = useMagicKeys({
passive: false,
onEventFired(e) {
if (e.ctrlKey && e.key === 'k' && e.type === 'keydown') {
e.preventDefault();
}
if (e.metaKey && e.key === 'k' && e.type === 'keydown') {
e.preventDefault();
}
},
});
whenever(keys.ctrl_k, claimFocus);
whenever(keys.meta_k, claimFocus);
whenever(keys.escape, releaseFocus);
function renderOption({ tool }: { tool: Tool }) {
return h(SearchBarItem, { tool });
}
function onSelect(path: string) {
router.push(path);
queryString.value = '';
}
function claimFocus() {
displayDropDown.value = true;
inputEl.value?.focus();
}
function releaseFocus() {
displayDropDown.value = false;
}
function onFocus() {
tracker.trackEvent({ eventName: 'Search-bar focused' });
displayDropDown.value = true;
}
</script>
<template>
<div class="search-bar">
<n-auto-complete
v-model:value="queryString"
:options="options"
:on-select="(value) => onSelect(String(value))"
:render-label="renderOption"
:default-value="'aa'"
:get-show="() => displayDropDown"
:on-focus="onFocus"
@update:value="() => (displayDropDown = true)"
>
<template #default="{ handleInput, handleBlur, handleFocus, value: slotValue }">
<n-input
ref="inputEl"
round
clearable
:placeholder="`Search a tool (use ${isMac ? 'Cmd' : 'Ctrl'} + K to focus)`"
:value="slotValue"
:input-props="{ autocomplete: 'disabled' }"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur"
>
<template #prefix>
<n-icon :component="SearchRound" />
</template>
</n-input>
</template>
</n-auto-complete>
</div>
</template>

View file

@ -1,45 +0,0 @@
<script lang="ts" setup>
import type { Tool } from '@/tools/tools.types';
import { toRefs } from 'vue';
const props = defineProps<{ tool: Tool }>();
const { tool } = toRefs(props);
</script>
<template>
<div class="search-bar-item">
<n-icon class="icon" :component="tool.icon" />
<div>
<div class="name">{{ tool.name }}</div>
<div class="description">{{ tool.description }}</div>
</div>
</div>
</template>
<style lang="less" scoped>
.search-bar-item {
padding: 10px;
display: flex;
flex-direction: row;
align-items: center;
.icon {
font-size: 30px;
margin-right: 10px;
opacity: 0.7;
}
.name {
font-weight: bold;
font-size: 15px;
line-height: 1;
margin-bottom: 5px;
}
.description {
opacity: 0.7;
line-height: 1;
}
}
</style>

View file

@ -0,0 +1,17 @@
<script setup lang="ts">
import { useCopy } from '@/composable/copy';
const props = withDefaults(defineProps<{ value?: string }>(), { value: '' });
const { value } = toRefs(props);
const initialText = 'Copy to clipboard';
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
const tooltipText = computed(() => isJustCopied.value ? 'Copied!' : initialText);
</script>
<template>
<c-tooltip :tooltip="tooltipText">
<span cursor-pointer font-mono @click="copy()">{{ value }}</span>
</c-tooltip>
</template>

View file

@ -1,6 +1,48 @@
<script setup lang="ts">
import { Copy } from '@vicons/tabler';
import { useElementSize } from '@vueuse/core';
import hljs from 'highlight.js/lib/core';
import jsonHljs from 'highlight.js/lib/languages/json';
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(
defineProps<{
value: string
followHeightOf?: HTMLElement | null
language?: string
copyPlacement?: 'top-right' | 'bottom-right' | 'outside' | 'none'
copyMessage?: string
}>(),
{
followHeightOf: null,
language: 'txt',
copyPlacement: 'top-right',
copyMessage: 'Copy to clipboard',
},
);
hljs.registerLanguage('sql', sqlHljs);
hljs.registerLanguage('json', jsonHljs);
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) };
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
const tooltipText = computed(() => isJustCopied.value ? 'Copied!' : copyMessage.value);
</script>
<template>
<div style="overflow-x: hidden; width: 100%">
<n-card class="result-card">
<c-card relative>
<n-scrollbar
x-scrollable
trigger="none"
@ -10,93 +52,25 @@
<n-code :code="value" :language="language" :trim="false" data-test-id="area-content" />
</n-config-provider>
</n-scrollbar>
<n-tooltip v-if="value" trigger="hover">
<template #trigger>
<div class="copy-button" :class="[copyPlacement]">
<n-button circle secondary size="large" @click="onCopyClicked">
<div absolute right-10px top-10px>
<c-tooltip v-if="value" :tooltip="tooltipText" position="left">
<c-button circle important:h-10 important:w-10 @click="copy()">
<n-icon size="22" :component="Copy" />
</n-button>
</c-button>
</c-tooltip>
</div>
</c-card>
<div v-if="copyPlacement === 'outside'" mt-4 flex justify-center>
<c-button @click="copy()">
{{ tooltipText }}
</c-button>
</div>
</template>
<span>{{ tooltipText }}</span>
</n-tooltip>
</n-card>
<n-space v-if="copyPlacement === 'outside'" justify="center" mt-4>
<n-button secondary @click="onCopyClicked"> {{ tooltipText }} </n-button>
</n-space>
</div>
</template>
<script setup lang="ts">
import { Copy } from '@vicons/tabler';
import { useClipboard, useElementSize } from '@vueuse/core';
import hljs from 'highlight.js/lib/core';
import jsonHljs from 'highlight.js/lib/languages/json';
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 { ref, toRefs } from 'vue';
hljs.registerLanguage('sql', sqlHljs);
hljs.registerLanguage('json', jsonHljs);
hljs.registerLanguage('html', xmlHljs);
hljs.registerLanguage('yaml', yamlHljs);
const props = withDefaults(
defineProps<{
value: string;
followHeightOf?: HTMLElement | null;
language?: string;
copyPlacement?: 'top-right' | 'bottom-right' | 'outside' | 'none';
copyMessage?: string;
}>(),
{
followHeightOf: null,
language: 'txt',
copyPlacement: 'top-right',
copyMessage: 'Copy to clipboard',
},
);
const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(props);
const { height } = followHeightOf ? useElementSize(followHeightOf) : { height: ref(null) };
const { copy } = useClipboard({ source: value });
const tooltipText = ref(copyMessage.value);
function onCopyClicked() {
copy();
tooltipText.value = 'Copied !';
setTimeout(() => {
tooltipText.value = copyMessage.value;
}, 2000);
}
</script>
<style lang="less" scoped>
::v-deep(.n-scrollbar) {
padding-bottom: 10px;
margin-bottom: -10px;
}
.result-card {
position: relative;
.copy-button {
position: absolute;
opacity: 1;
&.top-right {
top: 10px;
right: 10px;
}
&.bottom-right {
bottom: 10px;
right: 10px;
}
&.outside,
&.none {
display: none;
}
}
}
</style>

View file

@ -1,72 +1,41 @@
<template>
<router-link :to="tool.path">
<n-card class="tool-card">
<n-space justify="space-between" align="center">
<n-icon class="icon" size="40" :component="tool.icon" />
<n-space align="center">
<n-tag
v-if="tool.isNew"
size="small"
class="badge-new"
round
type="success"
:bordered="false"
:color="{ color: theme.primaryColor, textColor: theme.tagColor }"
>
New
</n-tag>
<favorite-button :tool="tool" />
</n-space>
</n-space>
<n-h3 class="title">
<n-ellipsis>{{ tool.name }}</n-ellipsis>
</n-h3>
<div class="description">
<n-ellipsis :line-clamp="2" :tooltip="false" style="min-height: 44.78px">
{{ tool.description }}
<br />&nbsp;
</n-ellipsis>
</div>
</n-card>
</router-link>
</template>
<script setup lang="ts">
import type { Tool } from '@/tools/tools.types';
import { useThemeVars } from 'naive-ui';
import { toRefs } from 'vue';
import FavoriteButton from './FavoriteButton.vue';
import type { Tool } from '@/tools/tools.types';
const props = defineProps<{ tool: Tool & { category: string } }>();
const { tool } = toRefs(props);
const theme = useThemeVars();
</script>
<style lang="less" scoped>
a {
text-decoration: none;
}
<template>
<router-link :to="tool.path" class="decoration-none">
<c-card class="h-full transition transition-duration-0.5s !border-2px !hover:border-primary">
<div flex items-center justify-between>
<n-icon class="text-neutral-400 dark:text-neutral-600" size="40" :component="tool.icon" />
.tool-card {
&:hover {
border-color: var(--n-color-target);
}
<div flex items-center gap-8px>
<div
v-if="tool.isNew"
class="rounded-full px-8px py-3px text-xs text-white dark:text-neutral-800"
:style="{
'background-color': theme.primaryColor,
}"
>
{{ $t('toolCard.new') }}
</div>
.icon {
opacity: 0.6;
color: v-bind('theme.textColorBase');
}
<FavoriteButton :tool="tool" />
</div>
</div>
.title {
margin: 5px 0;
}
<div class="truncat my-5px text-lg text-black dark:text-white">
{{ tool.name }}
</div>
.description {
opacity: 0.6;
color: v-bind('theme.textColorBase');
margin: 5px 0;
}
}
</style>
<div class="line-clamp-2 text-neutral-500 dark:text-neutral-400">
{{ tool.description }}
</div>
</c-card>
</router-link>
</template>

View file

@ -0,0 +1,22 @@
import { type Ref, ref, watchEffect } from 'vue';
export { computedCatch };
function computedCatch<T, D>(getter: () => T, { defaultValue }: { defaultValue: D; defaultErrorMessage?: string }): [Ref<T | D>, Ref<string | undefined>];
function computedCatch<T, D>(getter: () => T, { defaultValue, defaultErrorMessage = 'Unknown error' }: { defaultValue?: D; defaultErrorMessage?: string } = {}) {
const error = ref<string | undefined>();
const value = ref<T | D | undefined>();
watchEffect(() => {
try {
error.value = undefined;
value.value = getter();
}
catch (err) {
error.value = err instanceof Error ? err.message : err?.toString() ?? defaultErrorMessage;
value.value = defaultValue;
}
});
return [value, error] as const;
}

View file

@ -11,7 +11,8 @@ function computedRefreshable<T>(getter: () => T, { throttle }: { throttle?: numb
if (throttle) {
watchThrottled(getter, update, { throttle });
} else {
}
else {
watch(getter, update);
}

View file

@ -1,15 +1,30 @@
// eslint-disable-next-line no-restricted-imports
import { useClipboard } from '@vueuse/core';
import { useMessage } from 'naive-ui';
import type { Ref } from 'vue';
import type { MaybeRefOrGetter } from 'vue';
export function useCopy({ source, text = 'Copied to the clipboard', createToast = true }: { source?: MaybeRefOrGetter<string>; text?: string; createToast?: boolean } = {}) {
const { copy, copied, ...rest } = useClipboard({
source,
legacy: true,
});
export function useCopy({ source, text = 'Copied to the clipboard' }: { source: Ref; text?: string }) {
const { copy } = useClipboard({ source });
const message = useMessage();
return {
async copy() {
...rest,
isJustCopied: copied,
async copy(content?: string, { notificationMessage }: { notificationMessage?: string } = {}) {
if (source) {
await copy();
message.success(text);
}
else {
await copy(content);
}
if (createToast) {
message.success(notificationMessage ?? text);
}
},
};
}

View 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;

View file

@ -0,0 +1,32 @@
import { describe, expect, it } from 'vitest';
import { getMimeTypeFromBase64 } from './downloadBase64';
describe('downloadBase64', () => {
describe('getMimeTypeFromBase64', () => {
it('when the base64 string has a data URI, it returns the mime type', () => {
expect(getMimeTypeFromBase64({ base64String: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA' })).to.deep.equal({ mimeType: 'image/png' });
expect(getMimeTypeFromBase64({ base64String: 'data:image/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA' })).to.deep.equal({ mimeType: 'image/jpg' });
});
it('when the base64 string has no data URI, it try to infer the mime type from the signature', () => {
// https://en.wikipedia.org/wiki/List_of_file_signatures
// PNG
expect(getMimeTypeFromBase64({ base64String: 'iVBORw0KGgoAAAANSUhEUgAAAAUA' })).to.deep.equal({ mimeType: 'image/png' });
// GIF
expect(getMimeTypeFromBase64({ base64String: 'R0lGODdh' })).to.deep.equal({ mimeType: 'image/gif' });
expect(getMimeTypeFromBase64({ base64String: 'R0lGODlh' })).to.deep.equal({ mimeType: 'image/gif' });
// JPG
expect(getMimeTypeFromBase64({ base64String: '/9j/' })).to.deep.equal({ mimeType: 'image/jpg' });
// PDF
expect(getMimeTypeFromBase64({ base64String: 'JVBERi0' })).to.deep.equal({ mimeType: 'application/pdf' });
});
it('when the base64 string has no data URI and no signature, it returns an undefined mimeType', () => {
expect(getMimeTypeFromBase64({ base64String: 'JVBERi' })).to.deep.equal({ mimeType: undefined });
});
});
});

View file

@ -1,37 +1,118 @@
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';
function getFileExtensionFromBase64({
base64String,
export {
getMimeTypeFromBase64,
getMimeTypeFromExtension, getExtensionFromMimeType,
useDownloadFileFromBase64, useDownloadFileFromBase64Refs,
previewImageFromBase64,
};
const commonMimeTypesSignatures = {
'JVBERi0': 'application/pdf',
'R0lGODdh': 'image/gif',
'R0lGODlh': 'image/gif',
'iVBORw0KGgo': 'image/png',
'/9j/': 'image/jpg',
};
function getMimeTypeFromBase64({ base64String }: { base64String: string }) {
const [,mimeTypeFromBase64] = base64String.match(/data:(.*?);base64/i) ?? [];
if (mimeTypeFromBase64) {
return { mimeType: mimeTypeFromBase64 };
}
const inferredMimeType = _.find(commonMimeTypesSignatures, (_mimeType, signature) => base64String.startsWith(signature));
if (inferredMimeType) {
return { mimeType: inferredMimeType };
}
return { mimeType: undefined };
}
function getFileExtensionFromMimeType({
mimeType,
defaultExtension = 'txt',
}: {
base64String: string;
defaultExtension?: string;
mimeType: string | undefined
defaultExtension?: string
}) {
const hasMimeType = base64String.match(/data:(.*?);base64/i);
if (hasMimeType) {
return getExtensionFromMime(hasMimeType[1]) || defaultExtension;
if (mimeType) {
return getExtensionFromMimeType(mimeType) ?? defaultExtension;
}
return defaultExtension;
}
export function useDownloadFileFromBase64({ source, filename }: { source: Ref<string>; filename?: string }) {
return {
download() {
const base64String = source.value;
if (base64String === '') {
function downloadFromBase64({ sourceValue, filename, extension, fileMimeType }:
{ sourceValue: string; filename?: string; extension?: string; fileMimeType?: string }) {
if (sourceValue === '') {
throw new Error('Base64 string is empty');
}
const cleanFileName = filename ?? `file.${getFileExtensionFromBase64({ base64String })}`;
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 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;
}

View file

@ -1,4 +1,4 @@
import { get, type MaybeRef } from '@vueuse/core';
import { type MaybeRef, get } from '@vueuse/core';
import Fuse from 'fuse.js';
import { computed } from 'vue';
@ -9,14 +9,21 @@ function useFuzzySearch<Data>({
data,
options = {},
}: {
search: MaybeRef<string>;
data: Data[];
options?: Fuse.IFuseOptions<Data>;
search: MaybeRef<string>
data: Data[]
options?: Fuse.IFuseOptions<Data> & { filterEmpty?: boolean }
}) {
const fuse = new Fuse(data, options);
const filterEmpty = options.filterEmpty ?? true;
const searchResult = computed(() => {
return fuse.search(get(search)).map(({ item }) => item);
const searchResult = computed<Data[]>(() => {
const query = get(search);
if (!filterEmpty && query === '') {
return data;
}
return fuse.search(query).map(({ item }) => item);
});
return { searchResult };

View file

@ -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 }) {
@ -26,10 +33,34 @@ function useQueryParam<T>({ name, defaultValue }: { name: string; defaultValue:
return computed<T>({
get() {
return transformer.fromQuery(proxy.value) as T;
return transformer.fromQuery(proxy.value) as unknown as T;
},
set(value) {
proxy.value = transformer.toQuery(value as never);
},
});
}
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;
}

View file

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-empty-function */
import { describe, expect, it } from 'vitest';
import { isFalsyOrHasThrown } from './validation';
@ -11,7 +10,7 @@ describe('useValidation', () => {
expect(isFalsyOrHasThrown(() => {})).toBe(true);
expect(
isFalsyOrHasThrown(() => {
throw new Error();
throw new Error('message');
}),
).toBe(true);
});

View file

@ -1,44 +1,59 @@
import { type MaybeRef, get } from '@vueuse/core';
import _ from 'lodash';
import { reactive, watch, type Ref } from 'vue';
import { type Ref, reactive, watch } from 'vue';
type ValidatorReturnType = unknown;
type GetErrorMessageReturnType = string;
export interface UseValidationRule<T> {
validator: (value: T) => ValidatorReturnType;
message: string;
validator: (value: T) => ValidatorReturnType
getErrorMessage?: (value: T) => GetErrorMessageReturnType
message: string
}
export function isFalsyOrHasThrown(cb: () => ValidatorReturnType): boolean {
try {
const returnValue = cb();
if (_.isNil(returnValue)) return true;
if (_.isNil(returnValue)) {
return true;
}
return returnValue === false;
} catch (_) {
}
catch (_) {
return true;
}
}
export type ValidationAttrs = {
feedback: string;
validationStatus: string | undefined;
};
export function getErrorMessageOrThrown(cb: () => GetErrorMessageReturnType): string {
try {
return cb() || '';
}
catch (e: any) {
return e.toString();
}
}
export interface ValidationAttrs {
feedback: string
validationStatus: string | undefined
}
export function useValidation<T>({
source,
rules,
watch: watchRefs = [],
}: {
source: Ref<T>;
rules: UseValidationRule<T>[];
watch?: Ref<unknown>[];
source: Ref<T>
rules: MaybeRef<UseValidationRule<T>[]>
watch?: Ref<unknown>[]
}) {
const state = reactive<{
message: string;
status: undefined | 'error';
isValid: boolean;
attrs: ValidationAttrs;
message: string
status: undefined | 'error'
isValid: boolean
attrs: ValidationAttrs
}>({
message: '',
status: undefined,
@ -55,9 +70,15 @@ export function useValidation<T>({
state.message = '';
state.status = undefined;
for (const rule of rules) {
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';
}
}

View file

@ -23,9 +23,9 @@ export const config = figue({
env: {
doc: 'Application current env',
format: 'enum',
values: ['production', 'development', 'test'],
values: ['production', 'development', 'preview', 'test'],
default: 'development',
env: 'MODE',
env: 'VITE_VERCEL_ENV',
},
},
plausible: {
@ -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,

View file

@ -1,19 +1,19 @@
<script lang="ts" setup>
import { NIcon, useThemeVars } from 'naive-ui';
import { computed } from 'vue';
import { RouterLink } from 'vue-router';
import { Heart, Menu2, Home2 } from '@vicons/tabler';
import { toolsByCategory } from '@/tools';
import { Heart, Home2, Menu2 } from '@vicons/tabler';
import { storeToRefs } from 'pinia';
import HeroGradient from '../assets/hero-gradient.svg?component';
import MenuLayout from '../components/MenuLayout.vue';
import NavbarButtons from '../components/NavbarButtons.vue';
import { useStyleStore } from '@/stores/style.store';
import { config } from '@/config';
import type { ToolCategory } from '@/tools/tools.types';
import { useToolStore } from '@/tools/tools.store';
import { useTracker } from '@/modules/tracker/tracker.services';
import CollapsibleToolMenu from '@/components/CollapsibleToolMenu.vue';
import SearchBar from '../components/SearchBar.vue';
import HeroGradient from '../assets/hero-gradient.svg?component';
import MenuLayout from '../components/MenuLayout.vue';
import NavbarButtons from '../components/NavbarButtons.vue';
const themeVars = useThemeVars();
const styleStore = useStyleStore();
@ -21,116 +21,108 @@ const version = config.app.version;
const commitSha = config.app.lastCommitSha.slice(0, 7);
const { tracker } = useTracker();
const { t } = useI18n();
const toolStore = useToolStore();
const { favoriteTools, toolsByCategory } = storeToRefs(toolStore);
const tools = computed<ToolCategory[]>(() => [
...(toolStore.favoriteTools.length > 0 ? [{ name: 'Your favorite tools', components: toolStore.favoriteTools }] : []),
...toolsByCategory,
...(favoriteTools.value.length > 0 ? [{ name: t('tools.categories.favorite-tools'), components: favoriteTools.value }] : []),
...toolsByCategory.value,
]);
</script>
<template>
<menu-layout class="menu-layout" :class="{ isSmallScreen: styleStore.isSmallScreen }">
<MenuLayout class="menu-layout" :class="{ isSmallScreen: styleStore.isSmallScreen }">
<template #sider>
<router-link to="/" class="hero-wrapper">
<hero-gradient class="gradient" />
<RouterLink to="/" class="hero-wrapper">
<HeroGradient class="gradient" />
<div class="text-wrapper">
<div class="title">IT - TOOLS</div>
<div class="divider" />
<div class="subtitle">Handy tools for developers</div>
<div class="title">
IT - TOOLS
</div>
</router-link>
<div class="divider" />
<div class="subtitle">
{{ $t('home.subtitle') }}
</div>
</div>
</RouterLink>
<div class="sider-content">
<n-space v-if="styleStore.isSmallScreen" justify="center">
<navbar-buttons />
</n-space>
<div v-if="styleStore.isSmallScreen" flex flex-col items-center>
<locale-selector w="90%" />
<collapsible-tool-menu :tools-by-category="tools" />
<div flex justify-center>
<NavbarButtons />
</div>
</div>
<CollapsibleToolMenu :tools-by-category="tools" />
<div class="footer">
<div>
IT-Tools
<n-button
text
tag="a"
target="_blank"
rel="noopener"
type="primary"
depth="3"
:href="`https://github.com/CorentinTh/it-tools/tree/v${version}`"
>
<c-link target="_blank" rel="noopener" :href="`https://github.com/CorentinTh/it-tools/tree/v${version}`">
v{{ version }}
</n-button>
</c-link>
<template v-if="commitSha && commitSha.length > 0">
-
<n-button
text
tag="a"
<c-link
target="_blank"
rel="noopener"
type="primary"
depth="3"
:href="`https://github.com/CorentinTh/it-tools/tree/${commitSha}`"
>
{{ commitSha }}
</n-button>
</c-link>
</template>
</div>
<div>
© {{ new Date().getFullYear() }}
<n-button text tag="a" target="_blank" rel="noopener" type="primary" href="https://github.com/CorentinTh">
<c-link target="_blank" rel="noopener" href="https://corentin.tech?utm_source=it-tools&utm_medium=footer">
Corentin Thomasset
</n-button>
</c-link>
</div>
</div>
</div>
</template>
<template #content>
<div class="navigation">
<n-button
:size="styleStore.isSmallScreen ? 'medium' : 'large'"
<div flex items-center justify-center gap-2>
<c-button
circle
quaternary
aria-label="Toggle menu"
variant="text"
:aria-label="$t('home.toggleMenu')"
@click="styleStore.isMenuCollapsed = !styleStore.isMenuCollapsed"
>
<n-icon size="25" :component="Menu2" />
</n-button>
<NIcon size="25" :component="Menu2" />
</c-button>
<router-link to="/" #="{ navigate, href }" custom>
<n-tooltip trigger="hover">
<template #trigger>
<n-button
tag="a"
:href="href"
:size="styleStore.isSmallScreen ? 'medium' : 'large'"
circle
quaternary
aria-label="Home"
@click="navigate"
>
<n-icon size="25" :component="Home2" />
</n-button>
</template>
Home
</n-tooltip>
</router-link>
<c-tooltip :tooltip="$t('home.home')" position="bottom">
<c-button to="/" circle variant="text" :aria-label="$t('home.home')">
<NIcon size="25" :component="Home2" />
</c-button>
</c-tooltip>
<search-bar />
<c-tooltip :tooltip="$t('home.uiLib')" position="bottom">
<c-button v-if="config.app.env === 'development'" to="/c-lib" circle variant="text" :aria-label="$t('home.uiLib')">
<icon-mdi:brush-variant text-20px />
</c-button>
</c-tooltip>
<navbar-buttons v-if="!styleStore.isSmallScreen" />
<command-palette />
<n-tooltip trigger="hover">
<template #trigger>
<n-button
<locale-selector v-if="!styleStore.isSmallScreen" />
<div>
<NavbarButtons v-if="!styleStore.isSmallScreen" />
</div>
<c-tooltip position="bottom" :tooltip="$t('home.support')">
<c-button
round
type="primary"
tag="a"
href="https://www.buymeacoffee.com/cthmsst"
rel="noopener"
target="_blank"
@ -138,16 +130,14 @@ const tools = computed<ToolCategory[]>(() => [
:bordered="false"
@click="() => tracker.trackEvent({ eventName: 'Support button clicked' })"
>
Buy me a coffee
<n-icon v-if="!styleStore.isSmallScreen" :component="Heart" ml-2 />
</n-button>
</template>
Support IT Tools development !
</n-tooltip>
{{ $t('home.buyMeACoffee') }}
<NIcon v-if="!styleStore.isSmallScreen" :component="Heart" ml-2 />
</c-button>
</c-tooltip>
</div>
<slot />
</template>
</menu-layout>
</MenuLayout>
</template>
<style lang="less" scoped>
@ -165,8 +155,8 @@ const tools = computed<ToolCategory[]>(() => [
.support-button {
background: rgb(37, 99, 108);
background: linear-gradient(48deg, rgba(37, 99, 108, 1) 0%, rgba(59, 149, 111, 1) 60%, rgba(20, 160, 88, 1) 100%);
color: #fff;
transition: all ease 0.2s;
color: #fff !important;
transition: padding ease 0.2s !important;
&:hover {
color: #fff;
@ -225,25 +215,4 @@ const tools = computed<ToolCategory[]>(() => [
}
}
}
// ::v-deep(.n-menu-item-content-header) {
// overflow: visible !important;
// // overflow-x: hidden !important;
// }
.navigation {
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
& > *:not(:last-child) {
margin-right: 5px;
}
.search-bar {
// width: 100%;
flex-grow: 1;
}
}
</style>

View file

@ -2,10 +2,10 @@
import { useRoute } from 'vue-router';
import { useHead } from '@vueuse/head';
import type { HeadObject } from '@vueuse/head';
import { computed } from 'vue';
import BaseLayout from './base.layout.vue';
import FavoriteButton from '@/components/FavoriteButton.vue';
import type { Tool } from '@/tools/tools.types';
import BaseLayout from './base.layout.vue';
const route = useRoute();
@ -23,26 +23,31 @@ const head = computed<HeadObject>(() => ({
],
}));
useHead(head);
const { t } = useI18n();
const i18nKey = computed<string>(() => route.path.trim().replace('/', ''));
const toolTitle = computed<string>(() => t(`tools.${i18nKey.value}.title`, String(route.meta.name)));
const toolDescription = computed<string>(() => t(`tools.${i18nKey.value}.description`, String(route.meta.description)));
</script>
<template>
<base-layout>
<BaseLayout>
<div class="tool-layout">
<div class="tool-header">
<n-space align="center" justify="space-between" :wrap="false">
<div flex flex-nowrap items-center justify-between>
<n-h1>
{{ route.meta.name }}
{{ toolTitle }}
</n-h1>
<div>
<favorite-button :tool="{name: route.meta.name} as Tool" />
<FavoriteButton :tool="{ name: route.meta.name, path: route.path } as Tool" />
</div>
</div>
</n-space>
<div class="separator" />
<div class="description">
{{ route.meta.description }}
{{ toolDescription }}
</div>
</div>
</div>
@ -50,7 +55,7 @@ useHead(head);
<div class="tool-content">
<slot />
</div>
</base-layout>
</BaseLayout>
</template>
<style lang="less" scoped>

View file

@ -1,25 +1,29 @@
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import { createHead } from '@vueuse/head';
// eslint-disable-next-line import/no-unresolved
import { registerSW } from 'virtual:pwa-register';
import shadow from 'vue-shadow-dom';
import { plausible } from './plugins/plausible.plugin';
import 'virtual:uno.css';
registerSW();
import { naive } from './plugins/naive.plugin';
import App from './App.vue';
import router from './router';
import { i18nPlugin } from './plugins/i18n.plugin';
registerSW();
const app = createApp(App);
app.use(createPinia());
app.use(createHead());
app.use(i18nPlugin);
app.use(router);
app.use(naive);
app.use(plausible);
app.use(shadow);
app.mount('#app');

View file

@ -0,0 +1,91 @@
import { defineStore } from 'pinia';
import _ from 'lodash';
import type { PaletteOption } from './command-palette.types';
import { useToolStore } from '@/tools/tools.store';
import { useFuzzySearch } from '@/composable/fuzzySearch';
import { useStyleStore } from '@/stores/style.store';
import SunIcon from '~icons/mdi/white-balance-sunny';
import GithubIcon from '~icons/mdi/github';
import BugIcon from '~icons/mdi/bug-outline';
import DiceIcon from '~icons/mdi/dice-5';
import InfoIcon from '~icons/mdi/information-outline';
export const useCommandPaletteStore = defineStore('command-palette', () => {
const toolStore = useToolStore();
const styleStore = useStyleStore();
const router = useRouter();
const searchPrompt = ref('');
const toolsOptions = toolStore.tools.map(tool => ({
...tool,
to: tool.path,
toolCategory: tool.category,
category: 'Tools',
}));
const searchOptions: PaletteOption[] = [
...toolsOptions,
{
name: 'Random tool',
description: 'Get a random tool from the list.',
action: () => {
const { path } = _.sample(toolStore.tools)!;
router.push(path);
},
icon: DiceIcon,
category: 'Tools',
keywords: ['random', 'tool', 'pick', 'choose', 'select'],
closeOnSelect: true,
},
{
name: 'Toggle dark mode',
description: 'Toggle dark mode on or off.',
action: () => styleStore.toggleDark(),
icon: SunIcon,
category: 'Actions',
keywords: ['dark', 'theme', 'toggle', 'mode', 'light', 'system'],
},
{
name: 'Github repository',
href: 'https://github.com/CorentinTh/it-tools',
category: 'External',
description: 'View the source code of it-tools on Github.',
keywords: ['github', 'repo', 'repository', 'source', 'code'],
icon: GithubIcon,
},
{
name: 'Report a bug or an issue',
description: 'Report a bug or an issue to help improve it-tools.',
href: 'https://github.com/CorentinTh/it-tools/issues/new/choose',
category: 'Actions',
keywords: ['report', 'issue', 'bug', 'problem', 'error'],
icon: BugIcon,
},
{
name: 'About',
description: 'Learn more about IT-Tools.',
to: '/about',
category: 'Pages',
keywords: ['about', 'learn', 'more', 'info', 'information'],
icon: InfoIcon,
},
];
const { searchResult } = useFuzzySearch({
search: searchPrompt,
data: searchOptions,
options: {
keys: [{ name: 'name', weight: 2 }, 'description', 'keywords', 'category'],
threshold: 0.3,
},
});
const filteredSearchResult = computed(() =>
_.chain(searchResult.value).groupBy('category').mapValues(categoryOptions => _.take(categoryOptions, 5)).value());
return {
filteredSearchResult,
searchPrompt,
};
});

View file

@ -0,0 +1,14 @@
import type { Component } from 'vue';
import type { RouteLocationRaw } from 'vue-router';
export interface PaletteOption {
name: string
description?: string
icon?: Component
action?: () => void
to?: RouteLocationRaw
category: string
keywords?: string[]
href?: string
closeOnSelect?: boolean
}

View file

@ -0,0 +1,154 @@
<script setup lang="ts">
import { storeToRefs } from 'pinia';
import _ from 'lodash';
import { useCommandPaletteStore } from './command-palette.store';
import type { PaletteOption } from './command-palette.types';
const isModalOpen = ref(false);
const inputRef = ref();
const router = useRouter();
const isMac = computed(() => window.navigator.userAgent.toLowerCase().includes('mac'));
const commandPaletteStore = useCommandPaletteStore();
const { searchPrompt, filteredSearchResult } = storeToRefs(commandPaletteStore);
const keys = useMagicKeys({
passive: false,
onEventFired(e) {
if (e.ctrlKey && e.key === 'k' && e.type === 'keydown') {
e.preventDefault();
}
if (e.metaKey && e.key === 'k' && e.type === 'keydown') {
e.preventDefault();
}
},
});
whenever(isModalOpen, () => inputRef.value?.focus());
whenever(keys.ctrl_k, open);
whenever(keys.meta_k, open);
whenever(keys.escape, close);
function open() {
return isModalOpen.value = true;
}
function close() {
isModalOpen.value = false;
searchPrompt.value = '';
}
const selectedOptionIndex = ref(0);
function handleKeydown(event: KeyboardEvent) {
const { key } = event;
const isEnterPressed = key === 'Enter';
const isArrowUpOrDown = ['ArrowUp', 'ArrowDown'].includes(key);
const isArrowDown = key === 'ArrowDown';
if (isArrowUpOrDown) {
const increment = isArrowDown ? 1 : -1;
const maxIndex = Math.max(_.chain(filteredSearchResult.value).values().flatten().size().value() - 1, 0);
selectedOptionIndex.value = Math.min(Math.max(selectedOptionIndex.value + increment, 0), maxIndex);
return;
}
if (isEnterPressed) {
const option = _.chain(filteredSearchResult.value)
.values()
.flatten()
.nth(selectedOptionIndex.value)
.value();
activateOption(option);
}
}
function getOptionIndex(option: PaletteOption) {
return _.chain(filteredSearchResult.value)
.values()
.flatten()
.findIndex(o => o === option)
.value();
}
function activateOption(option: PaletteOption) {
const { closeOnSelect } = option;
if (option.action) {
option.action();
if (closeOnSelect) {
close();
}
return;
}
const closeAfterNavigation = closeOnSelect || _.isUndefined(closeOnSelect);
if (option.to) {
router.push(option.to);
if (closeAfterNavigation) {
close();
}
return;
}
if (option.href) {
window.open(option.href, '_blank');
if (closeAfterNavigation) {
close();
}
}
}
</script>
<template>
<div flex-1>
<c-button w-full important:justify-start @click="isModalOpen = true">
<span flex items-center gap-3 op-40>
<icon-mdi-search />
{{ $t('search.label') }}
<span hidden flex-1 border border-current border-op-40 rounded border-solid px-5px py-3px sm:inline>
{{ isMac ? 'Cmd' : 'Ctrl' }}&nbsp;+&nbsp;K
</span>
</span>
</c-button>
<c-modal v-model:open="isModalOpen" class="palette-modal" shadow-xl important:max-w-650px important:pa-12px @keydown="handleKeydown">
<c-input-text ref="inputRef" v-model:value="searchPrompt" raw-text placeholder="Type to search a tool or a command..." autofocus clearable />
<div v-for="(options, category) in filteredSearchResult" :key="category">
<div ml-3 mt-3 text-sm font-bold text-primary op-60>
{{ category }}
</div>
<command-palette-option v-for="option in options" :key="option.name" :option="option" :selected="selectedOptionIndex === getOptionIndex(option)" @activated="activateOption" />
</div>
</c-modal>
</div>
</template>
<style scoped lang="less">
.c-input-text {
font-size: 18px;
::v-deep(.input-wrapper) {
padding: 4px;
padding-left: 18px;
}
}
.c-modal--overlay {
align-items: flex-start !important;
padding-top: 80px;
}
</style>

View file

@ -0,0 +1,36 @@
<script setup lang="ts">
import type { PaletteOption } from '../command-palette.types';
const props = withDefaults(defineProps<{ option: PaletteOption; selected?: boolean }>(), {
selected: false,
});
const emit = defineEmits(['activated']);
const { option } = toRefs(props);
const { selected } = toRefs(props);
</script>
<template>
<div
role="option"
:aria-selected="selected"
:class="{
'text-white': selected,
'bg-primary': selected,
}"
w-full flex cursor-pointer items-center overflow-hidden rounded pa-3 transition hover:bg-primary hover:text-white
@click="() => emit('activated', option)"
>
<component :is="option.icon" v-if="option.icon" mr-3 h-30px w-30px shrink-0 op-50 />
<div flex-1 overflow-hidden>
<div truncate font-bold lh-tight op-90>
{{ option.name }}
</div>
<div v-if="option.description" truncate lh-tight op-60>
{{ option.description }}
</div>
</div>
</div>
</template>

View file

@ -0,0 +1,32 @@
<script setup lang="ts">
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: 'Українська',
zh: '中文',
vi: 'Tiếng Việt',
};
const localeOptions = computed(() =>
availableLocales.map(locale => ({
label: localesLong[locale] ?? locale,
value: locale,
})),
);
</script>
<template>
<c-select
v-model:value="locale"
:options="localeOptions"
placeholder="Select a language"
w-100px
/>
</template>

View file

@ -0,0 +1,7 @@
import { format } from 'date-fns';
export { getUrlFriendlyDateTime };
function getUrlFriendlyDateTime({ date = new Date() }: { date?: Date } = {}) {
return format(date, 'yyyy-MM-dd-HH-mm-ss');
}

View file

@ -0,0 +1,5 @@
function clamp({ value, min = 0, max = 100 }: { value: number; min?: number; max?: number }) {
return Math.min(Math.max(value, min), max);
}
export { clamp };

View file

@ -16,7 +16,7 @@ function useTracker() {
const plausible: ReturnType<typeof Plausible> | undefined = inject('plausible');
if (_.isNil(plausible)) {
throw new Error('Plausible must be instantiated');
throw new TypeError('Plausible must be instantiated');
}
const tracker = createTrackerService({ plausible });

View file

@ -1,5 +1,4 @@
<script setup lang="ts">
import { Coffee } from '@vicons/tabler';
import { useHead } from '@vueuse/head';
useHead({ title: 'Page not found - IT Tools' });
@ -7,14 +6,22 @@ useHead({ title: 'Page not found - IT Tools' });
<template>
<div mt-20 flex flex-col items-center>
<n-icon :component="Coffee" size="100" depth="3" />
<span text-90px lh-1 op-50>
<icon-mdi:kettle-steam-outline />
</span>
<n-h1 m-0 mt-3>404 Not Found</n-h1>
<n-text mt-4 block depth="3">Sorry, this page does not seem to exist</n-text>
<n-text mb-8 block depth="3">Maybe the cache is doing tricky things, try force-refreshing?</n-text>
<h1 m-0 mt-3>
{{ $t('404.notFound') }}
</h1>
<div mt-4 op-60>
{{ $t('404.sorry') }}
</div>
<div mb-8 op-60>
{{ $t('404.maybe') }}
</div>
<router-link to="/" #="{ navigate, href }" custom>
<n-button tag="a" :href="href" secondary @click="navigate"> Back home </n-button>
</router-link>
<c-button to="/">
{{ $t('404.backHome') }}
</c-button>
</div>
</template>

View file

@ -1,100 +1,9 @@
<script setup lang="ts">
import { useTracker } from '@/modules/tracker/tracker.services';
import { useHead } from '@vueuse/head';
useHead({ title: 'About - IT Tools' });
const { tracker } = useTracker();
</script>
<template>
<div class="about-page">
<n-h1>About</n-h1>
<n-p>
This wonderful website, made with by
<n-button text tag="a" href="https://github.com/CorentinTh" target="_blank" rel="noopener" type="primary">
Corentin Thomasset </n-button
>, aggregates useful tools for developer and people working in IT. If you find it useful, please fell free to
share it to people you think may find it useful too and don't forget to pin it in your shortcut bar !
</n-p>
<n-p>
IT Tools is open-source (under the MIT license) and free, and will always be, but it cost 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
<n-button
type="primary"
tag="a"
text
href="https://www.buymeacoffee.com/cthmsst"
rel="noopener"
target="_blank"
@click="() => tracker.trackEvent({ eventName: 'Support button clicked' })"
>
sponsoring me </n-button
>.
</n-p>
<n-h2>Technologies</n-h2>
<n-p>
IT Tools is made in Vue JS (vue 3) with the the naive-ui component library and is hosted and continuously deployed
by Vercel. Third party open-source libraries are used in some tools, you may find the complete list in the
<n-button
type="primary"
tag="a"
text
href="https://github.com/CorentinTh/it-tools/blob/main/package.json"
rel="noopener"
target="_blank"
>
package.json
</n-button>
file of the repository.
</n-p>
<n-h2>Found a bug? A tool is missing?</n-h2>
<n-p>
If you need a tool that is currently not present here, and you think can be relevant, you are welcome to submit a
feature request in the
<n-button
type="primary"
tag="a"
text
href="https://github.com/CorentinTh/it-tools/issues/new?assignees=CorentinTh&labels=enhancement&template=feature_request.md&title=%5BFEAT%5D%20My%20feature"
rel="noopener"
target="_blank"
>
issues section
</n-button>
in the GitHub repository.
</n-p>
<n-p>
And if you found a bug, or something broken that doesn't work as expected, please fill a bug report in the
<n-button
type="primary"
tag="a"
text
href="https://github.com/CorentinTh/it-tools/issues/new?assignees=CorentinTh&labels=bug&template=bug_report.md&title=%5BBUG%5D%20My%20bug"
rel="noopener"
target="_blank"
>
issues section
</n-button>
in the GitHub repository.
</n-p>
</div>
<c-markdown :markdown="$t('about.content')" mx-auto mt-50px max-w-600px />
</template>
<style scoped lang="less">
.about-page {
max-width: 600px;
margin: 50px auto;
box-sizing: border-box;
.n-h2 {
margin-bottom: 0px;
}
.n-p {
text-align: justify;
}
}
</style>

View file

@ -1,88 +1,92 @@
<script setup lang="ts">
import { config } from '@/config';
import { useToolStore } from '@/tools/tools.store';
import { Heart } from '@vicons/tabler';
import { IconDragDrop, 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';
import { config } from '@/config';
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="home-page">
<div class="pt-50px">
<div class="grid-wrapper">
<n-grid v-if="config.showBanner" x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
<n-gi>
<colored-card title="You like it-tools?" :icon="Heart">
Give us a star on
<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"
rel="noopener"
target="_blank"
aria-label="IT-Tools' GitHub repository"
>GitHub</a
>
or follow us on
:aria-label="$t('home.follow.githubRepository')"
>GitHub</a>
{{ $t('home.follow.p2') }}
<a
href="https://twitter.com/ittoolsdottech"
href="https://x.com/ittoolsdottech"
rel="noopener"
target="_blank"
aria-label="IT-Tools' Twitter account"
>Twitter</a
>! Thank you
<n-icon :component="Heart" />
</colored-card>
</n-gi>
</n-grid>
:aria-label="$t('home.follow.twitterXAccount')"
>X</a>.
{{ $t('home.follow.thankYou') }}
<n-icon :component="IconHeart" />
</ColoredCard>
</div>
<transition name="height">
<div v-if="toolStore.favoriteTools.length > 0">
<n-h3>Your favorite tools</n-h3>
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
<n-gi v-for="tool in toolStore.favoriteTools" :key="tool.name">
<tool-card :tool="tool" />
</n-gi>
</n-grid>
<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>
<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">
<n-h3>Newest tools</n-h3>
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
<n-gi v-for="tool in toolStore.newTools" :key="tool.name">
<tool-card :tool="tool" />
</n-gi>
</n-grid>
<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">
<ToolCard v-for="tool in toolStore.newTools" :key="tool.name" :tool="tool" />
</div>
</div>
<n-h3>All the tools</n-h3>
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
<n-gi v-for="tool in toolStore.tools" :key="tool.name">
<transition>
<tool-card :tool="tool" />
</transition>
</n-gi>
</n-grid>
<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">
<ToolCard v-for="tool in toolStore.tools" :key="tool.name" :tool="tool" />
</div>
</div>
</div>
</template>
<style scoped lang="less">
.home-page {
padding-top: 50px;
}
.n-h3 {
margin-bottom: 10px;
}
::v-deep(.n-grid) {
margin-bottom: 30px;
}
.height-enter-active,
.height-leave-active {
transition: all 0.5s ease-in-out;
@ -97,4 +101,24 @@ useHead({ title: 'IT Tools - Handy online tools for developers' });
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>

View file

@ -0,0 +1,21 @@
import messages from '@intlify/unplugin-vue-i18n/messages';
import { get } from '@vueuse/core';
import type { Plugin } from 'vue';
import { createI18n } from 'vue-i18n';
const i18n = createI18n({
legacy: false,
locale: 'en',
messages,
});
export const i18nPlugin: Plugin = {
install: (app) => {
app.use(i18n);
},
};
export const translate = function (localeKey: string) {
const hasKey = i18n.global.te(localeKey, get(i18n.global.locale));
return hasKey ? i18n.global.t(localeKey) : localeKey;
};

View file

@ -1,8 +1,8 @@
import { config } from '@/config';
import { noop } from 'lodash';
import Plausible from 'plausible-tracker';
import type { App } from 'vue';
import { config } from '@/config';
function createFakePlausibleInstance(): Pick<ReturnType<typeof Plausible>, 'trackEvent' | 'enableAutoPageviews'> {
return {
@ -15,11 +15,11 @@ function createPlausibleInstance({
config,
}: {
config: {
isTrackerEnabled: boolean;
domain: string;
apiHost: string;
trackLocalhost: boolean;
};
isTrackerEnabled: boolean
domain: string
apiHost: string
trackLocalhost: boolean
}
}) {
if (config.isTrackerEnabled) {
return Plausible(config);

View file

@ -4,6 +4,7 @@ import HomePage from './pages/Home.page.vue';
import NotFound from './pages/404.page.vue';
import { tools } from './tools';
import { config } from './config';
import { routes as demoRoutes } from './ui/demo/demo.routes';
const toolsRoutes = tools.map(({ path, name, component, ...config }) => ({
path,
@ -14,7 +15,7 @@ const toolsRoutes = tools.map(({ path, name, component, ...config }) => ({
const toolsRedirectRoutes = tools
.filter(({ redirectFrom }) => redirectFrom && redirectFrom.length > 0)
.flatMap(
({ path, redirectFrom }) => redirectFrom?.map((redirectSource) => ({ path: redirectSource, redirect: path })) ?? [],
({ path, redirectFrom }) => redirectFrom?.map(redirectSource => ({ path: redirectSource, redirect: path })) ?? [],
);
const router = createRouter({
@ -32,6 +33,7 @@ const router = createRouter({
},
...toolsRoutes,
...toolsRedirectRoutes,
...(config.app.env === 'development' ? demoRoutes : []),
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
],
});

33
src/shims.d.ts vendored
View file

@ -1,10 +1,41 @@
declare module '*.vue' {
import type { ComponentOptions, ComponentOptions } from 'vue';
import type { ComponentOptions } from 'vue';
const Component: ComponentOptions;
export default Component;
}
declare module '*.md' {
import type { ComponentOptions } from 'vue';
const Component: ComponentOptions;
export default Component;
}
declare module 'iarna-toml-esm' {
export const parse: (toml: string) => any;
export const stringify: (obj: any) => string;
}
declare module 'emojilib' {
const lib: Record<string, string[]>;
export default lib;
}
declare module 'unicode-emoji-json' {
const emoji: Record<string, {
name: string;
slug: string;
group: string;
emoji_version: string;
unicode_version: string;
skin_tone_support: boolean;
skin_tone_support_unicode_version: string;
}>;
export default emoji;
}
declare module 'pdf-signature-reader' {
const verifySignature: (pdf: ArrayBuffer) => ({signatures: SignatureInfo[]});
export default verifySignature;
}

View file

@ -1,17 +1,19 @@
import { useMediaQuery, useStorage } from '@vueuse/core';
import { useDark, useMediaQuery, useStorage, useToggle } from '@vueuse/core';
import { defineStore } from 'pinia';
import { watch, type Ref } from 'vue';
import { type Ref, watch } from 'vue';
export const useStyleStore = defineStore('style', {
state: () => {
const isDarkTheme = useStorage('isDarkTheme', true) as Ref<boolean>;
const isDarkTheme = useDark();
const toggleDark = useToggle(isDarkTheme);
const isSmallScreen = useMediaQuery('(max-width: 700px)');
const isMenuCollapsed = useStorage('isMenuCollapsed', isSmallScreen.value) as Ref<boolean>;
watch(isSmallScreen, (v) => (isMenuCollapsed.value = v));
watch(isSmallScreen, v => (isMenuCollapsed.value = v));
return {
isDarkTheme,
toggleDark,
isMenuCollapsed,
isSmallScreen,
};

View file

@ -0,0 +1,93 @@
<script setup lang="ts">
import figlet from 'figlet';
import TextareaCopyable from '@/components/TextareaCopyable.vue';
const input = ref('Ascii ART');
const font = useStorage('ascii-text-drawer:font', 'Standard');
const width = useStorage('ascii-text-drawer:width', 80);
const output = ref('');
const errored = ref(false);
const processing = ref(false);
figlet.defaults({ fontPath: '//unpkg.com/figlet@1.6.0/fonts/' });
watchEffect(async () => {
processing.value = true;
try {
const options: figlet.Options = {
font: font.value as figlet.Fonts,
width: width.value,
whitespaceBreak: true,
};
output.value = await (new Promise<string>((resolve, reject) =>
figlet.text(input.value, options,
(err, text) => {
if (err) {
reject(err);
return;
}
resolve(text ?? '');
})));
errored.value = false;
}
catch (e: any) {
errored.value = true;
}
processing.value = false;
});
const fonts = ['1Row', '3-D', '3D Diagonal', '3D-ASCII', '3x5', '4Max', '5 Line Oblique', 'AMC 3 Line', 'AMC 3 Liv1', 'AMC AAA01', 'AMC Neko', 'AMC Razor', 'AMC Razor2', 'AMC Slash', 'AMC Slider', 'AMC Thin', 'AMC Tubes', 'AMC Untitled', 'ANSI Shadow', 'ASCII New Roman', 'Acrobatic', 'Alligator', 'Alligator2', 'Alpha', 'Alphabet', 'Arrows', 'Avatar', 'B1FF', 'B1FF', 'Banner', 'Banner3-D', 'Banner3', 'Banner4', 'Barbwire', 'Basic', 'Bear', 'Bell', 'Benjamin', 'Big Chief', 'Big Money-ne', 'Big Money-nw', 'Big Money-se', 'Big Money-sw', 'Big', 'Bigfig', 'Binary', 'Block', 'Blocks', 'Bloody', 'Bolger', 'Braced', 'Bright', 'Broadway KB', 'Broadway', 'Bubble', 'Bulbhead', 'Caligraphy', 'Caligraphy2', 'Calvin S', 'Cards', 'Catwalk', 'Chiseled', 'Chunky', 'Coinstak', 'Cola', 'Colossal', 'Computer', 'Contessa', 'Contrast', 'Cosmike', 'Crawford', 'Crawford2', 'Crazy', 'Cricket', 'Cursive', 'Cyberlarge', 'Cybermedium', 'Cybersmall', 'Cygnet', 'DANC4', 'DOS Rebel', 'DWhistled', 'Dancing Font', 'Decimal', 'Def Leppard', 'Delta Corps Priest 1', 'Diamond', 'Diet Cola', 'Digital', 'Doh', 'Doom', 'Dot Matrix', 'Double Shorts', 'Double', 'Dr Pepper', 'Efti Chess', 'Efti Font', 'Efti Italic', 'Efti Piti', 'Efti Robot', 'Efti Wall', 'Efti Water', 'Electronic', 'Elite', 'Epic', 'Fender', 'Filter', 'Fire Font-k', 'Fire Font-s', 'Flipped', 'Flower Power', 'Four Tops', 'Fraktur', 'Fun Face', 'Fun Faces', 'Fuzzy', 'Georgi16', 'Georgia11', 'Ghost', 'Ghoulish', 'Glenyn', 'Goofy', 'Gothic', 'Graceful', 'Gradient', 'Graffiti', 'Greek', 'Heart Left', 'Heart Right', 'Henry 3D', 'Hex', 'Hieroglyphs', 'Hollywood', 'Horizontal Left', 'Horizontal Right', 'ICL-1900', 'Impossible', 'Invita', 'Isometric1', 'Isometric2', 'Isometric3', 'Isometric4', 'Italic', 'Ivrit', 'JS Block Letters', 'JS Bracket Letters', 'JS Capital Curves', 'JS Cursive', 'JS Stick Letters', 'Jacky', 'Jazmine', 'Jerusalem', 'Katakana', 'Kban', 'Keyboard', 'Knob', 'Konto Slant', 'Konto', 'LCD', 'Larry 3D 2', 'Larry 3D', 'Lean', 'Letters', 'Lil Devil', 'Line Blocks', 'Linux', 'Lockergnome', 'Madrid', 'Marquee', 'Maxfour', 'Merlin1', 'Merlin2', 'Mike', 'Mini', 'Mirror', 'Mnemonic', 'Modular', 'Morse', 'Morse2', 'Moscow', 'Mshebrew210', 'Muzzle', 'NScript', 'NT Greek', 'NV Script', 'Nancyj-Fancy', 'Nancyj-Improved', 'Nancyj-Underlined', 'Nancyj', 'Nipples', 'O8', 'OS2', 'Octal', 'Ogre', 'Old Banner', 'Patorjk\'s Cheese', 'Patorjk-HeX', 'Pawp', 'Peaks Slant', 'Peaks', 'Pebbles', 'Pepper', 'Poison', 'Puffy', 'Puzzle', 'Pyramid', 'Rammstein', 'Rectangles', 'Red Phoenix', 'Relief', 'Relief2', 'Reverse', 'Roman', 'Rot13', 'Rot13', 'Rotated', 'Rounded', 'Rowan Cap', 'Rozzo', 'Runic', 'Runyc', 'S Blood', 'SL Script', 'Santa Clara', 'Script', 'Serifcap', 'Shadow', 'Shimrod', 'Short', 'Slant Relief', 'Slant', 'Slide', 'Small Caps', 'Small Isometric1', 'Small Keyboard', 'Small Poison', 'Small Script', 'Small Shadow', 'Small Slant', 'Small Tengwar', 'Small', 'Soft', 'Speed', 'Spliff', 'Stacey', 'Stampate', 'Stampatello', 'Standard', 'Star Strips', 'Star Wars', 'Stellar', 'Stforek', 'Stick Letters', 'Stop', 'Straight', 'Stronger Than All', 'Sub-Zero', 'Swamp Land', 'Swan', 'Sweet', 'THIS', 'Tanja', 'Tengwar', 'Term', 'Test1', 'The Edge', 'Thick', 'Thin', 'Thorned', 'Three Point', 'Ticks Slant', 'Ticks', 'Tiles', 'Tinker-Toy', 'Tombstone', 'Train', 'Trek', 'Tsalagi', 'Tubular', 'Twisted', 'Two Point', 'USA Flag', 'Univers', 'Varsity', 'Wavy', 'Weird', 'Wet Letter', 'Whimsy', 'Wow'];
</script>
<template>
<c-card style="max-width: 600px;">
<c-input-text
v-model:value="input"
label="Your text:"
placeholder="Your text to draw"
raw-text
multiline
rows="4"
/>
<n-divider />
<n-grid cols="4" x-gap="12" w-full>
<n-gi span="2">
<c-select
v-model:value="font"
label-position="top"
label="Font:"
:options="fonts"
searchable="true"
placeholder="Select font to use"
/>
</n-gi>
<n-gi span="2">
<n-form-item label="Width:" label-placement="top" label-width="100" :show-feedback="false">
<n-input-number v-model:value="width" min="0" max="10000" w-full placeholder="Width of the text" />
</n-form-item>
</n-gi>
</n-grid>
<n-divider />
<div v-if="processing" flex items-center justify-center>
<n-spin size="medium" />
<span class="ml-2">Loading font...</span>
</div>
<c-alert v-if="errored" mt-1 text-center type="error">
Current settings resulted in error.
</c-alert>
<n-form-item v-if="!processing && !errored" label="Ascii Art text:">
<TextareaCopyable
:value="output"
mb-1 mt-1
copy-placement="outside"
/>
</n-form-item>
</c-card>
</template>

View file

@ -0,0 +1,12 @@
import { Artboard } from '@vicons/tabler';
import { defineTool } from '../tool';
export const tool = defineTool({
name: 'ASCII Art Text Generator',
path: '/ascii-text-drawer',
description: 'Create ASCII art text with many fonts and styles.',
keywords: ['ascii', 'asciiart', 'text', 'drawer'],
component: () => import('./ascii-text-drawer.vue'),
icon: Artboard,
createdAt: new Date('2024-03-03'),
});

View file

@ -1,87 +1,139 @@
<template>
<n-card title="Base64 to file">
<n-form-item
:feedback="base64InputValidation.message"
:validation-status="base64InputValidation.status"
:show-label="false"
>
<n-input v-model:value="base64Input" type="textarea" placeholder="Put your base64 file string here..." rows="5" />
</n-form-item>
<n-space justify="center">
<n-button :disabled="base64Input === '' || !base64InputValidation.isValid" secondary @click="downloadFile()">
Download file
</n-button>
</n-space>
</n-card>
<n-card title="File to base64">
<n-upload v-model:file-list="fileList" :show-file-list="true" :on-before-upload="onUpload" list-type="image">
<n-upload-dragger>
<div mb-2>
<n-icon size="35" :depth="3" :component="Upload" />
</div>
<n-text style="font-size: 14px"> Click or drag a file to this area to upload </n-text>
</n-upload-dragger>
</n-upload>
<n-input :value="fileBase64" type="textarea" readonly placeholder="File in base64 will be here" />
<n-space justify="center">
<n-button secondary @click="copyFileBase64()"> Copy </n-button>
</n-space>
</n-card>
</template>
<script setup lang="ts">
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';
import { Upload } from '@vicons/tabler';
import { useBase64 } from '@vueuse/core';
import type { UploadFileInfo } from 'naive-ui';
import { ref, type Ref } from 'vue';
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: [
{
message: 'Invalid base 64 string',
validator: (value) => isValidBase64(value.trim()),
validator: value => isValidBase64(value.trim()),
},
],
});
function downloadFile() {
if (!base64InputValidation.isValid) return;
watch(
base64Input,
(newValue, _) => {
const { mimeType } = getMimeTypeFromBase64({ base64String: newValue });
if (mimeType) {
fileExtension.value = getExtensionFromMimeType(mimeType) || fileExtension.value;
}
},
);
function previewImage() {
if (!base64InputValidation.isValid) {
return;
}
try {
download();
} catch (_) {
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;
}
try {
download();
}
catch (_) {
//
}
}
const fileList = ref();
const fileInput = ref() as Ref<File>;
const { base64: fileBase64 } = useBase64(fileInput);
const { copy: copyFileBase64 } = useCopy({ source: fileBase64, text: 'Base64 string copied to the clipboard' });
async function onUpload({ file: { file } }: { file: UploadFileInfo }) {
async function onUpload(file: File) {
if (file) {
fileList.value = [];
fileInput.value = file;
}
}
</script>
<style lang="less" scoped>
.n-input,
.n-upload {
margin-bottom: 15px;
}
<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
placeholder="Put your base64 file string here..."
rows="5"
:validation="base64InputValidation"
mb-2
/>
<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>
</div>
</c-card>
<c-card title="File to base64">
<c-file-upload title="Drag and drop a file here, or click to select a file" @file-upload="onUpload" />
<c-input-text :value="fileBase64" multiline readonly placeholder="File in base64 will be here" rows="5" my-2 />
<div flex justify-center>
<c-button @click="copyFileBase64()">
Copy
</c-button>
</div>
</c-card>
</template>
<style lang="less" scoped>
::v-deep(.n-upload-trigger) {
width: 100%;
}

View file

@ -1,10 +1,11 @@
import { FileDigit } from '@vicons/tabler';
import { defineTool } from '../tool';
import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
name: 'Base64 file converter',
name: translate('tools.base64-file-converter.title'),
path: '/base64-file-converter',
description: "Convert string, files or images into a it's base64 representation.",
description: translate('tools.base64-file-converter.description'),
keywords: ['base64', 'converter', 'upload', 'image', 'file', 'conversion', 'web', 'data', 'format'],
component: () => import('./base64-file-converter.vue'),
icon: FileDigit,

View file

@ -1,55 +1,90 @@
<template>
<n-card title="String to base64">
<n-form-item label="String to encode">
<n-input v-model:value="textInput" type="textarea" placeholder="Put your string here..." rows="5" />
</n-form-item>
<n-form-item label="Base64 of string">
<n-input
:value="base64Output"
type="textarea"
readonly
placeholder="The base64 encoding of your string will be here"
rows="5"
/>
</n-form-item>
<n-space justify="center">
<n-button secondary @click="copyTextBase64()"> Copy base64 </n-button>
</n-space>
</n-card>
<n-card title="Base64 to string">
<n-form-item label="Base64 string to decode" v-bind="b64Validation.attrs">
<n-input v-model:value="base64Input" type="textarea" placeholder="Your base64 string..." rows="5" />
</n-form-item>
<n-form-item label="Decoded string">
<n-input :value="textOutput" type="textarea" readonly placeholder="The decoded string will be here" rows="5" />
</n-form-item>
<n-space justify="center">
<n-button secondary @click="copyText()"> Copy decoded string </n-button>
</n-space>
</n-card>
</template>
<script setup lang="ts">
import { useCopy } from '@/composable/copy';
import { useValidation } from '@/composable/validation';
import { base64ToText, isValidBase64, textToBase64 } from '@/utils/base64';
import { withDefaultOnError } from '@/utils/defaults';
import { computed, ref } from 'vue';
const encodeUrlSafe = useStorage('base64-string-converter--encode-url-safe', false);
const decodeUrlSafe = useStorage('base64-string-converter--decode-url-safe', false);
const textInput = ref('');
const base64Output = computed(() => textToBase64(textInput.value));
const base64Output = computed(() => textToBase64(textInput.value, { makeUrlSafe: encodeUrlSafe.value }));
const { copy: copyTextBase64 } = useCopy({ source: base64Output, text: 'Base64 string copied to the clipboard' });
const base64Input = ref('');
const textOutput = computed(() => withDefaultOnError(() => base64ToText(base64Input.value.trim()), ''));
const textOutput = computed(() =>
withDefaultOnError(() => base64ToText(base64Input.value.trim(), { makeUrlSafe: decodeUrlSafe.value }), ''),
);
const { copy: copyText } = useCopy({ source: textOutput, text: 'String copied to the clipboard' });
const b64Validation = useValidation({
source: base64Input,
rules: [{ message: 'Invalid base64 string', validator: (value) => isValidBase64(value.trim()) }],
});
const b64ValidationRules = [
{
message: 'Invalid base64 string',
validator: (value: string) => isValidBase64(value.trim(), { makeUrlSafe: decodeUrlSafe.value }),
},
];
const b64ValidationWatch = [decodeUrlSafe];
</script>
<template>
<c-card title="String to base64">
<n-form-item label="Encode URL safe" label-placement="left">
<n-switch v-model:value="encodeUrlSafe" />
</n-form-item>
<c-input-text
v-model:value="textInput"
multiline
placeholder="Put your string here..."
rows="5"
label="String to encode"
raw-text
mb-5
/>
<c-input-text
label="Base64 of string"
:value="base64Output"
multiline
readonly
placeholder="The base64 encoding of your string will be here"
rows="5"
mb-5
/>
<div flex justify-center>
<c-button @click="copyTextBase64()">
Copy base64
</c-button>
</div>
</c-card>
<c-card title="Base64 to string">
<n-form-item label="Decode URL safe" label-placement="left">
<n-switch v-model:value="decodeUrlSafe" />
</n-form-item>
<c-input-text
v-model:value="base64Input"
multiline
placeholder="Your base64 string..."
rows="5"
:validation-rules="b64ValidationRules"
:validation-watch="b64ValidationWatch"
label="Base64 string to decode"
mb-5
/>
<c-input-text
v-model:value="textOutput"
label="Decoded string"
placeholder="The decoded string will be here"
multiline
rows="5"
readonly
mb-5
/>
<div flex justify-center>
<c-button @click="copyText()">
Copy decoded string
</c-button>
</div>
</c-card>
</template>

View file

@ -1,10 +1,11 @@
import { FileDigit } from '@vicons/tabler';
import { defineTool } from '../tool';
import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
name: 'Base64 string encoder/decoder',
name: translate('tools.base64-string-converter.title'),
path: '/base64-string-converter',
description: 'Simply encode and decode string into a their base64 representation.',
description: translate('tools.base64-string-converter.description'),
keywords: ['base64', 'converter', 'conversion', 'web', 'data', 'format', 'atob', 'btoa'],
component: () => import('./base64-string-converter.vue'),
icon: FileDigit,

View file

@ -1,37 +1,6 @@
<template>
<div>
<n-form-item label="Username">
<n-input v-model:value="username" placeholder="Your username..." clearable />
</n-form-item>
<n-form-item label="Password">
<n-input
v-model:value="password"
placeholder="Your password..."
type="password"
show-password-on="click"
clearable
/>
</n-form-item>
<br />
<n-card>
<n-statistic label="Authorization header:" class="header">
<n-scrollbar x-scrollable style="max-width: 550px; margin-bottom: -10px; padding-bottom: 10px" trigger="none">
{{ header }}
</n-scrollbar>
</n-statistic>
</n-card>
<br />
<n-space justify="center">
<n-button secondary @click="copy">Copy header</n-button>
</n-space>
</div>
</template>
<script setup lang="ts">
import { useCopy } from '@/composable/copy';
import { textToBase64 } from '@/utils/base64';
import { computed, ref } from 'vue';
const username = ref('');
const password = ref('');
@ -40,6 +9,34 @@ const header = computed(() => `Authorization: Basic ${textToBase64(`${username.v
const { copy } = useCopy({ source: header, text: 'Header copied to the clipboard' });
</script>
<template>
<div>
<c-input-text v-model:value="username" label="Username" placeholder="Your username..." clearable raw-text mb-5 />
<c-input-text
v-model:value="password"
label="Password"
placeholder="Your password..."
clearable
raw-text
mb-2
type="password"
/>
<c-card>
<n-statistic label="Authorization header:" class="header">
<n-scrollbar x-scrollable style="max-width: 550px; margin-bottom: -10px; padding-bottom: 10px" trigger="none">
{{ header }}
</n-scrollbar>
</n-statistic>
</c-card>
<div mt-5 flex justify-center>
<c-button @click="copy()">
Copy header
</c-button>
</div>
</div>
</template>
<style lang="less" scoped>
::v-deep(.n-statistic-value__content) {
font-family: monospace;

View file

@ -1,10 +1,11 @@
import { PasswordRound } from '@vicons/material';
import { defineTool } from '../tool';
import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
name: 'Basic auth generator',
name: translate('tools.basic-auth-generator.title'),
path: '/basic-auth-generator',
description: 'Generate a base64 basic auth header from an username and a password.',
description: translate('tools.basic-auth-generator.description'),
keywords: [
'basic',
'auth',

View file

@ -1,63 +1,7 @@
<template>
<n-card title="Hash">
<n-form label-width="120">
<n-form-item label="Your string: " label-placement="left">
<n-input
v-model:value="input"
placeholder="Your string to bcrypt..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
/>
</n-form-item>
<n-form-item label="Salt count: " label-placement="left">
<n-input-number v-model:value="saltCount" placeholder="Salt rounds..." :max="10" :min="0" w-full />
</n-form-item>
<n-input :value="hashed" readonly style="text-align: center" />
</n-form>
<br />
<n-space justify="center">
<n-button secondary @click="copy"> Copy hash </n-button>
</n-space>
</n-card>
<n-card title="Compare string with hash">
<n-form label-width="120">
<n-form-item label="Your string: " label-placement="left">
<n-input
v-model:value="compareString"
placeholder="Your string to compare..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
/>
</n-form-item>
<n-form-item label="Your hash: " label-placement="left">
<n-input
v-model:value="compareHash"
placeholder="Your hahs to compare..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
/>
</n-form-item>
<n-form-item label="Do they match ? " label-placement="left" :show-feedback="false">
<div class="compare-result" :class="{ positive: compareMatch }">
{{ compareMatch ? 'Yes' : 'No' }}
</div>
</n-form-item>
</n-form>
</n-card>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import { hashSync, compareSync } from 'bcryptjs';
import { useCopy } from '@/composable/copy';
import { compareSync, hashSync } from 'bcryptjs';
import { useThemeVars } from 'naive-ui';
import { useCopy } from '@/composable/copy';
const themeVars = useThemeVars();
@ -71,6 +15,48 @@ const compareHash = ref('');
const compareMatch = computed(() => compareSync(compareString.value, compareHash.value));
</script>
<template>
<c-card title="Hash">
<c-input-text
v-model:value="input"
placeholder="Your string to bcrypt..."
raw-text
label="Your string: "
label-position="left"
label-align="right"
label-width="120px"
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="100" :min="0" w-full />
</n-form-item>
<c-input-text :value="hashed" readonly text-center />
<div mt-5 flex justify-center>
<c-button @click="copy()">
Copy hash
</c-button>
</div>
</c-card>
<c-card title="Compare string with hash">
<n-form label-width="120">
<n-form-item label="Your string: " label-placement="left">
<c-input-text v-model:value="compareString" placeholder="Your string to compare..." raw-text />
</n-form-item>
<n-form-item label="Your hash: " label-placement="left">
<c-input-text v-model:value="compareHash" placeholder="Your hash to compare..." raw-text />
</n-form-item>
<n-form-item label="Do they match ? " label-placement="left" :show-feedback="false">
<div class="compare-result" :class="{ positive: compareMatch }">
{{ compareMatch ? 'Yes' : 'No' }}
</div>
</n-form-item>
</n-form>
</c-card>
</template>
<style lang="less" scoped>
.compare-result {
color: v-bind('themeVars.errorColor');

Some files were not shown because too many files have changed in this diff Show more