feat(tools): new badge for recently created tools
This commit is contained in:
		
							parent
							
								
									ac89490794
								
							
						
					
					
						commit
						11720e6cde
					
				
							
								
								
									
										154
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										154
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -20,9 +20,10 @@ | |||||||
|         "cronstrue": "^2.2.0", |         "cronstrue": "^2.2.0", | ||||||
|         "crypto-js": "^4.1.1", |         "crypto-js": "^4.1.1", | ||||||
|         "date-fns": "^2.28.0", |         "date-fns": "^2.28.0", | ||||||
|         "figue": "^1.1.0", |         "figue": "^1.2.0", | ||||||
|         "highlight.js": "^11.5.1", |         "highlight.js": "^11.5.1", | ||||||
|         "lodash": "^4.17.21", |         "lodash": "^4.17.21", | ||||||
|  |         "mathjs": "^10.6.0", | ||||||
|         "naive-ui": "^2.28.0", |         "naive-ui": "^2.28.0", | ||||||
|         "pinia": "^2.0.11", |         "pinia": "^2.0.11", | ||||||
|         "plausible-tracker": "^0.3.5", |         "plausible-tracker": "^0.3.5", | ||||||
| @ -1643,7 +1644,6 @@ | |||||||
|       "version": "7.17.9", |       "version": "7.17.9", | ||||||
|       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", |       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", | ||||||
|       "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", |       "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", | ||||||
|       "dev": true, |  | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "regenerator-runtime": "^0.13.4" |         "regenerator-runtime": "^0.13.4" | ||||||
|       }, |       }, | ||||||
| @ -3558,6 +3558,18 @@ | |||||||
|         "dot-prop": "^5.1.0" |         "dot-prop": "^5.1.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/complex.js": { | ||||||
|  |       "version": "2.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz", | ||||||
|  |       "integrity": "sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": "*" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "type": "patreon", | ||||||
|  |         "url": "https://www.patreon.com/infusion" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/concat-map": { |     "node_modules/concat-map": { | ||||||
|       "version": "0.0.1", |       "version": "0.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", |       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", | ||||||
| @ -4164,8 +4176,7 @@ | |||||||
|     "node_modules/decimal.js": { |     "node_modules/decimal.js": { | ||||||
|       "version": "10.3.1", |       "version": "10.3.1", | ||||||
|       "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", |       "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", | ||||||
|       "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", |       "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" | ||||||
|       "dev": true |  | ||||||
|     }, |     }, | ||||||
|     "node_modules/deep-eql": { |     "node_modules/deep-eql": { | ||||||
|       "version": "3.0.1", |       "version": "3.0.1", | ||||||
| @ -4956,6 +4967,11 @@ | |||||||
|         "node": ">=6" |         "node": ">=6" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/escape-latex": { | ||||||
|  |       "version": "1.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", | ||||||
|  |       "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" | ||||||
|  |     }, | ||||||
|     "node_modules/escape-string-regexp": { |     "node_modules/escape-string-regexp": { | ||||||
|       "version": "1.0.5", |       "version": "1.0.5", | ||||||
|       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", |       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", | ||||||
| @ -5523,9 +5539,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/figue": { |     "node_modules/figue": { | ||||||
|       "version": "1.1.0", |       "version": "1.2.0", | ||||||
|       "resolved": "https://registry.npmjs.org/figue/-/figue-1.1.0.tgz", |       "resolved": "https://registry.npmjs.org/figue/-/figue-1.2.0.tgz", | ||||||
|       "integrity": "sha512-toW/IfEPBr42giaiqRtC4TkEDZA2q3E1GdzvYG7iJzIYK/fMVvzD2aqU3PJRh+QXCGp+uVxud1Zm7rpV7Fmprg==", |       "integrity": "sha512-CXKr12kiNWjKtUK3X+YHeXKepn80s9Rg6pgZXoLQYEybgwaGJ9uGW4DrBrVK30ZWZf1mcvTbXF56AcovG7gLVw==", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "lodash": "^4.17.21" |         "lodash": "^4.17.21" | ||||||
|       }, |       }, | ||||||
| @ -5670,6 +5686,18 @@ | |||||||
|         "node": ">=8.0.0" |         "node": ">=8.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/fraction.js": { | ||||||
|  |       "version": "4.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", | ||||||
|  |       "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": "*" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "type": "patreon", | ||||||
|  |         "url": "https://www.patreon.com/infusion" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/from": { |     "node_modules/from": { | ||||||
|       "version": "0.1.7", |       "version": "0.1.7", | ||||||
|       "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", |       "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", | ||||||
| @ -6813,6 +6841,11 @@ | |||||||
|         "node": ">=8" |         "node": ">=8" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/javascript-natural-sort": { | ||||||
|  |       "version": "0.7.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", | ||||||
|  |       "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=" | ||||||
|  |     }, | ||||||
|     "node_modules/jest-diff": { |     "node_modules/jest-diff": { | ||||||
|       "version": "27.5.1", |       "version": "27.5.1", | ||||||
|       "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", |       "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", | ||||||
| @ -7517,6 +7550,28 @@ | |||||||
|         "url": "https://github.com/fb55/entities?sponsor=1" |         "url": "https://github.com/fb55/entities?sponsor=1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/mathjs": { | ||||||
|  |       "version": "10.6.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-10.6.0.tgz", | ||||||
|  |       "integrity": "sha512-4oI0CSX7LtcyexTSLV8uo+llj8hB5LvVE9ApjN6rBjBplQaZ4/Gr3jh0zEla9+KaCig5wonZ9oFKD+GKXFL8hg==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@babel/runtime": "^7.17.9", | ||||||
|  |         "complex.js": "^2.1.1", | ||||||
|  |         "decimal.js": "^10.3.1", | ||||||
|  |         "escape-latex": "^1.2.0", | ||||||
|  |         "fraction.js": "^4.2.0", | ||||||
|  |         "javascript-natural-sort": "^0.7.1", | ||||||
|  |         "seedrandom": "^3.0.5", | ||||||
|  |         "tiny-emitter": "^2.1.0", | ||||||
|  |         "typed-function": "^2.1.0" | ||||||
|  |       }, | ||||||
|  |       "bin": { | ||||||
|  |         "mathjs": "bin/cli.js" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 14" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/mdn-data": { |     "node_modules/mdn-data": { | ||||||
|       "version": "2.0.14", |       "version": "2.0.14", | ||||||
|       "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", |       "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", | ||||||
| @ -9019,8 +9074,7 @@ | |||||||
|     "node_modules/regenerator-runtime": { |     "node_modules/regenerator-runtime": { | ||||||
|       "version": "0.13.9", |       "version": "0.13.9", | ||||||
|       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", |       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", | ||||||
|       "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", |       "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" | ||||||
|       "dev": true |  | ||||||
|     }, |     }, | ||||||
|     "node_modules/regenerator-transform": { |     "node_modules/regenerator-transform": { | ||||||
|       "version": "0.15.0", |       "version": "0.15.0", | ||||||
| @ -9287,6 +9341,11 @@ | |||||||
|         "node": ">=4" |         "node": ">=4" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/seedrandom": { | ||||||
|  |       "version": "3.0.5", | ||||||
|  |       "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", | ||||||
|  |       "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" | ||||||
|  |     }, | ||||||
|     "node_modules/seemly": { |     "node_modules/seemly": { | ||||||
|       "version": "0.3.3", |       "version": "0.3.3", | ||||||
|       "resolved": "https://registry.npmjs.org/seemly/-/seemly-0.3.3.tgz", |       "resolved": "https://registry.npmjs.org/seemly/-/seemly-0.3.3.tgz", | ||||||
| @ -9990,6 +10049,11 @@ | |||||||
|         "readable-stream": "3" |         "readable-stream": "3" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/tiny-emitter": { | ||||||
|  |       "version": "2.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", | ||||||
|  |       "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" | ||||||
|  |     }, | ||||||
|     "node_modules/tinypool": { |     "node_modules/tinypool": { | ||||||
|       "version": "0.1.3", |       "version": "0.1.3", | ||||||
|       "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.1.3.tgz", |       "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.1.3.tgz", | ||||||
| @ -10108,6 +10172,14 @@ | |||||||
|         "node": ">=4" |         "node": ">=4" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/typed-function": { | ||||||
|  |       "version": "2.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-2.1.0.tgz", | ||||||
|  |       "integrity": "sha512-bctQIOqx2iVbWGDGPWwIm18QScpu2XRmkC19D8rQGFsjKSgteq/o1hTZvIG/wuDq8fanpBDrLkLq+aEN/6y5XQ==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 10" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/typedarray": { |     "node_modules/typedarray": { | ||||||
|       "version": "0.0.6", |       "version": "0.0.6", | ||||||
|       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", |       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", | ||||||
| @ -12426,7 +12498,6 @@ | |||||||
|       "version": "7.17.9", |       "version": "7.17.9", | ||||||
|       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", |       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", | ||||||
|       "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", |       "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", | ||||||
|       "dev": true, |  | ||||||
|       "requires": { |       "requires": { | ||||||
|         "regenerator-runtime": "^0.13.4" |         "regenerator-runtime": "^0.13.4" | ||||||
|       } |       } | ||||||
| @ -13935,6 +14006,11 @@ | |||||||
|         "dot-prop": "^5.1.0" |         "dot-prop": "^5.1.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "complex.js": { | ||||||
|  |       "version": "2.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz", | ||||||
|  |       "integrity": "sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==" | ||||||
|  |     }, | ||||||
|     "concat-map": { |     "concat-map": { | ||||||
|       "version": "0.0.1", |       "version": "0.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", |       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", | ||||||
| @ -14418,8 +14494,7 @@ | |||||||
|     "decimal.js": { |     "decimal.js": { | ||||||
|       "version": "10.3.1", |       "version": "10.3.1", | ||||||
|       "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", |       "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", | ||||||
|       "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", |       "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" | ||||||
|       "dev": true |  | ||||||
|     }, |     }, | ||||||
|     "deep-eql": { |     "deep-eql": { | ||||||
|       "version": "3.0.1", |       "version": "3.0.1", | ||||||
| @ -14918,6 +14993,11 @@ | |||||||
|       "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", |       "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "escape-latex": { | ||||||
|  |       "version": "1.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", | ||||||
|  |       "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" | ||||||
|  |     }, | ||||||
|     "escape-string-regexp": { |     "escape-string-regexp": { | ||||||
|       "version": "1.0.5", |       "version": "1.0.5", | ||||||
|       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", |       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", | ||||||
| @ -15334,9 +15414,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "figue": { |     "figue": { | ||||||
|       "version": "1.1.0", |       "version": "1.2.0", | ||||||
|       "resolved": "https://registry.npmjs.org/figue/-/figue-1.1.0.tgz", |       "resolved": "https://registry.npmjs.org/figue/-/figue-1.2.0.tgz", | ||||||
|       "integrity": "sha512-toW/IfEPBr42giaiqRtC4TkEDZA2q3E1GdzvYG7iJzIYK/fMVvzD2aqU3PJRh+QXCGp+uVxud1Zm7rpV7Fmprg==", |       "integrity": "sha512-CXKr12kiNWjKtUK3X+YHeXKepn80s9Rg6pgZXoLQYEybgwaGJ9uGW4DrBrVK30ZWZf1mcvTbXF56AcovG7gLVw==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "lodash": "^4.17.21" |         "lodash": "^4.17.21" | ||||||
|       } |       } | ||||||
| @ -15439,6 +15519,11 @@ | |||||||
|         "signal-exit": "^3.0.2" |         "signal-exit": "^3.0.2" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "fraction.js": { | ||||||
|  |       "version": "4.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", | ||||||
|  |       "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" | ||||||
|  |     }, | ||||||
|     "from": { |     "from": { | ||||||
|       "version": "0.1.7", |       "version": "0.1.7", | ||||||
|       "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", |       "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", | ||||||
| @ -16283,6 +16368,11 @@ | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "javascript-natural-sort": { | ||||||
|  |       "version": "0.7.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", | ||||||
|  |       "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=" | ||||||
|  |     }, | ||||||
|     "jest-diff": { |     "jest-diff": { | ||||||
|       "version": "27.5.1", |       "version": "27.5.1", | ||||||
|       "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", |       "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", | ||||||
| @ -16835,6 +16925,22 @@ | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "mathjs": { | ||||||
|  |       "version": "10.6.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-10.6.0.tgz", | ||||||
|  |       "integrity": "sha512-4oI0CSX7LtcyexTSLV8uo+llj8hB5LvVE9ApjN6rBjBplQaZ4/Gr3jh0zEla9+KaCig5wonZ9oFKD+GKXFL8hg==", | ||||||
|  |       "requires": { | ||||||
|  |         "@babel/runtime": "^7.17.9", | ||||||
|  |         "complex.js": "^2.1.1", | ||||||
|  |         "decimal.js": "^10.3.1", | ||||||
|  |         "escape-latex": "^1.2.0", | ||||||
|  |         "fraction.js": "^4.2.0", | ||||||
|  |         "javascript-natural-sort": "^0.7.1", | ||||||
|  |         "seedrandom": "^3.0.5", | ||||||
|  |         "tiny-emitter": "^2.1.0", | ||||||
|  |         "typed-function": "^2.1.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "mdn-data": { |     "mdn-data": { | ||||||
|       "version": "2.0.14", |       "version": "2.0.14", | ||||||
|       "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", |       "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", | ||||||
| @ -17970,8 +18076,7 @@ | |||||||
|     "regenerator-runtime": { |     "regenerator-runtime": { | ||||||
|       "version": "0.13.9", |       "version": "0.13.9", | ||||||
|       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", |       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", | ||||||
|       "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", |       "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" | ||||||
|       "dev": true |  | ||||||
|     }, |     }, | ||||||
|     "regenerator-transform": { |     "regenerator-transform": { | ||||||
|       "version": "0.15.0", |       "version": "0.15.0", | ||||||
| @ -18165,6 +18270,11 @@ | |||||||
|         "kind-of": "^6.0.0" |         "kind-of": "^6.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "seedrandom": { | ||||||
|  |       "version": "3.0.5", | ||||||
|  |       "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", | ||||||
|  |       "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" | ||||||
|  |     }, | ||||||
|     "seemly": { |     "seemly": { | ||||||
|       "version": "0.3.3", |       "version": "0.3.3", | ||||||
|       "resolved": "https://registry.npmjs.org/seemly/-/seemly-0.3.3.tgz", |       "resolved": "https://registry.npmjs.org/seemly/-/seemly-0.3.3.tgz", | ||||||
| @ -18711,6 +18821,11 @@ | |||||||
|         "readable-stream": "3" |         "readable-stream": "3" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "tiny-emitter": { | ||||||
|  |       "version": "2.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", | ||||||
|  |       "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" | ||||||
|  |     }, | ||||||
|     "tinypool": { |     "tinypool": { | ||||||
|       "version": "0.1.3", |       "version": "0.1.3", | ||||||
|       "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.1.3.tgz", |       "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.1.3.tgz", | ||||||
| @ -18801,6 +18916,11 @@ | |||||||
|       "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", |       "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "typed-function": { | ||||||
|  |       "version": "2.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-2.1.0.tgz", | ||||||
|  |       "integrity": "sha512-bctQIOqx2iVbWGDGPWwIm18QScpu2XRmkC19D8rQGFsjKSgteq/o1hTZvIG/wuDq8fanpBDrLkLq+aEN/6y5XQ==" | ||||||
|  |     }, | ||||||
|     "typedarray": { |     "typedarray": { | ||||||
|       "version": "0.0.6", |       "version": "0.0.6", | ||||||
|       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", |       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", | ||||||
|  | |||||||
| @ -25,9 +25,10 @@ | |||||||
|     "cronstrue": "^2.2.0", |     "cronstrue": "^2.2.0", | ||||||
|     "crypto-js": "^4.1.1", |     "crypto-js": "^4.1.1", | ||||||
|     "date-fns": "^2.28.0", |     "date-fns": "^2.28.0", | ||||||
|     "figue": "^1.1.0", |     "figue": "^1.2.0", | ||||||
|     "highlight.js": "^11.5.1", |     "highlight.js": "^11.5.1", | ||||||
|     "lodash": "^4.17.21", |     "lodash": "^4.17.21", | ||||||
|  |     "mathjs": "^10.6.0", | ||||||
|     "naive-ui": "^2.28.0", |     "naive-ui": "^2.28.0", | ||||||
|     "pinia": "^2.0.11", |     "pinia": "^2.0.11", | ||||||
|     "plausible-tracker": "^0.3.5", |     "plausible-tracker": "^0.3.5", | ||||||
|  | |||||||
| @ -39,16 +39,16 @@ createToolFile( | |||||||
| 
 | 
 | ||||||
| <style lang="less" scoped> | <style lang="less" scoped> | ||||||
| </style> | </style> | ||||||
| ` | `,
 | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| createToolFile( | createToolFile( | ||||||
|   `index.ts`, |   `index.ts`, | ||||||
|   ` |   ` | ||||||
| import { ArrowsShuffle } from '@vicons/tabler'; | import { ArrowsShuffle } from '@vicons/tabler'; | ||||||
| import type { ITool } from './../Tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: '${toolNameTitleCase}', |   name: '${toolNameTitleCase}', | ||||||
|   path: '/${toolName}', |   path: '/${toolName}', | ||||||
|   description: '', |   description: '', | ||||||
| @ -56,7 +56,7 @@ export const tool: ITool = { | |||||||
|   component: () => import('./${toolName}.vue'), |   component: () => import('./${toolName}.vue'), | ||||||
|   icon: ArrowsShuffle, |   icon: ArrowsShuffle, | ||||||
| }; | }; | ||||||
| ` | `,
 | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| createToolFile(`${toolName}.service.ts`, ``); | createToolFile(`${toolName}.service.ts`, ``); | ||||||
| @ -69,7 +69,7 @@ import { expect, describe, it } from 'vitest'; | |||||||
| // describe('${toolName}', () => {
 | // describe('${toolName}', () => {
 | ||||||
| //
 | //
 | ||||||
| // })
 | // })
 | ||||||
| ` | `,
 | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| const toolsIndex = join(toolsDir, 'index.ts'); | const toolsIndex = join(toolsDir, 'index.ts'); | ||||||
|  | |||||||
							
								
								
									
										36
									
								
								src/components/MenuIconItem.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/components/MenuIconItem.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | <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 { ITool } from '@/tools/tool'; | ||||||
|  | import { useThemeVars } from 'naive-ui'; | ||||||
|  | import { toRefs } from 'vue'; | ||||||
|  | 
 | ||||||
|  | const props = defineProps<{ tool: ITool }>(); | ||||||
|  | const { tool } = toRefs(props); | ||||||
|  | 
 | ||||||
|  | const theme = useThemeVars(); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style lang="less" scoped> | ||||||
|  | .menu-icon-item { | ||||||
|  |   position: relative; | ||||||
|  | 
 | ||||||
|  |   .badge { | ||||||
|  |     position: absolute; | ||||||
|  |     background-color: v-bind('theme.primaryColor'); | ||||||
|  |     border-radius: 10px; | ||||||
|  |     line-height: 1; | ||||||
|  |     top: 3px; | ||||||
|  |     left: -6px; | ||||||
|  |     font-size: 10px; | ||||||
|  | 
 | ||||||
|  |     height: 6px; | ||||||
|  |     width: 6px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -1,10 +1,24 @@ | |||||||
| <template> | <template> | ||||||
|   <router-link :to="tool.path"> |   <router-link :to="tool.path"> | ||||||
|     <n-card class="tool-card"> |     <n-card class="tool-card"> | ||||||
|  |       <n-space justify="space-between" align="center"> | ||||||
|         <n-icon class="icon" size="40" :component="tool.icon" /> |         <n-icon class="icon" size="40" :component="tool.icon" /> | ||||||
|  |         <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> | ||||||
|  |       </n-space> | ||||||
|       <n-h3 class="title"> |       <n-h3 class="title"> | ||||||
|         <n-ellipsis>{{ tool.name }}</n-ellipsis> |         <n-ellipsis>{{ tool.name }}</n-ellipsis> | ||||||
|       </n-h3> |       </n-h3> | ||||||
|  | 
 | ||||||
|       <div class="description"> |       <div class="description"> | ||||||
|         <n-ellipsis :line-clamp="2" :tooltip="false"> |         <n-ellipsis :line-clamp="2" :tooltip="false"> | ||||||
|           {{ tool.description }} |           {{ tool.description }} | ||||||
| @ -15,11 +29,13 @@ | |||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import type { ITool } from '@/tools/Tool'; | import type { ITool } from '@/tools/tool'; | ||||||
|  | import { useThemeVars } from 'naive-ui'; | ||||||
| import { toRefs } from 'vue'; | import { toRefs } from 'vue'; | ||||||
| 
 | 
 | ||||||
| const props = defineProps<{ tool: ITool & { category: string } }>(); | const props = defineProps<{ tool: ITool & { category: string } }>(); | ||||||
| const { tool } = toRefs(props); | const { tool } = toRefs(props); | ||||||
|  | const theme = useThemeVars(); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style lang="less" scoped> | <style lang="less" scoped> | ||||||
|  | |||||||
| @ -47,6 +47,14 @@ export const config = figue({ | |||||||
|       default: false, |       default: false, | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|  |   tools: { | ||||||
|  |     newTools: { | ||||||
|  |       doc: 'Tool names for tools flagged a as new', | ||||||
|  |       format: 'array', | ||||||
|  |       default: [], | ||||||
|  |       env: 'VITE_NEW_TOOLS', | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
| }) | }) | ||||||
|   .loadEnv({ |   .loadEnv({ | ||||||
|     ...import.meta.env, |     ...import.meta.env, | ||||||
|  | |||||||
| @ -10,6 +10,8 @@ import HeroGradient from '../assets/hero-gradient.svg?component'; | |||||||
| import MenuLayout from '../components/MenuLayout.vue'; | import MenuLayout from '../components/MenuLayout.vue'; | ||||||
| import NavbarButtons from '../components/NavbarButtons.vue'; | import NavbarButtons from '../components/NavbarButtons.vue'; | ||||||
| import { config } from '@/config'; | import { config } from '@/config'; | ||||||
|  | import MenuIconItem from '@/components/MenuIconItem.vue'; | ||||||
|  | import type { ITool } from '@/tools/tool'; | ||||||
| 
 | 
 | ||||||
| const themeVars = useThemeVars(); | const themeVars = useThemeVars(); | ||||||
| const route = useRoute(); | const route = useRoute(); | ||||||
| @ -18,15 +20,15 @@ const version = config.app.version; | |||||||
| const commitSha = config.app.lastCommitSha.slice(0, 7); | const commitSha = config.app.lastCommitSha.slice(0, 7); | ||||||
| 
 | 
 | ||||||
| const makeLabel = (text: string, to: string) => () => h(RouterLink, { to }, { default: () => text }); | const makeLabel = (text: string, to: string) => () => h(RouterLink, { to }, { default: () => text }); | ||||||
| const makeIcon = (icon: Component) => () => h(NIcon, null, { default: () => h(icon) }); | const makeIcon = (tool: ITool) => () => h(MenuIconItem, { tool }); | ||||||
| 
 | 
 | ||||||
| const menuOptions = toolsByCategory.map((category) => ({ | const menuOptions = toolsByCategory.map((category) => ({ | ||||||
|   label: category.name, |   label: category.name, | ||||||
|   key: category.name, |   key: category.name, | ||||||
|   type: 'group', |   type: 'group', | ||||||
|   children: category.components.map(({ name, path, icon }) => ({ |   children: category.components.map((tool) => ({ | ||||||
|     label: makeLabel(name, path), |     label: makeLabel(tool.name, tool.path), | ||||||
|     icon: makeIcon(icon), |     icon: makeIcon(tool), | ||||||
|     key: name, |     key: name, | ||||||
|   })), |   })), | ||||||
| })); | })); | ||||||
| @ -218,6 +220,11 @@ const menuOptions = toolsByCategory.map((category) => ({ | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // ::v-deep(.n-menu-item-content-header) { | ||||||
|  | //   overflow: visible !important; | ||||||
|  | //   // overflow-x: hidden !important; | ||||||
|  | // } | ||||||
|  | 
 | ||||||
| .navigation { | .navigation { | ||||||
|   display: flex; |   display: flex; | ||||||
|   align-items: center; |   align-items: center; | ||||||
|  | |||||||
| @ -4,8 +4,10 @@ import BaseLayout from './base.layout.vue'; | |||||||
| import { useHead } from '@vueuse/head'; | import { useHead } from '@vueuse/head'; | ||||||
| import type { HeadObject } from '@vueuse/head'; | import type { HeadObject } from '@vueuse/head'; | ||||||
| import { reactive } from 'vue'; | import { reactive } from 'vue'; | ||||||
|  | import { useThemeVars } from 'naive-ui'; | ||||||
| 
 | 
 | ||||||
| const route = useRoute(); | const route = useRoute(); | ||||||
|  | const theme = useThemeVars(); | ||||||
| 
 | 
 | ||||||
| const head = reactive<HeadObject>({ | const head = reactive<HeadObject>({ | ||||||
|   title: `${route.meta.name} - IT Tools`, |   title: `${route.meta.name} - IT Tools`, | ||||||
| @ -27,7 +29,21 @@ useHead(head); | |||||||
|   <base-layout> |   <base-layout> | ||||||
|     <div class="tool-layout"> |     <div class="tool-layout"> | ||||||
|       <div class="tool-header"> |       <div class="tool-header"> | ||||||
|         <n-h1>{{ route.meta.name }}</n-h1> |         <n-h1> | ||||||
|  |           {{ route.meta.name }} | ||||||
|  | 
 | ||||||
|  |           <n-tag | ||||||
|  |             v-if="route.meta.isNew" | ||||||
|  |             round | ||||||
|  |             type="success" | ||||||
|  |             :bordered="false" | ||||||
|  |             :color="{ color: theme.primaryColor, textColor: theme.tagColor }" | ||||||
|  |           > | ||||||
|  |             New tool | ||||||
|  |           </n-tag> | ||||||
|  |           <!-- <span class="new-tool-badge">New !</span> --> | ||||||
|  |         </n-h1> | ||||||
|  | 
 | ||||||
|         <div class="separator" /> |         <div class="separator" /> | ||||||
|         <div class="description"> |         <div class="description"> | ||||||
|           {{ route.meta.description }} |           {{ route.meta.description }} | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ useHead({ title: 'IT Tools - Handy online tools for developers' }); | |||||||
| <template> | <template> | ||||||
|   <div class="home-page"> |   <div class="home-page"> | ||||||
|     <n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8"> |     <n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8"> | ||||||
|       <n-gi v-for="tool in toolsWithCategory" :key="tool.name"> |       <n-gi v-for="tool in toolsWithCategory.reverse().sort(({ isNew }) => (isNew ? -1 : 1))" :key="tool.name"> | ||||||
|         <tool-card :tool="tool" /> |         <tool-card :tool="tool" /> | ||||||
|       </n-gi> |       </n-gi> | ||||||
|     </n-grid> |     </n-grid> | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { FileDigit } from '@vicons/tabler'; | import { FileDigit } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Base64 converter', |   name: 'Base64 converter', | ||||||
|   path: '/base64-converter', |   path: '/base64-converter', | ||||||
|   description: "Convert string, files or images into a it's base64 representation.", |   description: "Convert string, files or images into a it's base64 representation.", | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   component: () => import('./base64-converter.vue'), |   component: () => import('./base64-converter.vue'), | ||||||
|   icon: FileDigit, |   icon: FileDigit, | ||||||
|   redirectFrom: ['/file-to-base64', '/base64-string-converter'], |   redirectFrom: ['/file-to-base64', '/base64-string-converter'], | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { LockSquare } from '@vicons/tabler'; | import { LockSquare } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Bcrypt', |   name: 'Bcrypt', | ||||||
|   path: '/bcrypt', |   path: '/bcrypt', | ||||||
|   description: |   description: | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   keywords: ['bcrypt', 'hash', 'compare', 'password', 'salt', 'round', 'storage', 'crypto'], |   keywords: ['bcrypt', 'hash', 'compare', 'password', 'salt', 'round', 'storage', 'crypto'], | ||||||
|   component: () => import('./bcrypt.vue'), |   component: () => import('./bcrypt.vue'), | ||||||
|   icon: LockSquare, |   icon: LockSquare, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { AlignJustified } from '@vicons/tabler'; | import { AlignJustified } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'BIP39 passphrase generator', |   name: 'BIP39 passphrase generator', | ||||||
|   path: '/bip39-generator', |   path: '/bip39-generator', | ||||||
|   description: 'Generate BIP39 passphrase from existing or random mnemonic, or get the mnemonic from the passphrase.', |   description: 'Generate BIP39 passphrase from existing or random mnemonic, or get the mnemonic from the passphrase.', | ||||||
|   keywords: ['BIP39', 'passphrase', 'generator', 'mnemonic', 'entropy'], |   keywords: ['BIP39', 'passphrase', 'generator', 'mnemonic', 'entropy'], | ||||||
|   component: () => import('./bip39-generator.vue'), |   component: () => import('./bip39-generator.vue'), | ||||||
|   icon: AlignJustified, |   icon: AlignJustified, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { LetterCaseToggle } from '@vicons/tabler'; | import { LetterCaseToggle } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Case converter', |   name: 'Case converter', | ||||||
|   path: '/case-converter', |   path: '/case-converter', | ||||||
|   description: 'Change the case of a string and chose between different formats', |   description: 'Change the case of a string and chose between different formats', | ||||||
| @ -22,4 +22,4 @@ export const tool: ITool = { | |||||||
|   ], |   ], | ||||||
|   component: () => import('./case-converter.vue'), |   component: () => import('./case-converter.vue'), | ||||||
|   icon: LetterCaseToggle, |   icon: LetterCaseToggle, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { Palette } from '@vicons/tabler'; | import { Palette } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Color converter', |   name: 'Color converter', | ||||||
|   path: '/color-converter', |   path: '/color-converter', | ||||||
|   description: 'Convert color between the different formats (hex, rgb, hsl and css name)', |   description: 'Convert color between the different formats (hex, rgb, hsl and css name)', | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   component: () => import('./color-converter.vue'), |   component: () => import('./color-converter.vue'), | ||||||
|   icon: Palette, |   icon: Palette, | ||||||
|   redirectFrom: ['/color-picker-converter'], |   redirectFrom: ['/color-picker-converter'], | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { Alarm } from '@vicons/tabler'; | import { Alarm } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Crontab generator', |   name: 'Crontab generator', | ||||||
|   path: '/crontab-generator', |   path: '/crontab-generator', | ||||||
|   description: 'Validate and generate crontab and get the human readable description of the cron schedule.', |   description: 'Validate and generate crontab and get the human readable description of the cron schedule.', | ||||||
| @ -22,4 +22,4 @@ export const tool: ITool = { | |||||||
|   ], |   ], | ||||||
|   component: () => import('./crontab-generator.vue'), |   component: () => import('./crontab-generator.vue'), | ||||||
|   icon: Alarm, |   icon: Alarm, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { Calendar } from '@vicons/tabler'; | import { Calendar } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Date-time converter', |   name: 'Date-time converter', | ||||||
|   path: '/date-converter', |   path: '/date-converter', | ||||||
|   description: 'Convert date and time into the various different formats', |   description: 'Convert date and time into the various different formats', | ||||||
|   keywords: ['date', 'time', 'converter', 'iso', 'utc', 'timezone', 'year', 'month', 'day', 'minute', 'seconde'], |   keywords: ['date', 'time', 'converter', 'iso', 'utc', 'timezone', 'year', 'month', 'day', 'minute', 'seconde'], | ||||||
|   component: () => import('./date-time-converter.vue'), |   component: () => import('./date-time-converter.vue'), | ||||||
|   icon: Calendar, |   icon: Calendar, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { DeviceDesktop } from '@vicons/tabler'; | import { DeviceDesktop } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Device information', |   name: 'Device information', | ||||||
|   path: '/device-information', |   path: '/device-information', | ||||||
|   description: 'Get information about your current device (screen size, pixel-ratio, user agent, ...)', |   description: 'Get information about your current device (screen size, pixel-ratio, user agent, ...)', | ||||||
| @ -20,4 +20,4 @@ export const tool: ITool = { | |||||||
|   ], |   ], | ||||||
|   component: () => import('./device-information.vue'), |   component: () => import('./device-information.vue'), | ||||||
|   icon: DeviceDesktop, |   icon: DeviceDesktop, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { Lock } from '@vicons/tabler'; | import { Lock } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Encrypt / decrypt text', |   name: 'Encrypt / decrypt text', | ||||||
|   path: '/encryption', |   path: '/encryption', | ||||||
|   description: 'Encrypt and decrypt text clear text using crypto algorithm like AES, TripleDES, Rabbit or RC4.', |   description: 'Encrypt and decrypt text clear text using crypto algorithm like AES, TripleDES, Rabbit or RC4.', | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   component: () => import('./encryption.vue'), |   component: () => import('./encryption.vue'), | ||||||
|   icon: Lock, |   icon: Lock, | ||||||
|   redirectFrom: ['/cypher'], |   redirectFrom: ['/cypher'], | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { BrandGit } from '@vicons/tabler'; | import { BrandGit } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Git cheatsheet', |   name: 'Git cheatsheet', | ||||||
|   path: '/git-memo', |   path: '/git-memo', | ||||||
|   description: |   description: | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   keywords: ['git', 'push', 'force', 'pull', 'commit', 'amend', 'rebase', 'merge', 'reset', 'soft', 'hard', 'lease'], |   keywords: ['git', 'push', 'force', 'pull', 'commit', 'amend', 'rebase', 'merge', 'reset', 'soft', 'hard', 'lease'], | ||||||
|   component: () => import('./git-memo.vue'), |   component: () => import('./git-memo.vue'), | ||||||
|   icon: BrandGit, |   icon: BrandGit, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { EyeOff } from '@vicons/tabler'; | import { EyeOff } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Hash text', |   name: 'Hash text', | ||||||
|   path: '/hash-text', |   path: '/hash-text', | ||||||
|   description: |   description: | ||||||
| @ -24,4 +24,4 @@ export const tool: ITool = { | |||||||
|   component: () => import('./hash-text.vue'), |   component: () => import('./hash-text.vue'), | ||||||
|   icon: EyeOff, |   icon: EyeOff, | ||||||
|   redirectFrom: ['/hash'], |   redirectFrom: ['/hash'], | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { Code } from '@vicons/tabler'; | import { Code } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Escape html entities', |   name: 'Escape html entities', | ||||||
|   path: '/html-entities', |   path: '/html-entities', | ||||||
|   description: 'Escape or unescape html entities (replace <,>, &, " and \' to their html version)', |   description: 'Escape or unescape html entities (replace <,>, &, " and \' to their html version)', | ||||||
|   keywords: ['html', 'entities', 'escape', 'unescape', 'special', 'characters', 'tags'], |   keywords: ['html', 'entities', 'escape', 'unescape', 'special', 'characters', 'tags'], | ||||||
|   component: () => import('./html-entities.vue'), |   component: () => import('./html-entities.vue'), | ||||||
|   icon: Code, |   icon: Code, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { ArrowsLeftRight } from '@vicons/tabler'; | import { ArrowsLeftRight } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Integer base converter', |   name: 'Integer base converter', | ||||||
|   path: '/base-converter', |   path: '/base-converter', | ||||||
|   description: 'Convert number between different bases (decimal, hexadecimal, binary, octal, base64, ...)', |   description: 'Convert number between different bases (decimal, hexadecimal, binary, octal, base64, ...)', | ||||||
|   keywords: ['integer', 'number', 'base', 'conversion', 'decimal', 'hexadecimal', 'binary', 'octal', 'base64'], |   keywords: ['integer', 'number', 'base', 'conversion', 'decimal', 'hexadecimal', 'binary', 'octal', 'base64'], | ||||||
|   component: () => import('./integer-base-converter.vue'), |   component: () => import('./integer-base-converter.vue'), | ||||||
|   icon: ArrowsLeftRight, |   icon: ArrowsLeftRight, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { Braces } from '@vicons/tabler'; | import { Braces } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'JSON viewer', |   name: 'JSON viewer', | ||||||
|   path: '/json-viewer', |   path: '/json-viewer', | ||||||
|   description: 'Prettify JSON string to a human friendly readable format.', |   description: 'Prettify JSON string to a human friendly readable format.', | ||||||
|   keywords: ['json', 'viewer', 'prettify', 'format'], |   keywords: ['json', 'viewer', 'prettify', 'format'], | ||||||
|   component: () => import('./json-viewer.vue'), |   component: () => import('./json-viewer.vue'), | ||||||
|   icon: Braces, |   icon: Braces, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { AlignJustified } from '@vicons/tabler'; | import { AlignJustified } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Lorem ipsum generator', |   name: 'Lorem ipsum generator', | ||||||
|   path: '/lorem-ipsum-generator', |   path: '/lorem-ipsum-generator', | ||||||
|   description: |   description: | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   keywords: ['lorem', 'ipsum', 'dolor', 'sit', 'amet', 'placeholder', 'text', 'filler', 'random', 'generator'], |   keywords: ['lorem', 'ipsum', 'dolor', 'sit', 'amet', 'placeholder', 'text', 'filler', 'random', 'generator'], | ||||||
|   component: () => import('./lorem-ipsum-generator.vue'), |   component: () => import('./lorem-ipsum-generator.vue'), | ||||||
|   icon: AlignJustified, |   icon: AlignJustified, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { Qrcode } from '@vicons/tabler'; | import { Qrcode } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'QR Code generator', |   name: 'QR Code generator', | ||||||
|   path: '/qrcode-generator', |   path: '/qrcode-generator', | ||||||
|   description: |   description: | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   keywords: ['qr', 'code', 'generator', 'square', 'color', 'link', 'low', 'medium', 'quartile', 'high', 'transparent'], |   keywords: ['qr', 'code', 'generator', 'square', 'color', 'link', 'low', 'medium', 'quartile', 'high', 'transparent'], | ||||||
|   component: () => import('./qr-code-generator.vue'), |   component: () => import('./qr-code-generator.vue'), | ||||||
|   icon: Qrcode, |   icon: Qrcode, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { Server } from '@vicons/tabler'; | import { Server } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Random port generator', |   name: 'Random port generator', | ||||||
|   path: '/random-port-generator', |   path: '/random-port-generator', | ||||||
|   description: 'Generate random port numbers outside of the range of "known" ports (0-1023).', |   description: 'Generate random port numbers outside of the range of "known" ports (0-1023).', | ||||||
|   keywords: ['system', 'port', 'lan', 'generator', 'random', 'development', 'computer'], |   keywords: ['system', 'port', 'lan', 'generator', 'random', 'development', 'computer'], | ||||||
|   component: () => import('./random-port-generator.vue'), |   component: () => import('./random-port-generator.vue'), | ||||||
|   icon: Server, |   icon: Server, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { LetterX } from '@vicons/tabler'; | import { LetterX } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Roman numeral converter', |   name: 'Roman numeral converter', | ||||||
|   path: '/roman-numeral-converter', |   path: '/roman-numeral-converter', | ||||||
|   description: 'Convert Roman numerals to numbers and convert numbers to Roman numerals.', |   description: 'Convert Roman numerals to numbers and convert numbers to Roman numerals.', | ||||||
|   keywords: ['roman', 'arabic', 'converter', 'X', 'I', 'V', 'L', 'C', 'D', 'M'], |   keywords: ['roman', 'arabic', 'converter', 'X', 'I', 'V', 'L', 'C', 'D', 'M'], | ||||||
|   component: () => import('./roman-numeral-converter.vue'), |   component: () => import('./roman-numeral-converter.vue'), | ||||||
|   icon: LetterX, |   icon: LetterX, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { FileText } from '@vicons/tabler'; | import { FileText } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Text statistics', |   name: 'Text statistics', | ||||||
|   path: '/text-statistics', |   path: '/text-statistics', | ||||||
|   description: "Get information about a text, the amount of characters, the amount of words, it's size, ...", |   description: "Get information about a text, the amount of characters, the amount of words, it's size, ...", | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   component: () => import('./text-statistics.vue'), |   component: () => import('./text-statistics.vue'), | ||||||
|   icon: FileText, |   icon: FileText, | ||||||
|   redirectFrom: ['/text-stats'], |   redirectFrom: ['/text-stats'], | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { ArrowsShuffle } from '@vicons/tabler'; | import { ArrowsShuffle } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Token generator', |   name: 'Token generator', | ||||||
|   path: '/token-generator', |   path: '/token-generator', | ||||||
|   description: |   description: | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   keywords: ['token', 'random', 'string', 'alphanumeric', 'symbols', 'number', 'letters', 'lowercase', 'uppercase'], |   keywords: ['token', 'random', 'string', 'alphanumeric', 'symbols', 'number', 'letters', 'lowercase', 'uppercase'], | ||||||
|   component: () => import('./token-generator.tool.vue'), |   component: () => import('./token-generator.tool.vue'), | ||||||
|   icon: ArrowsShuffle, |   icon: ArrowsShuffle, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,3 +1,4 @@ | |||||||
|  | import { config } from '@/config'; | ||||||
| import type { Component } from 'vue'; | import type { Component } from 'vue'; | ||||||
| 
 | 
 | ||||||
| export interface ITool { | export interface ITool { | ||||||
| @ -8,6 +9,7 @@ export interface ITool { | |||||||
|   component: () => Promise<Component>; |   component: () => Promise<Component>; | ||||||
|   icon: Component; |   icon: Component; | ||||||
|   redirectFrom?: string[]; |   redirectFrom?: string[]; | ||||||
|  |   isNew: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export interface ToolCategory { | export interface ToolCategory { | ||||||
| @ -15,3 +17,17 @@ export interface ToolCategory { | |||||||
|   icon: Component; |   icon: Component; | ||||||
|   components: ITool[]; |   components: ITool[]; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>; | ||||||
|  | 
 | ||||||
|  | export function defineTool( | ||||||
|  |   tool: WithOptional<ITool, 'isNew'>, | ||||||
|  |   { newTools }: { newTools: string[] } = { newTools: config.tools.newTools }, | ||||||
|  | ) { | ||||||
|  |   const isNew = newTools.includes(tool.name); | ||||||
|  | 
 | ||||||
|  |   return { | ||||||
|  |     isNew, | ||||||
|  |     ...tool, | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { Link } from '@vicons/tabler'; | import { Link } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Encode/decode url formatted strings', |   name: 'Encode/decode url formatted strings', | ||||||
|   path: '/url-encoder', |   path: '/url-encoder', | ||||||
|   description: 'Encode to url-encoded format (also known as "percent-encoded") or decode from it.', |   description: 'Encode to url-encoded format (also known as "percent-encoded") or decode from it.', | ||||||
|   keywords: ['url', 'encode', 'decode', 'percent', '%20', 'format'], |   keywords: ['url', 'encode', 'decode', 'percent', '%20', 'format'], | ||||||
|   component: () => import('./url-encoder.vue'), |   component: () => import('./url-encoder.vue'), | ||||||
|   icon: Link, |   icon: Link, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { Unlink } from '@vicons/tabler'; | import { Unlink } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'Url parser', |   name: 'Url parser', | ||||||
|   path: '/url-parser', |   path: '/url-parser', | ||||||
|   description: |   description: | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   keywords: ['url', 'parser', 'protocol', 'origin', 'params', 'port', 'username', 'password', 'href'], |   keywords: ['url', 'parser', 'protocol', 'origin', 'params', 'port', 'username', 'password', 'href'], | ||||||
|   component: () => import('./url-parser.vue'), |   component: () => import('./url-parser.vue'), | ||||||
|   icon: Unlink, |   icon: Unlink, | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { Fingerprint } from '@vicons/tabler'; | import { Fingerprint } from '@vicons/tabler'; | ||||||
| import type { ITool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| 
 | 
 | ||||||
| export const tool: ITool = { | export const tool = defineTool({ | ||||||
|   name: 'UUIDs v4 generator', |   name: 'UUIDs v4 generator', | ||||||
|   path: '/uuid-generator', |   path: '/uuid-generator', | ||||||
|   description: |   description: | ||||||
| @ -9,4 +9,4 @@ export const tool: ITool = { | |||||||
|   keywords: ['uuid', 'v4', 'random', 'id', 'alphanumeric', 'identity', 'token', 'string', 'identifier', 'unique'], |   keywords: ['uuid', 'v4', 'random', 'id', 'alphanumeric', 'identity', 'token', 'string', 'identifier', 'unique'], | ||||||
|   component: () => import('./uuid-generator.vue'), |   component: () => import('./uuid-generator.vue'), | ||||||
|   icon: Fingerprint, |   icon: Fingerprint, | ||||||
| }; | }); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user