-
Showing {filteredItems.length} tools
+
+ Showing {filteredItems.length} tools
+
{showFavoritesOnly && (
)}
- {selectedBasis !== "All" && (
+ {selectedBasis !== 'All' && (
diff --git a/package-lock.json b/package-lock.json
index 1701a09..d11d0f7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,6 +18,7 @@
"animejs": "3.2.2",
"antd": "5.16.2",
"bcryptjs": "^2.4.3",
+ "class-validator": "^0.15.1",
"curlconverter": "^4.12.0",
"dayjs": "^1.11.19",
"framer-motion": "11.2.6",
@@ -3829,9 +3830,9 @@
"license": "MIT"
},
"node_modules/@types/validator": {
- "version": "13.12.2",
- "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.2.tgz",
- "integrity": "sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==",
+ "version": "13.15.10",
+ "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz",
+ "integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==",
"license": "MIT"
},
"node_modules/@typescript-eslint/parser": {
@@ -5131,14 +5132,14 @@
}
},
"node_modules/class-validator": {
- "version": "0.14.1",
- "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.1.tgz",
- "integrity": "sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==",
+ "version": "0.15.1",
+ "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.15.1.tgz",
+ "integrity": "sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw==",
"license": "MIT",
"dependencies": {
- "@types/validator": "^13.11.8",
- "libphonenumber-js": "^1.10.53",
- "validator": "^13.9.0"
+ "@types/validator": "^13.15.3",
+ "libphonenumber-js": "^1.11.1",
+ "validator": "^13.15.22"
}
},
"node_modules/classnames": {
@@ -8709,6 +8710,17 @@
"node": ">=0.4.0"
}
},
+ "node_modules/javascript-obfuscator/node_modules/class-validator": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.1.tgz",
+ "integrity": "sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/validator": "^13.11.8",
+ "libphonenumber-js": "^1.10.53",
+ "validator": "^13.9.0"
+ }
+ },
"node_modules/javascript-obfuscator/node_modules/eslint-scope": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
@@ -9981,6 +9993,8 @@
},
"node_modules/npm/node_modules/@isaacs/cliui": {
"version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10010,12 +10024,16 @@
},
"node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": {
"version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": {
"version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10048,6 +10066,8 @@
},
"node_modules/npm/node_modules/@isaacs/fs-minipass": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
+ "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10060,12 +10080,16 @@
},
"node_modules/npm/node_modules/@isaacs/string-locale-compare": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz",
+ "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==",
"dev": true,
"inBundle": true,
"license": "ISC"
},
"node_modules/npm/node_modules/@npmcli/agent": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz",
+ "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10082,6 +10106,8 @@
},
"node_modules/npm/node_modules/@npmcli/arborist": {
"version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-8.0.1.tgz",
+ "integrity": "sha512-ZyJWuvP+SdT7JmHkmtGyElm/MkQZP/i4boJXut6HDgx1tmJc/JZ9OwahRuKD+IyowJcLyB/bbaXtYh+RoTCUuw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10131,6 +10157,8 @@
},
"node_modules/npm/node_modules/@npmcli/config": {
"version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-9.0.0.tgz",
+ "integrity": "sha512-P5Vi16Y+c8E0prGIzX112ug7XxqfaPFUVW/oXAV+2VsxplKZEnJozqZ0xnK8V8w/SEsBf+TXhUihrEIAU4CA5Q==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10150,6 +10178,8 @@
},
"node_modules/npm/node_modules/@npmcli/fs": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz",
+ "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10162,6 +10192,8 @@
},
"node_modules/npm/node_modules/@npmcli/git": {
"version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.3.tgz",
+ "integrity": "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10181,6 +10213,8 @@
},
"node_modules/npm/node_modules/@npmcli/installed-package-contents": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz",
+ "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10197,6 +10231,8 @@
},
"node_modules/npm/node_modules/@npmcli/map-workspaces": {
"version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-4.0.2.tgz",
+ "integrity": "sha512-mnuMuibEbkaBTYj9HQ3dMe6L0ylYW+s/gfz7tBDMFY/la0w9Kf44P9aLn4/+/t3aTR3YUHKoT6XQL9rlicIe3Q==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10212,6 +10248,8 @@
},
"node_modules/npm/node_modules/@npmcli/metavuln-calculator": {
"version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-8.0.1.tgz",
+ "integrity": "sha512-WXlJx9cz3CfHSt9W9Opi1PTFc4WZLFomm5O8wekxQZmkyljrBRwATwDxfC9iOXJwYVmfiW1C1dUe0W2aN0UrSg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10228,6 +10266,8 @@
},
"node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": {
"version": "20.0.0",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-20.0.0.tgz",
+ "integrity": "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10259,6 +10299,8 @@
},
"node_modules/npm/node_modules/@npmcli/name-from-folder": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-3.0.0.tgz",
+ "integrity": "sha512-61cDL8LUc9y80fXn+lir+iVt8IS0xHqEKwPu/5jCjxQTVoSCmkXvw4vbMrzAMtmghz3/AkiBjhHkDKUH+kf7kA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10268,6 +10310,8 @@
},
"node_modules/npm/node_modules/@npmcli/node-gyp": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz",
+ "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10277,6 +10321,8 @@
},
"node_modules/npm/node_modules/@npmcli/package-json": {
"version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.2.0.tgz",
+ "integrity": "sha512-rCNLSB/JzNvot0SEyXqWZ7tX2B5dD2a1br2Dp0vSYVo5jh8Z0EZ7lS9TsZ1UtziddB1UfNUaMCc538/HztnJGA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10307,6 +10353,8 @@
},
"node_modules/npm/node_modules/@npmcli/query": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/query/-/query-4.0.1.tgz",
+ "integrity": "sha512-4OIPFb4weUUwkDXJf4Hh1inAn8neBGq3xsH4ZsAaN6FK3ldrFkH7jSpCc7N9xesi0Sp+EBXJ9eGMDrEww2Ztqw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10319,6 +10367,8 @@
},
"node_modules/npm/node_modules/@npmcli/redact": {
"version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.2.2.tgz",
+ "integrity": "sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10328,6 +10378,8 @@
},
"node_modules/npm/node_modules/@npmcli/run-script": {
"version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.1.0.tgz",
+ "integrity": "sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10345,6 +10397,8 @@
},
"node_modules/npm/node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10355,6 +10409,8 @@
},
"node_modules/npm/node_modules/@sigstore/protobuf-specs": {
"version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.4.3.tgz",
+ "integrity": "sha512-fk2zjD9117RL9BjqEwF7fwv7Q/P9yGsMV4MUJZ/DocaQJ6+3pKr+syBq1owU5Q5qGw5CUbXzm+4yJ2JVRDQeSA==",
"dev": true,
"inBundle": true,
"license": "Apache-2.0",
@@ -10364,6 +10420,8 @@
},
"node_modules/npm/node_modules/@sigstore/tuf": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.1.1.tgz",
+ "integrity": "sha512-eFFvlcBIoGwVkkwmTi/vEQFSva3xs5Ot3WmBcjgjVdiaoelBLQaQ/ZBfhlG0MnG0cmTYScPpk7eDdGDWUcFUmg==",
"dev": true,
"inBundle": true,
"license": "Apache-2.0",
@@ -10377,6 +10435,8 @@
},
"node_modules/npm/node_modules/@tufjs/canonical-json": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz",
+ "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10386,6 +10446,8 @@
},
"node_modules/npm/node_modules/abbrev": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz",
+ "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10404,6 +10466,8 @@
},
"node_modules/npm/node_modules/ansi-regex": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10431,18 +10495,24 @@
},
"node_modules/npm/node_modules/archy": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+ "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/balanced-match": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/bin-links": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-5.0.0.tgz",
+ "integrity": "sha512-sdleLVfCjBtgO5cNjA2HVRvWBJAHs4zwenaCPMNJAJU0yNxpzj80IpjOIimkpkr+mhlA+how5poQtt53PygbHA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10459,6 +10529,8 @@
},
"node_modules/npm/node_modules/binary-extensions": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10471,6 +10543,8 @@
},
"node_modules/npm/node_modules/brace-expansion": {
"version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10480,6 +10554,8 @@
},
"node_modules/npm/node_modules/cacache": {
"version": "19.0.1",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz",
+ "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10503,6 +10579,8 @@
},
"node_modules/npm/node_modules/cacache/node_modules/chownr": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
+ "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
"dev": true,
"inBundle": true,
"license": "BlueOak-1.0.0",
@@ -10544,6 +10622,8 @@
},
"node_modules/npm/node_modules/cacache/node_modules/yallist": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
+ "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
"dev": true,
"inBundle": true,
"license": "BlueOak-1.0.0",
@@ -10565,6 +10645,8 @@
},
"node_modules/npm/node_modules/chownr": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10589,6 +10671,8 @@
},
"node_modules/npm/node_modules/cidr-regex": {
"version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/cidr-regex/-/cidr-regex-4.1.3.tgz",
+ "integrity": "sha512-86M1y3ZeQvpZkZejQCcS+IaSWjlDUC+ORP0peScQ4uEUFCZ8bEQVz7NlJHqysoUb6w3zCjx4Mq/8/2RHhMwHYw==",
"dev": true,
"inBundle": true,
"license": "BSD-2-Clause",
@@ -10601,6 +10685,8 @@
},
"node_modules/npm/node_modules/cli-columns": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-columns/-/cli-columns-4.0.0.tgz",
+ "integrity": "sha512-XW2Vg+w+L9on9wtwKpyzluIPCWXjaBahI7mTcYjx+BVIYD9c3yqcv/yKC7CmdCZat4rq2yiE1UMSJC5ivKfMtQ==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10614,6 +10700,8 @@
},
"node_modules/npm/node_modules/cmd-shim": {
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-7.0.0.tgz",
+ "integrity": "sha512-rtpaCbr164TPPh+zFdkWpCyZuKkjpAzODfaZCf/SVJZzJN+4bHQb/LP3Jzq5/+84um3XXY8r548XiWKSborwVw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10623,6 +10711,8 @@
},
"node_modules/npm/node_modules/color-convert": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10635,18 +10725,24 @@
},
"node_modules/npm/node_modules/color-name": {
"version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/common-ancestor-path": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz",
+ "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==",
"dev": true,
"inBundle": true,
"license": "ISC"
},
"node_modules/npm/node_modules/cross-spawn": {
"version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10661,6 +10757,8 @@
},
"node_modules/npm/node_modules/cross-spawn/node_modules/which": {
"version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10676,6 +10774,8 @@
},
"node_modules/npm/node_modules/cssesc": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10714,18 +10814,24 @@
},
"node_modules/npm/node_modules/eastasianwidth": {
"version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/emoji-regex": {
"version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/encoding": {
"version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10736,6 +10842,8 @@
},
"node_modules/npm/node_modules/env-paths": {
"version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10745,6 +10853,8 @@
},
"node_modules/npm/node_modules/err-code": {
"version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
"dev": true,
"inBundle": true,
"license": "MIT"
@@ -10757,6 +10867,8 @@
},
"node_modules/npm/node_modules/fastest-levenshtein": {
"version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10766,6 +10878,8 @@
},
"node_modules/npm/node_modules/foreground-child": {
"version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10782,6 +10896,8 @@
},
"node_modules/npm/node_modules/fs-minipass": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
+ "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10814,12 +10930,16 @@
},
"node_modules/npm/node_modules/graceful-fs": {
"version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true,
"inBundle": true,
"license": "ISC"
},
"node_modules/npm/node_modules/hosted-git-info": {
"version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz",
+ "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10832,12 +10952,16 @@
},
"node_modules/npm/node_modules/http-cache-semantics": {
"version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
+ "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
"dev": true,
"inBundle": true,
"license": "BSD-2-Clause"
},
"node_modules/npm/node_modules/http-proxy-agent": {
"version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10851,6 +10975,8 @@
},
"node_modules/npm/node_modules/https-proxy-agent": {
"version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10864,6 +10990,8 @@
},
"node_modules/npm/node_modules/iconv-lite": {
"version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10877,6 +11005,8 @@
},
"node_modules/npm/node_modules/ignore-walk": {
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz",
+ "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10889,6 +11019,8 @@
},
"node_modules/npm/node_modules/imurmurhash": {
"version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10898,6 +11030,8 @@
},
"node_modules/npm/node_modules/ini": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz",
+ "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10907,6 +11041,8 @@
},
"node_modules/npm/node_modules/init-package-json": {
"version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-7.0.2.tgz",
+ "integrity": "sha512-Qg6nAQulaOQZjvaSzVLtYRqZmuqOi7gTknqqgdhZy7LV5oO+ppvHWq15tZYzGyxJLTH5BxRTqTa+cPDx2pSD9Q==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -10938,6 +11074,8 @@
},
"node_modules/npm/node_modules/ip-regex": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-5.0.0.tgz",
+ "integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10950,6 +11088,8 @@
},
"node_modules/npm/node_modules/is-cidr": {
"version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/is-cidr/-/is-cidr-5.1.1.tgz",
+ "integrity": "sha512-AwzRMjtJNTPOgm7xuYZ71715z99t+4yRnSnSzgK5err5+heYi4zMuvmpUadaJ28+KCXCQo8CjUrKQZRWSPmqTQ==",
"dev": true,
"inBundle": true,
"license": "BSD-2-Clause",
@@ -10962,6 +11102,8 @@
},
"node_modules/npm/node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -10971,12 +11113,16 @@
},
"node_modules/npm/node_modules/isexe": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true,
"inBundle": true,
"license": "ISC"
},
"node_modules/npm/node_modules/jackspeak": {
"version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"dev": true,
"inBundle": true,
"license": "BlueOak-1.0.0",
@@ -10998,6 +11144,8 @@
},
"node_modules/npm/node_modules/json-parse-even-better-errors": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz",
+ "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11007,6 +11155,8 @@
},
"node_modules/npm/node_modules/json-stringify-nice": {
"version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz",
+ "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11016,6 +11166,8 @@
},
"node_modules/npm/node_modules/jsonparse": {
"version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
"dev": true,
"engines": [
"node >= 0.2.0"
@@ -11025,18 +11177,24 @@
},
"node_modules/npm/node_modules/just-diff": {
"version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-6.0.2.tgz",
+ "integrity": "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/just-diff-apply": {
"version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.5.0.tgz",
+ "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/libnpmaccess": {
"version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-9.0.0.tgz",
+ "integrity": "sha512-mTCFoxyevNgXRrvgdOhghKJnCWByBc9yp7zX4u9RBsmZjwOYdUDEBfL5DdgD1/8gahsYnauqIWFbq0iK6tO6CQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11050,6 +11208,8 @@
},
"node_modules/npm/node_modules/libnpmdiff": {
"version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/libnpmdiff/-/libnpmdiff-7.0.1.tgz",
+ "integrity": "sha512-CPcLUr23hLwiil/nAlnMQ/eWSTXPPaX+Qe31di8JvcV2ELbbBueucZHBaXlXruUch6zIlSY6c7JCGNAqKN7yaQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11069,6 +11229,8 @@
},
"node_modules/npm/node_modules/libnpmexec": {
"version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/libnpmexec/-/libnpmexec-9.0.1.tgz",
+ "integrity": "sha512-+SI/x9p0KUkgJdW9L0nDNqtjsFRY3yA5kQKdtGYNMXX4iP/MXQjuXF8MaUAweuV6Awm8plxqn8xCPs2TelZEUg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11090,6 +11252,8 @@
},
"node_modules/npm/node_modules/libnpmfund": {
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/libnpmfund/-/libnpmfund-6.0.1.tgz",
+ "integrity": "sha512-UBbHY9yhhZVffbBpFJq+TsR2KhhEqpQ2mpsIJa6pt0PPQaZ2zgOjvGUYEjURYIGwg2wL1vfQFPeAtmN5w6i3Gg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11102,6 +11266,8 @@
},
"node_modules/npm/node_modules/libnpmhook": {
"version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/libnpmhook/-/libnpmhook-11.0.0.tgz",
+ "integrity": "sha512-Xc18rD9NFbRwZbYCQ+UCF5imPsiHSyuQA8RaCA2KmOUo8q4kmBX4JjGWzmZnxZCT8s6vwzmY1BvHNqBGdg9oBQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11115,6 +11281,8 @@
},
"node_modules/npm/node_modules/libnpmorg": {
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/libnpmorg/-/libnpmorg-7.0.0.tgz",
+ "integrity": "sha512-DcTodX31gDEiFrlIHurBQiBlBO6Var2KCqMVCk+HqZhfQXqUfhKGmFOp0UHr6HR1lkTVM0MzXOOYtUObk0r6Dg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11128,6 +11296,8 @@
},
"node_modules/npm/node_modules/libnpmpack": {
"version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/libnpmpack/-/libnpmpack-8.0.1.tgz",
+ "integrity": "sha512-E53w3QcldAXg5cG9NpXZcsgNiLw5AEtu7ufGJk6+dxudD0/U5Y6vHIws+CJiI76I9rAidXasKmmS2mwiYDncBw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11143,6 +11313,8 @@
},
"node_modules/npm/node_modules/libnpmpublish": {
"version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-10.0.1.tgz",
+ "integrity": "sha512-xNa1DQs9a8dZetNRV0ky686MNzv1MTqB3szgOlRR3Fr24x1gWRu7aB9OpLZsml0YekmtppgHBkyZ+8QZlzmEyw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11162,6 +11334,8 @@
},
"node_modules/npm/node_modules/libnpmsearch": {
"version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/libnpmsearch/-/libnpmsearch-8.0.0.tgz",
+ "integrity": "sha512-W8FWB78RS3Nkl1gPSHOlF024qQvcoU/e3m9BGDuBfVZGfL4MJ91GXXb04w3zJCGOW9dRQUyWVEqupFjCrgltDg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11174,6 +11348,8 @@
},
"node_modules/npm/node_modules/libnpmteam": {
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/libnpmteam/-/libnpmteam-7.0.0.tgz",
+ "integrity": "sha512-PKLOoVukN34qyJjgEm5DEOnDwZkeVMUHRx8NhcKDiCNJGPl7G/pF1cfBw8yicMwRlHaHkld1FdujOzKzy4AlwA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11187,6 +11363,8 @@
},
"node_modules/npm/node_modules/libnpmversion": {
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/libnpmversion/-/libnpmversion-7.0.0.tgz",
+ "integrity": "sha512-0xle91R6F8r/Q/4tHOnyKko+ZSquEXNdxwRdKCPv4kC1cOVBMFXRsKKrVtRKtXcFn362U8ZlJefk4Apu00424g==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11203,12 +11381,16 @@
},
"node_modules/npm/node_modules/lru-cache": {
"version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
"inBundle": true,
"license": "ISC"
},
"node_modules/npm/node_modules/make-fetch-happen": {
"version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz",
+ "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11231,6 +11413,8 @@
},
"node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11240,6 +11424,8 @@
},
"node_modules/npm/node_modules/minimatch": {
"version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11255,6 +11441,8 @@
},
"node_modules/npm/node_modules/minipass": {
"version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11264,6 +11452,8 @@
},
"node_modules/npm/node_modules/minipass-collect": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz",
+ "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11276,6 +11466,8 @@
},
"node_modules/npm/node_modules/minipass-fetch": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.1.tgz",
+ "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11293,6 +11485,8 @@
},
"node_modules/npm/node_modules/minipass-flush": {
"version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11305,6 +11499,8 @@
},
"node_modules/npm/node_modules/minipass-flush/node_modules/minipass": {
"version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11317,6 +11513,8 @@
},
"node_modules/npm/node_modules/minipass-pipeline": {
"version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11329,6 +11527,8 @@
},
"node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": {
"version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11341,6 +11541,8 @@
},
"node_modules/npm/node_modules/minipass-sized": {
"version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+ "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11353,6 +11555,8 @@
},
"node_modules/npm/node_modules/minipass-sized/node_modules/minipass": {
"version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11377,6 +11581,8 @@
},
"node_modules/npm/node_modules/mkdirp": {
"version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11389,12 +11595,16 @@
},
"node_modules/npm/node_modules/ms": {
"version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/mute-stream": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz",
+ "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11428,6 +11638,8 @@
},
"node_modules/npm/node_modules/node-gyp/node_modules/chownr": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
+ "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
"dev": true,
"inBundle": true,
"license": "BlueOak-1.0.0",
@@ -11469,6 +11681,8 @@
},
"node_modules/npm/node_modules/node-gyp/node_modules/yallist": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
+ "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
"dev": true,
"inBundle": true,
"license": "BlueOak-1.0.0",
@@ -11478,6 +11692,8 @@
},
"node_modules/npm/node_modules/nopt": {
"version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz",
+ "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11507,6 +11723,8 @@
},
"node_modules/npm/node_modules/npm-audit-report": {
"version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/npm-audit-report/-/npm-audit-report-6.0.0.tgz",
+ "integrity": "sha512-Ag6Y1irw/+CdSLqEEAn69T8JBgBThj5mw0vuFIKeP7hATYuQuS5jkMjK6xmVB8pr7U4g5Audbun0lHhBDMIBRA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11516,6 +11734,8 @@
},
"node_modules/npm/node_modules/npm-bundled": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz",
+ "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11540,6 +11760,8 @@
},
"node_modules/npm/node_modules/npm-normalize-package-bin": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz",
+ "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11549,6 +11771,8 @@
},
"node_modules/npm/node_modules/npm-package-arg": {
"version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz",
+ "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11564,6 +11788,8 @@
},
"node_modules/npm/node_modules/npm-packlist": {
"version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-9.0.0.tgz",
+ "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11576,6 +11802,8 @@
},
"node_modules/npm/node_modules/npm-pick-manifest": {
"version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz",
+ "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11591,6 +11819,8 @@
},
"node_modules/npm/node_modules/npm-profile": {
"version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-11.0.1.tgz",
+ "integrity": "sha512-HP5Cw9WHwFS9vb4fxVlkNAQBUhVL5BmW6rAR+/JWkpwqcFJid7TihKUdYDWqHl0NDfLd0mpucheGySqo8ysyfw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11604,6 +11834,8 @@
},
"node_modules/npm/node_modules/npm-registry-fetch": {
"version": "18.0.2",
+ "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz",
+ "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11623,6 +11855,8 @@
},
"node_modules/npm/node_modules/npm-user-validate": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-3.0.0.tgz",
+ "integrity": "sha512-9xi0RdSmJ4mPYTC393VJPz1Sp8LyCx9cUnm/L9Qcb3cFO8gjT4mN20P9FAsea8qDHdQ7LtcN8VLh2UT47SdKCw==",
"dev": true,
"inBundle": true,
"license": "BSD-2-Clause",
@@ -11644,12 +11878,16 @@
},
"node_modules/npm/node_modules/package-json-from-dist": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"dev": true,
"inBundle": true,
"license": "BlueOak-1.0.0"
},
"node_modules/npm/node_modules/pacote": {
"version": "19.0.1",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-19.0.1.tgz",
+ "integrity": "sha512-zIpxWAsr/BvhrkSruspG8aqCQUUrWtpwx0GjiRZQhEM/pZXrigA32ElN3vTcCPUDOFmHr6SFxwYrvVUs5NTEUg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11681,6 +11919,8 @@
},
"node_modules/npm/node_modules/parse-conflict-json": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-4.0.0.tgz",
+ "integrity": "sha512-37CN2VtcuvKgHUs8+0b1uJeEsbGn61GRHz469C94P5xiOoqpDYJYwjg4RY9Vmz39WyZAVkR5++nbJwLMIgOCnQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11695,6 +11935,8 @@
},
"node_modules/npm/node_modules/path-key": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11704,6 +11946,8 @@
},
"node_modules/npm/node_modules/path-scurry": {
"version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
"inBundle": true,
"license": "BlueOak-1.0.0",
@@ -11733,6 +11977,8 @@
},
"node_modules/npm/node_modules/proc-log": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz",
+ "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11742,6 +11988,8 @@
},
"node_modules/npm/node_modules/proggy": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/proggy/-/proggy-3.0.0.tgz",
+ "integrity": "sha512-QE8RApCM3IaRRxVzxrjbgNMpQEX6Wu0p0KBeoSiSEw5/bsGwZHsshF4LCxH2jp/r6BU+bqA3LrMDEYNfJnpD8Q==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11751,6 +11999,8 @@
},
"node_modules/npm/node_modules/promise-all-reject-late": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz",
+ "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11760,6 +12010,8 @@
},
"node_modules/npm/node_modules/promise-call-limit": {
"version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-3.0.2.tgz",
+ "integrity": "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11769,6 +12021,8 @@
},
"node_modules/npm/node_modules/promise-retry": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11782,6 +12036,8 @@
},
"node_modules/npm/node_modules/promzard": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/promzard/-/promzard-2.0.0.tgz",
+ "integrity": "sha512-Ncd0vyS2eXGOjchIRg6PVCYKetJYrW1BSbbIo+bKdig61TB6nH2RQNF2uP+qMpsI73L/jURLWojcw8JNIKZ3gg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11794,6 +12050,8 @@
},
"node_modules/npm/node_modules/qrcode-terminal": {
"version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz",
+ "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==",
"dev": true,
"inBundle": true,
"bin": {
@@ -11802,6 +12060,8 @@
},
"node_modules/npm/node_modules/read": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/read/-/read-4.1.0.tgz",
+ "integrity": "sha512-uRfX6K+f+R8OOrYScaM3ixPY4erg69f8DN6pgTvMcA9iRc8iDhwrA4m3Yu8YYKsXJgVvum+m8PkRboZwwuLzYA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11814,6 +12074,8 @@
},
"node_modules/npm/node_modules/read-cmd-shim": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-5.0.0.tgz",
+ "integrity": "sha512-SEbJV7tohp3DAAILbEMPXavBjAnMN0tVnh4+9G8ihV4Pq3HYF9h8QNez9zkJ1ILkv9G2BjdzwctznGZXgu/HGw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11823,6 +12085,8 @@
},
"node_modules/npm/node_modules/read-package-json-fast": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz",
+ "integrity": "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11836,6 +12100,8 @@
},
"node_modules/npm/node_modules/retry": {
"version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11845,6 +12111,8 @@
},
"node_modules/npm/node_modules/safer-buffer": {
"version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11864,6 +12132,8 @@
},
"node_modules/npm/node_modules/shebang-command": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11876,6 +12146,8 @@
},
"node_modules/npm/node_modules/shebang-regex": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11885,6 +12157,8 @@
},
"node_modules/npm/node_modules/signal-exit": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -11897,6 +12171,8 @@
},
"node_modules/npm/node_modules/sigstore": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.1.0.tgz",
+ "integrity": "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==",
"dev": true,
"inBundle": true,
"license": "Apache-2.0",
@@ -11914,6 +12190,8 @@
},
"node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz",
+ "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==",
"dev": true,
"inBundle": true,
"license": "Apache-2.0",
@@ -11926,6 +12204,8 @@
},
"node_modules/npm/node_modules/sigstore/node_modules/@sigstore/core": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz",
+ "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==",
"dev": true,
"inBundle": true,
"license": "Apache-2.0",
@@ -11935,6 +12215,8 @@
},
"node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.1.0.tgz",
+ "integrity": "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw==",
"dev": true,
"inBundle": true,
"license": "Apache-2.0",
@@ -11952,6 +12234,8 @@
},
"node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.1.1.tgz",
+ "integrity": "sha512-hVJD77oT67aowHxwT4+M6PGOp+E2LtLdTK3+FC0lBO9T7sYwItDMXZ7Z07IDCvR1M717a4axbIWckrW67KMP/w==",
"dev": true,
"inBundle": true,
"license": "Apache-2.0",
@@ -11966,6 +12250,8 @@
},
"node_modules/npm/node_modules/smart-buffer": {
"version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -11990,6 +12276,8 @@
},
"node_modules/npm/node_modules/socks-proxy-agent": {
"version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
+ "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12004,6 +12292,8 @@
},
"node_modules/npm/node_modules/spdx-correct": {
"version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+ "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
"dev": true,
"inBundle": true,
"license": "Apache-2.0",
@@ -12014,6 +12304,8 @@
},
"node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12024,12 +12316,16 @@
},
"node_modules/npm/node_modules/spdx-exceptions": {
"version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+ "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
"dev": true,
"inBundle": true,
"license": "CC-BY-3.0"
},
"node_modules/npm/node_modules/spdx-expression-parse": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+ "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12052,6 +12348,8 @@
},
"node_modules/npm/node_modules/ssri": {
"version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz",
+ "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12064,6 +12362,8 @@
},
"node_modules/npm/node_modules/string-width": {
"version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12079,6 +12379,8 @@
"node_modules/npm/node_modules/string-width-cjs": {
"name": "string-width",
"version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12093,6 +12395,8 @@
},
"node_modules/npm/node_modules/strip-ansi": {
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12106,6 +12410,8 @@
"node_modules/npm/node_modules/strip-ansi-cjs": {
"name": "strip-ansi",
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12118,6 +12424,8 @@
},
"node_modules/npm/node_modules/supports-color": {
"version": "9.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz",
+ "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12130,6 +12438,8 @@
},
"node_modules/npm/node_modules/tar": {
"version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12147,6 +12457,8 @@
},
"node_modules/npm/node_modules/tar/node_modules/fs-minipass": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12159,6 +12471,8 @@
},
"node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
"version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12171,6 +12485,8 @@
},
"node_modules/npm/node_modules/tar/node_modules/minipass": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12180,6 +12496,8 @@
},
"node_modules/npm/node_modules/tar/node_modules/minizlib": {
"version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12193,6 +12511,8 @@
},
"node_modules/npm/node_modules/tar/node_modules/minizlib/node_modules/minipass": {
"version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12205,12 +12525,16 @@
},
"node_modules/npm/node_modules/text-table": {
"version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/tiny-relative-date": {
"version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz",
+ "integrity": "sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A==",
"dev": true,
"inBundle": true,
"license": "MIT"
@@ -12259,6 +12583,8 @@
},
"node_modules/npm/node_modules/treeverse": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-3.0.0.tgz",
+ "integrity": "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12282,6 +12608,8 @@
},
"node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz",
+ "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12295,6 +12623,8 @@
},
"node_modules/npm/node_modules/unique-filename": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz",
+ "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12307,6 +12637,8 @@
},
"node_modules/npm/node_modules/unique-slug": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz",
+ "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12319,12 +12651,16 @@
},
"node_modules/npm/node_modules/util-deprecate": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/validate-npm-package-license": {
"version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
"dev": true,
"inBundle": true,
"license": "Apache-2.0",
@@ -12335,6 +12671,8 @@
},
"node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12354,12 +12692,16 @@
},
"node_modules/npm/node_modules/walk-up-path": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz",
+ "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==",
"dev": true,
"inBundle": true,
"license": "ISC"
},
"node_modules/npm/node_modules/which": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz",
+ "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12384,6 +12726,8 @@
},
"node_modules/npm/node_modules/wrap-ansi": {
"version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12402,6 +12746,8 @@
"node_modules/npm/node_modules/wrap-ansi-cjs": {
"name": "wrap-ansi",
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12419,6 +12765,8 @@
},
"node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
"version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12446,12 +12794,16 @@
},
"node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": {
"version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": {
"version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dev": true,
"inBundle": true,
"license": "MIT",
@@ -12484,6 +12836,8 @@
},
"node_modules/npm/node_modules/write-file-atomic": {
"version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-6.0.0.tgz",
+ "integrity": "sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -12497,6 +12851,8 @@
},
"node_modules/npm/node_modules/yallist": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true,
"inBundle": true,
"license": "ISC"
@@ -17121,9 +17477,9 @@
}
},
"node_modules/validator": {
- "version": "13.12.0",
- "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz",
- "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==",
+ "version": "13.15.35",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.35.tgz",
+ "integrity": "sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
diff --git a/package.json b/package.json
index 6558621..cbe5c9a 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
"animejs": "3.2.2",
"antd": "5.16.2",
"bcryptjs": "^2.4.3",
+ "class-validator": "^0.15.1",
"curlconverter": "^4.12.0",
"dayjs": "^1.11.19",
"framer-motion": "11.2.6",
From 9044712e1a885647602e0f6c10613f6e20fdf783 Mon Sep 17 00:00:00 2001
From: semantic-release-bot
Date: Tue, 14 Apr 2026 10:14:49 +0000
Subject: [PATCH 27/47] chore(release): 1.4.0-develop.9 [skip ci]
# [1.4.0-develop.9](https://github.com/betterbugs/dev-tools/compare/v1.4.0-develop.8...v1.4.0-develop.9) (2026-04-14)
### Features
* add class-validator dependency and update page styles ([#81](https://github.com/betterbugs/dev-tools/issues/81)) ([67f1aeb](https://github.com/betterbugs/dev-tools/commit/67f1aeb5a82cad25f2c8bb3dcdc67e453b62cee2))
---
CHANGELOG.md | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 78453f3..a84c7a4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+# [1.4.0-develop.9](https://github.com/betterbugs/dev-tools/compare/v1.4.0-develop.8...v1.4.0-develop.9) (2026-04-14)
+
+
+### Features
+
+* add class-validator dependency and update page styles ([#81](https://github.com/betterbugs/dev-tools/issues/81)) ([67f1aeb](https://github.com/betterbugs/dev-tools/commit/67f1aeb5a82cad25f2c8bb3dcdc67e453b62cee2))
+
# [1.4.0-develop.8](https://github.com/betterbugs/dev-tools/compare/v1.4.0-develop.7...v1.4.0-develop.8) (2026-03-08)
From 35c3e7901069e60a62e44a9987298945f18f65cc Mon Sep 17 00:00:00 2001
From: zeel0m
Date: Mon, 20 Apr 2026 11:10:03 +0530
Subject: [PATCH 28/47] feat: add Image Resizer and Time Calculator components
- Introduced Image Resizer component for local image resizing with format selection and aspect ratio options.
- Added Time Calculator component for performing arithmetic operations on time values and calculating durations between dates.
- Updated constants and routes to include new tools in the development tools list.
- Refined styles in development tools for better UI consistency.
---
app/[slug]/page.tsx | 4 +-
.../imageResizer.tsx | 587 ++++++++++++++++++
.../timeCalculator.tsx | 425 +++++++++++++
app/developmentToolsStyles.module.scss | 185 +-----
app/libs/constants.tsx | 28 +
app/libs/developmentToolsConstant.tsx | 186 ++++++
app/page.tsx | 6 +-
7 files changed, 1251 insertions(+), 170 deletions(-)
create mode 100644 app/components/developmentToolsComponent/imageResizer.tsx
create mode 100644 app/components/developmentToolsComponent/timeCalculator.tsx
diff --git a/app/[slug]/page.tsx b/app/[slug]/page.tsx
index b77333d..5bd7b63 100644
--- a/app/[slug]/page.tsx
+++ b/app/[slug]/page.tsx
@@ -214,9 +214,9 @@ const Page = ({ params: { slug } }: { params: { slug: string } }) => {
{/* Tools Panel - 20% width, fixed */}
{development_tools_list?.length > 0 && (
-
+
-
+
Other Tools
diff --git a/app/components/developmentToolsComponent/imageResizer.tsx b/app/components/developmentToolsComponent/imageResizer.tsx
new file mode 100644
index 0000000..b8d35a0
--- /dev/null
+++ b/app/components/developmentToolsComponent/imageResizer.tsx
@@ -0,0 +1,587 @@
+"use client";
+
+import React, { useEffect, useMemo, useRef, useState } from "react";
+import DevelopmentToolsStyles from "../../developmentToolsStyles.module.scss";
+
+const clamp = (value: number, min: number, max: number) => {
+ return Math.min(max, Math.max(min, value));
+};
+
+type LoadedImage = {
+ img: HTMLImageElement;
+ width: number;
+ height: number;
+};
+
+type OutputFormat = "png" | "jpg" | "webp";
+type SizeUnit = "KB" | "MB";
+
+const readFileAsDataURL = (file: File): Promise
=> {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(String(reader.result));
+ reader.onerror = reject;
+ reader.readAsDataURL(file);
+ });
+};
+
+const ImageResizer = () => {
+ const canvasRef = useRef(null);
+
+ const [src, setSrc] = useState("");
+ const [image, setImage] = useState(null);
+ const [fileName, setFileName] = useState("");
+ const [error, setError] = useState("");
+ const [isDragging, setIsDragging] = useState(false);
+
+ const [keepAspectRatio, setKeepAspectRatio] = useState(true);
+ const [targetWidth, setTargetWidth] = useState(0);
+ const [targetHeight, setTargetHeight] = useState(0);
+
+ const [format, setFormat] = useState("png");
+ const [quality, setQuality] = useState(92); // for jpg/webp
+ const [transparent, setTransparent] = useState(true); // for jpg, affects bg fill
+ const [bg, setBg] = useState("#ffffff");
+
+ const [output, setOutput] = useState("");
+ const [outputBytes, setOutputBytes] = useState(0);
+ const [targetSize, setTargetSize] = useState(300);
+ const [targetUnit, setTargetUnit] = useState("KB");
+ const [isOptimizing, setIsOptimizing] = useState(false);
+
+ const aspect = useMemo(() => {
+ if (!image) return 1;
+ return image.width / Math.max(1, image.height);
+ }, [image]);
+
+ useEffect(() => {
+ if (!src) return setImage(null);
+ const img = new Image();
+ img.crossOrigin = "anonymous";
+ img.onload = () => {
+ setImage({ img, width: img.width, height: img.height });
+ };
+ img.onerror = () => setError("Failed to load image");
+ img.src = src;
+ }, [src]);
+
+ useEffect(() => {
+ if (!image) return;
+ setTargetWidth(image.width);
+ setTargetHeight(image.height);
+ }, [image]);
+
+ const mime = useMemo(() => {
+ if (format === "jpg") return "image/jpeg";
+ if (format === "webp") return "image/webp";
+ return "image/png";
+ }, [format]);
+
+ const normalizedQuality = useMemo(() => {
+ if (format === "png") return undefined;
+ return clamp(quality / 100, 0.1, 1);
+ }, [format, quality]);
+
+ const renderToBlob = (qualityOverride?: number): Promise => {
+ if (!image) return Promise.resolve(null);
+ const canvas = canvasRef.current;
+ if (!canvas) return Promise.resolve(null);
+
+ const w = clamp(Math.floor(targetWidth || 0), 1, 20000);
+ const h = clamp(Math.floor(targetHeight || 0), 1, 20000);
+
+ canvas.width = w;
+ canvas.height = h;
+ const ctx = canvas.getContext("2d");
+ if (!ctx) return Promise.resolve(null);
+
+ ctx.clearRect(0, 0, w, h);
+ if (format === "jpg" && !transparent) {
+ ctx.fillStyle = bg;
+ ctx.fillRect(0, 0, w, h);
+ }
+
+ ctx.imageSmoothingEnabled = true;
+ ctx.imageSmoothingQuality = "high";
+ ctx.drawImage(image.img, 0, 0, w, h);
+
+ const q =
+ format === "png"
+ ? undefined
+ : typeof qualityOverride === "number"
+ ? clamp(qualityOverride, 0.1, 1)
+ : normalizedQuality;
+
+ return new Promise((resolve) => {
+ canvas.toBlob(
+ (blob) => resolve(blob),
+ mime,
+ q
+ );
+ });
+ };
+
+ const draw = async () => {
+ if (!image) return;
+ const blob = await renderToBlob();
+ if (!blob) return;
+ setOutput((prev) => {
+ if (prev) URL.revokeObjectURL(prev);
+ return URL.createObjectURL(blob);
+ });
+ setOutputBytes(blob.size);
+ };
+
+ useEffect(() => {
+ draw();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [image, targetWidth, targetHeight, format, quality, transparent, bg]);
+
+ useEffect(() => {
+ return () => {
+ if (output) URL.revokeObjectURL(output);
+ };
+ }, [output]);
+
+ const onFile = async (file?: File) => {
+ if (!file) return;
+ setError("");
+ try {
+ const dataUrl = await readFileAsDataURL(file);
+ setSrc(dataUrl);
+ setFileName(file.name);
+ } catch {
+ setError("Failed to read file");
+ }
+ };
+
+ const setWidthAndMaybeHeight = (w: number) => {
+ const newW = clamp(Math.floor(w || 0), 1, 20000);
+ setTargetWidth(newW);
+ if (keepAspectRatio && image) {
+ setTargetHeight(Math.max(1, Math.round(newW / aspect)));
+ }
+ };
+
+ const setHeightAndMaybeWidth = (h: number) => {
+ const newH = clamp(Math.floor(h || 0), 1, 20000);
+ setTargetHeight(newH);
+ if (keepAspectRatio && image) {
+ setTargetWidth(Math.max(1, Math.round(newH * aspect)));
+ }
+ };
+
+ const download = () => {
+ if (!output) return;
+ const a = document.createElement("a");
+ a.href = output;
+ const base = fileName ? fileName.replace(/\.[^.]+$/, "") : "image";
+ a.download = `${base}-${targetWidth}x${targetHeight}.${format === "jpg" ? "jpg" : format}`;
+ a.click();
+ };
+
+ const targetBytes = useMemo(() => {
+ const n = Math.max(1, Number(targetSize) || 0);
+ return targetUnit === "MB" ? Math.round(n * 1024 * 1024) : Math.round(n * 1024);
+ }, [targetSize, targetUnit]);
+
+ const compressToTargetSize = async () => {
+ if (!image) return;
+ if (format === "png") return;
+ setError("");
+ setIsOptimizing(true);
+ try {
+ const maxIters = 9;
+ let lo = 0.1;
+ let hi = 1;
+ let bestBlob: Blob | null = null;
+ let bestQ = hi;
+
+ for (let i = 0; i < maxIters; i++) {
+ const mid = (lo + hi) / 2;
+ const blob = await renderToBlob(mid);
+ if (!blob) break;
+
+ if (blob.size <= targetBytes) {
+ bestBlob = blob;
+ bestQ = mid;
+ lo = mid;
+ } else {
+ hi = mid;
+ }
+ }
+
+ const finalBlob = bestBlob ?? (await renderToBlob(0.1));
+ if (!finalBlob) return;
+
+ setQuality(Math.round(clamp(bestQ, 0.1, 1) * 100));
+ setOutput((prev) => {
+ if (prev) URL.revokeObjectURL(prev);
+ return URL.createObjectURL(finalBlob);
+ });
+ setOutputBytes(finalBlob.size);
+ } catch {
+ setError("Failed to optimize file size");
+ } finally {
+ setIsOptimizing(false);
+ }
+ };
+
+ const clearAll = () => {
+ if (output) URL.revokeObjectURL(output);
+ setSrc("");
+ setImage(null);
+ setFileName("");
+ setError("");
+ setKeepAspectRatio(true);
+ setTargetWidth(0);
+ setTargetHeight(0);
+ setFormat("png");
+ setQuality(92);
+ setTransparent(true);
+ setBg("#ffffff");
+ setOutput("");
+ setOutputBytes(0);
+ setTargetSize(300);
+ setTargetUnit("KB");
+ setIsOptimizing(false);
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
Upload
+
Drag & drop or pick a file
+
+ {image && (
+
+ {image.width}×{image.height}px
+
+ )}
+
+
+
{
+ e.preventDefault();
+ setIsDragging(true);
+ }}
+ onDragEnter={() => setIsDragging(true)}
+ onDragLeave={() => setIsDragging(false)}
+ onDrop={(e) => {
+ e.preventDefault();
+ setIsDragging(false);
+ onFile(e.dataTransfer.files?.[0]);
+ }}
+ className={`rounded-xl border border-dashed ${isDragging ? "border-primary bg-black/60" : "border-[#222222] bg-black/40"
+ } p-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 transition-colors`}
+ >
+
+
+ {fileName || "Drop an image here…"}
+
+
We never upload your file.
+
+
+ {src && (
+
+ Remove
+
+ )}
+
+
+
+
+
+
+
+
Resize
+
Set output dimensions in pixels
+
+
+
+
+
+
+
+
Locks width/height together.
+
+
setKeepAspectRatio(e.target.checked)}
+ disabled={!image}
+ />
+
+
+
+
+
+
Export
+
Choose format and compression
+
+
+
+ setFormat("png")}
+ className={`flex-1 px-2 py-2 rounded-lg text-sm ${format === "png" ? "bg-white/10 text-white" : "text-white/70 hover:text-white"
+ }`}
+ >
+ PNG
+
+ setFormat("jpg")}
+ className={`flex-1 px-2 py-2 rounded-lg text-sm ${format === "jpg" ? "bg-white/10 text-white" : "text-white/70 hover:text-white"
+ }`}
+ >
+ JPG
+
+ setFormat("webp")}
+ className={`flex-1 px-2 py-2 rounded-lg text-sm ${format === "webp" ? "bg-white/10 text-white" : "text-white/70 hover:text-white"
+ }`}
+ >
+ WebP
+
+
+
+ {format !== "png" && (
+
+
+ Quality
+ {quality}
+
+
setQuality(Number(e.target.value))}
+ style={{ accentColor: "#00DA92" }}
+ className="w-full mt-2"
+ />
+
+ )}
+
+
+
+
+
Target file size
+
+ Works for JPG/WebP (PNG is lossless).
+
+
+
+
+ setTargetSize(Number(e.target.value))}
+ className="col-span-2 w-full bg-black border border-[#222222] rounded-lg px-3 py-2 text-white focus:outline-none focus:border-primary"
+ disabled={!image || format === "png"}
+ />
+
+
+
+ {isOptimizing ? "Optimizing…" : `Compress to ≤ ${(targetBytes / 1024).toFixed(0)} KB`}
+
+
+
+ {format === "jpg" && (
+
+
+
+
Background
+
JPG has no transparency.
+
+
+ setTransparent(!e.target.checked)}
+ />
+
+
+
+
+
+
setBg(e.target.value)}
+ className="w-9 h-9 rounded-md border border-[#222222]"
+ disabled={transparent}
+ />
+
+ {["#ffffff", "#000000", "#f43f5e", "#f59e0b", "#10b981", "#3b82f6"].map((c) => (
+ {
+ setBg(c);
+ setTransparent(false);
+ }}
+ />
+ ))}
+
+
+
+ )}
+
+
+
+ Download
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
Preview
+
Canvas render of your export
+
+ {image && (
+
+ Output: {targetWidth}×{targetHeight}px
+
+ )}
+
+
+
+ {/* Keep canvas mounted so `draw()` can always produce output */}
+
+ {output ? (
+

+ ) : (
+
Upload an image to preview the result
+ )}
+
+ {output ? (
+
+
+ Size: {(outputBytes / 1024).toFixed(1)} KB
+
+ {format !== "png" && (
+
+ Quality: {quality}
+
+ )}
+
+ ) : null}
+
+
+
+
+ {error && (
+
+ )}
+
+
+
+
+
+
+ );
+};
+
+export default ImageResizer;
+
diff --git a/app/components/developmentToolsComponent/timeCalculator.tsx b/app/components/developmentToolsComponent/timeCalculator.tsx
new file mode 100644
index 0000000..3c23cf9
--- /dev/null
+++ b/app/components/developmentToolsComponent/timeCalculator.tsx
@@ -0,0 +1,425 @@
+"use client";
+
+import React, { useMemo, useState } from "react";
+import DevelopmentToolsStyles from "../../developmentToolsStyles.module.scss";
+
+type Mode = "add" | "subtract" | "multiply" | "divide" | "between";
+type Unit = "ms" | "s" | "min" | "h" | "d" | "w" | "mo" | "y";
+
+const UNIT_OPTIONS: { value: Unit; label: string }[] = [
+ { value: "ms", label: "ms" },
+ { value: "s", label: "seconds" },
+ { value: "min", label: "minutes" },
+ { value: "h", label: "hours" },
+ { value: "d", label: "days" },
+ { value: "w", label: "weeks" },
+ { value: "mo", label: "months*" },
+ { value: "y", label: "years*" },
+];
+
+const UNIT_TO_MS: Record = {
+ ms: 1,
+ s: 1000,
+ min: 60_000,
+ h: 3_600_000,
+ d: 86_400_000,
+ w: 604_800_000,
+ // Omni-style approximations
+ mo: 30.5 * 86_400_000,
+ y: 365 * 86_400_000,
+};
+
+const pad2 = (n: number) => String(n).padStart(2, "0");
+
+const formatPretty = (totalMs: number) => {
+ const sign = totalMs < 0 ? "-" : "";
+ const ms = Math.abs(Math.trunc(totalMs));
+ const totalSeconds = Math.floor(ms / 1000);
+ const seconds = totalSeconds % 60;
+ const totalMinutes = Math.floor(totalSeconds / 60);
+ const minutes = totalMinutes % 60;
+ const hours = Math.floor(totalMinutes / 60);
+ return `${sign}${hours} h ${minutes} min ${seconds} sec`;
+};
+
+const breakdown = (totalMs: number) => {
+ const sign = totalMs < 0 ? -1 : 1;
+ let ms = Math.abs(Math.trunc(totalMs));
+ const days = Math.floor(ms / UNIT_TO_MS.d);
+ ms -= days * UNIT_TO_MS.d;
+ const hours = Math.floor(ms / UNIT_TO_MS.h);
+ ms -= hours * UNIT_TO_MS.h;
+ const minutes = Math.floor(ms / UNIT_TO_MS.min);
+ ms -= minutes * UNIT_TO_MS.min;
+ const seconds = Math.floor(ms / UNIT_TO_MS.s);
+ ms -= seconds * UNIT_TO_MS.s;
+ return { sign, days, hours, minutes, seconds, milliseconds: ms };
+};
+
+type HMSRow = { h: number; m: number; s: number };
+
+const DEFAULT_HMS_ROWS: HMSRow[] = [
+ { h: 0, m: 0, s: 0 },
+ { h: 0, m: 0, s: 0 },
+];
+
+const toMs = (r: HMSRow) => (Number(r.h) * 3600 + Number(r.m) * 60 + Number(r.s)) * 1000;
+
+const calc = (
+ mode: Mode,
+ rows: HMSRow[],
+ multiplier: number,
+ divisor: number,
+ betweenStart: string,
+ betweenEnd: string
+) => {
+ const total = rows.reduce((acc, r) => acc + toMs(r), 0);
+
+ if (mode === "add") return { ms: total, error: "" };
+
+ if (mode === "subtract") {
+ if (rows.length < 2) return { ms: total, error: "" };
+ const first = toMs(rows[0] ?? { h: 0, m: 0, s: 0 });
+ const rest = rows.slice(1).reduce((acc, r) => acc + toMs(r), 0);
+ return { ms: first - rest, error: "" };
+ }
+
+ if (mode === "multiply") return { ms: total * Number(multiplier || 0), error: "" };
+
+ if (mode === "divide") {
+ const d = Number(divisor || 0);
+ if (d === 0) return { ms: 0, error: "Divisor cannot be 0." };
+ return { ms: total / d, error: "" };
+ }
+
+ // between
+ if (!betweenStart || !betweenEnd) return { ms: 0, error: "" };
+ const a = new Date(betweenStart).getTime();
+ const b = new Date(betweenEnd).getTime();
+ if (!Number.isFinite(a) || !Number.isFinite(b)) {
+ return { ms: 0, error: "Please select valid start and end dates." };
+ }
+ return { ms: b - a, error: "" };
+};
+
+const TimeCalculator = () => {
+ const [mode, setMode] = useState("add");
+ const [rows, setRows] = useState(DEFAULT_HMS_ROWS);
+ const [resultUnit, setResultUnit] = useState("h");
+ const [multiplier, setMultiplier] = useState(2);
+ const [divisor, setDivisor] = useState(2);
+ const [betweenStart, setBetweenStart] = useState("");
+ const [betweenEnd, setBetweenEnd] = useState("");
+
+ const computed = useMemo(
+ () => calc(mode, rows, multiplier, divisor, betweenStart, betweenEnd),
+ [mode, rows, multiplier, divisor, betweenStart, betweenEnd]
+ );
+
+ const resultMs = computed.ms;
+ const error = computed.error;
+
+ const resultInUnit = useMemo(() => {
+ const denom = UNIT_TO_MS[resultUnit];
+ if (!denom) return 0;
+ return resultMs / denom;
+ }, [resultMs, resultUnit]);
+
+ const pretty = useMemo(() => formatPretty(resultMs), [resultMs]);
+ const parts = useMemo(() => breakdown(resultMs), [resultMs]);
+
+ const addRow = () => setRows((prev) => [...prev, { h: 0, m: 0, s: 0 }]);
+ const removeRow = (idx: number) => setRows((prev) => prev.filter((_, i) => i !== idx));
+ const updateRow = (idx: number, patch: Partial) =>
+ setRows((prev) => prev.map((r, i) => (i === idx ? { ...r, ...patch } : r)));
+
+ const clearAll = () => {
+ setRows(DEFAULT_HMS_ROWS);
+ setResultUnit("h");
+ setMultiplier(2);
+ setDivisor(2);
+ setBetweenStart("");
+ setBetweenEnd("");
+ setMode("add");
+ };
+
+ const copy = async (text: string) => {
+ try {
+ await navigator.clipboard.writeText(text);
+ } catch {
+ // ignore
+ }
+ };
+
+ const modeTitle =
+ mode === "add"
+ ? "Add time"
+ : mode === "subtract"
+ ? "Subtract time"
+ : mode === "multiply"
+ ? "Multiply time"
+ : mode === "divide"
+ ? "Divide time"
+ : "Time between dates";
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
Calculator
+
{modeTitle}
+
+
+ Reset
+
+
+
+
+
+
+
+
+ {mode === "between" ? (
+
+ ) : (
+
+
Enter values (up to 20 rows)
+
3 ? "bb-thin-scroll max-h-[420px] overflow-auto pr-1" : ""
+ }`}
+ style={rows.length > 3 ? { scrollbarWidth: "thin" } : undefined}
+ >
+ {rows.slice(0, 20).map((r, idx) => (
+
+
+
+ {idx === 0 ? "Time 1" : idx === 1 ? "Time 2" : `Time ${idx + 1}`}
+
+
removeRow(idx)}
+ disabled={rows.length <= 1}
+ className="px-3 py-1.5 rounded-lg border border-white/10 bg-white/10 hover:bg-white/20 text-white text-sm disabled:opacity-60 disabled:cursor-not-allowed font-semibold"
+ >
+ Remove
+
+
+
+
+
+
+
hrs
+
updateRow(idx, { h: Number(e.target.value) || 0 })}
+ className="w-full bg-transparent outline-none text-white text-sm"
+ />
+
+
+
min
+
updateRow(idx, { m: Number(e.target.value) || 0 })}
+ className="w-full bg-transparent outline-none text-white text-sm"
+ />
+
+
+
sec
+
updateRow(idx, { s: Number(e.target.value) || 0 })}
+ className="w-full bg-transparent outline-none text-white text-sm"
+ />
+
+
+
+
+ ))}
+
+
+
+
= 20}
+ className="px-4 py-2 rounded-xl border border-white/10 bg-white/10 hover:bg-white/20 text-white disabled:opacity-60 disabled:cursor-not-allowed font-semibold text-sm"
+ >
+ + Add Row
+
+
+ {mode === "multiply" && (
+
+ ×
+ setMultiplier(Number(e.target.value) || 0)}
+ className="w-28 bg-black border border-[#222222] rounded-lg px-3 py-2 text-white focus:outline-none focus:border-primary"
+ />
+
+ )}
+
+ {mode === "divide" && (
+
+ ÷
+ setDivisor(Number(e.target.value) || 0)}
+ className="w-28 bg-black border border-[#222222] rounded-lg px-3 py-2 text-white focus:outline-none focus:border-primary"
+ />
+
+ )}
+
+
+
+ Tip: Use multiple rows for add/subtract. Multiply/divide applies to the total.
+
+
+ )}
+
+ {error &&
{error}
}
+
+
+
+
+
+
+
Result
+
View as formatted time and totals
+
+
+
+
+
+
+
+
In units
+
+
+
+ {Number.isFinite(resultInUnit) ? resultInUnit.toFixed(6).replace(/\.?0+$/, "") : "—"}
+
+
+
+
+
Breakdown
+
+ {parts.sign < 0 ? "-" : ""}
+ {parts.days}d {pad2(parts.hours)}h {pad2(parts.minutes)}m {pad2(parts.seconds)}s
+
+
{parts.milliseconds} ms
+
+
+
+
+ copy(pretty)}
+ className={`${DevelopmentToolsStyles.converterButton} text-black font-bold !py-3 !px-4 rounded-xl w-full text-sm`}
+ >
+ Copy pretty
+
+ copy(String(resultMs))}
+ className={`${DevelopmentToolsStyles.converterButton} text-black font-bold !py-3 !px-4 rounded-xl w-full text-sm`}
+ >
+ Copy ms
+
+ copy(String(Math.floor(resultMs / 1000)))}
+ className={`${DevelopmentToolsStyles.converterButton} text-black font-bold !py-3 !px-4 rounded-xl w-full text-sm`}
+ >
+ Copy seconds
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default TimeCalculator;
+
diff --git a/app/developmentToolsStyles.module.scss b/app/developmentToolsStyles.module.scss
index cb04ee0..eefe24c 100644
--- a/app/developmentToolsStyles.module.scss
+++ b/app/developmentToolsStyles.module.scss
@@ -1,4 +1,5 @@
@import "./styles/variables.scss";
+
// serach box css
.searchInput {
display: flex;
@@ -8,8 +9,6 @@
input {
background: #ffffff1a;
- border: 1px solid #ffffff66;
- color: #ffffff;
border-radius: 50px;
padding: 2px 24px;
height: 40px;
@@ -22,6 +21,7 @@
&:focus {
opacity: 1;
+
&::placeholder {
opacity: 0%;
}
@@ -32,6 +32,7 @@
font-size: 16px;
transition: all 0.3s linear;
}
+
@media (max-width: 600px) {
width: 370px;
opacity: 1;
@@ -39,163 +40,13 @@
padding: 2px 20px;
padding-right: 95px;
}
+
@media (min-width: 768px) {
height: 50px;
}
}
}
-:global([data-theme="light"]) .pageContainer {
- color: #111827;
-}
-
-:global([data-theme="light"]) .contentWrapper {
- color: #111827;
-}
-
-:global([data-theme="light"]) .searchInput {
- input {
- background: #ffffff;
- border: 1px solid #e5e7eb;
- color: #111827;
- opacity: 1;
-
- &::placeholder {
- color: #6b7280;
- }
- }
-}
-
-:global([data-theme="light"]) .promoPanel {
- background: #f9fafb;
- border: 1px solid #e5e7eb;
- color: #111827;
-}
-
-:global([data-theme="light"]) .filterSidebar {
- background: #f9fafb;
- border: 1px solid #e5e7eb;
-}
-
-:global([data-theme="light"]) .favoriteButton {
- background: #ffffff;
- border-color: #e5e7eb;
- color: #111827;
-
- &:hover {
- background: #f3f4f6;
- border-color: #d1d5db;
- }
-
- &[data-active="true"] {
- background: #e6f9f2;
- border-color: #10b981;
- color: #065f46;
- }
-}
-
-:global([data-theme="light"]) .favoriteCount {
- color: #4b5563;
-}
-
-:global([data-theme="light"]) .favoriteButton[data-active="true"] .favoriteCount {
- color: #065f46;
-}
-
-:global([data-theme="light"]) .filterHeading {
- color: #111827;
-}
-
-:global([data-theme="light"]) .filterSubLabel {
- color: #4b5563;
-}
-
-:global([data-theme="light"]) .filterCategoryButton {
- background: #ffffff;
- border-color: #e5e7eb;
- color: #111827;
-
- &:hover {
- background: #f6f7f8;
- border-color: #d1d5db;
- }
-
- &[data-active="true"] {
- background: #e6f9f2;
- border-color: #10b981;
- color: #065f46;
- }
-}
-
-:global([data-theme="light"]) .filterBasisButton {
- background: #ffffff;
- border-color: #e5e7eb;
- color: #111827;
-
- &:hover {
- background: #f6f7f8;
- border-color: #d1d5db;
- }
-
- &[data-active="true"] {
- background: #e6f9f2;
- border-color: #10b981;
- color: #065f46;
- }
-}
-
-:global([data-theme="light"]) .showingCount {
- color: #4b5563;
-}
-
-:global([data-theme="light"]) .activeFilterPill {
- background: #f3f4f6;
- border-color: #e5e7eb;
- color: #111827;
-
- &:hover {
- background: #e5e7eb;
- }
-}
-
-:global([data-theme="light"]) .sidePanel {
- background: #f9fafb;
- border: 1px solid #e5e7eb;
- border-radius: 0.75rem;
- color: #111827;
- padding: 1rem;
-}
-
-:global([data-theme="light"]) .sidePanelItem {
- background: #ffffff;
- border-color: #e5e7eb;
- color: #111827;
-
- &:hover {
- background: #f3f4f6;
- border-color: #10b981;
- }
-}
-
-:global([data-theme="light"]) .toolCard {
- background: #ffffff;
- border: 1px solid #e5e7eb;
-}
-
-:global([data-theme="light"]) .toolCardDescription {
- color: #4b5563;
-}
-
-:global([data-theme="light"]) .toolCardMeta {
- color: #6b7280;
-}
-
-:global([data-theme="light"]) .contentCardHoverEffect {
- &:hover {
- box-shadow: 2px 2px 4px rgba(16, 185, 129, 0.18);
- }
-}
-
// tab background color
.tabBackgroundColor {
background: linear-gradient(91.15deg, #11e498 11.3%, #05bae2 101.69%);
@@ -213,13 +64,16 @@
// content card hover effect
.contentCardHoverEffect {
border-left: 2px solid #11e498;
- div > p > svg {
+
+ div>p>svg {
color: #11e498;
}
+
&:hover {
- div > p > svg {
+ div>p>svg {
color: black;
}
+
background: linear-gradient(92.9deg, #00d1ff 23.92%, #16fca9 100.19%);
transform: scale(0.4);
-webkit-transform: scale(1.1);
@@ -237,23 +91,22 @@
.converterButton {
background: $primary;
}
+
.clearButton {
background: rgb(255, 79, 108);
}
+
.copyButton {
background: #00d0ff9a;
}
-.addToChromeButton {
- background: #000000;
- color: #ffffff;
-}
-
/* Webkit custom scrollbar styles */
.scrollbar {
overflow: auto;
- scrollbar-width: thin; /* Firefox */
- scrollbar-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.05); /* Firefox */
+ scrollbar-width: thin;
+ /* Firefox */
+ scrollbar-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.05);
+ /* Firefox */
}
/* Scrollbar track (background of the scrollbar) */
@@ -285,8 +138,10 @@
/* Modern scrollbar for code blocks */
.modernScrollbar {
overflow: auto;
- scrollbar-width: thin; /* Firefox */
- scrollbar-color: rgba(17, 228, 152, 0.4) rgba(255, 255, 255, 0.05); /* Firefox - using primary color */
+ scrollbar-width: thin;
+ /* Firefox */
+ scrollbar-color: rgba(17, 228, 152, 0.4) rgba(255, 255, 255, 0.05);
+ /* Firefox - using primary color */
}
.modernScrollbar::-webkit-scrollbar {
@@ -309,4 +164,4 @@
.modernScrollbar::-webkit-scrollbar-track {
background-color: rgba(255, 255, 255, 0.05);
border-radius: 10px;
-}
+}
\ No newline at end of file
diff --git a/app/libs/constants.tsx b/app/libs/constants.tsx
index 5e558a0..2e38a8f 100644
--- a/app/libs/constants.tsx
+++ b/app/libs/constants.tsx
@@ -144,6 +144,7 @@ import RgbToCmykConverter from '../components/developmentToolsComponent/rgbToCmy
import RgbToHexConverter from '../components/developmentToolsComponent/rgbToHexConverter';
import Rot13EncoderDecoderComponent from '../components/developmentToolsComponent/rot13EncoderDecoderComponent';
import RotateImageTool from '../components/developmentToolsComponent/rotateImageTool';
+import ImageResizer from '../components/developmentToolsComponent/imageResizer';
import RotationCalculatorComponent from '../components/developmentToolsComponent/rotationCalculatorComponent';
import ScssToCssConverter from '../components/developmentToolsComponent/scssToCssConverter';
import ShuffleLetters from '../components/developmentToolsComponent/shuffleLetters';
@@ -190,6 +191,7 @@ import XorCalculator from '../components/developmentToolsComponent/xorCalculator
import CurlToCodeConverter from '../components/developmentToolsComponent/curlToCodeConverter';
import YAMLFormatterAndBeautifier from '../components/developmentToolsComponent/yamlFormatterAndBeautifier';
import EpochConverter from '../components/developmentToolsComponent/epochConverter';
+import TimeCalculator from '../components/developmentToolsComponent/timeCalculator';
export const WEB_URL = 'https://www.betterbugs.io';
@@ -1624,6 +1626,12 @@ export const developmentToolsCategoryContent: any = {
title: 'Unix Timestamp Converter',
description: 'Convert Unix timestamps to readable dates and vice versa.',
},
+ {
+ url: '/time-calculator',
+ title: 'Time Calculator',
+ description:
+ 'Add, subtract, multiply, divide time, or calculate the time between dates.',
+ },
],
Category179: [
{
@@ -1633,6 +1641,19 @@ export const developmentToolsCategoryContent: any = {
'Decompose complex URLs into legible components and edit query parameters in a visual table.',
},
],
+ Category180: [
+ {
+ url: '/url-encode',
+ title: 'URL Encode',
+ description: 'Encode URLs.',
+ },
+ {
+ url: '/image-resizer',
+ title: 'Image Resizer',
+ description:
+ 'Resize images locally in your browser. Keep aspect ratio, choose format, and download.',
+ },
+ ],
};
export const PATHS = {
@@ -1817,6 +1838,8 @@ export const PATHS = {
MORSE_CODE_TRANSLATOR: '/morse-code-translator',
CURL_TO_CODE_CONVERTER: '/curl-to-code-converter',
UNIX_TIMESTAMP_CONVERTER: '/unix-timestamp-converter',
+ IMAGE_RESIZER: '/image-resizer',
+ TIME_CALCULATOR: '/time-calculator',
};
export const developmentToolsRoutes = [
@@ -2075,6 +2098,10 @@ export const developmentToolsRoutes = [
path: PATHS.ROTATE_IMAGE_TOOL,
component: ,
},
+ {
+ path: PATHS.IMAGE_RESIZER,
+ component: ,
+ },
{
path: PATHS.CSV_TO_EXCEL_FILE_CONVERTOR,
component: ,
@@ -2540,6 +2567,7 @@ export const developmentToolsRoutes = [
path: PATHS.UNIX_TIMESTAMP_CONVERTER,
component: ,
},
+ { path: PATHS.TIME_CALCULATOR, component: },
];
// lorem ipsum text
diff --git a/app/libs/developmentToolsConstant.tsx b/app/libs/developmentToolsConstant.tsx
index 48a7d67..d80d449 100644
--- a/app/libs/developmentToolsConstant.tsx
+++ b/app/libs/developmentToolsConstant.tsx
@@ -11683,6 +11683,192 @@ console.log(encoded); // "SGVsbG8gV29ybGQh"`,
og_image: '/images/og-images/Cover.png',
},
},
+ [`image-resizer`]: {
+ hero_section: {
+ title: 'Image Resizer',
+ description:
+ 'Resize images locally in your browser. Keep aspect ratio, choose output format (PNG/JPG/WebP), and download the resized file.',
+ },
+ development_tools_list: [
+ { tool: 'Rotate Image Tool', url: PATHS.ROTATE_IMAGE_TOOL },
+ { tool: 'Placeholder Image Generator', url: PATHS.PLACEHOLDER_IMAGE_GENERATOR },
+ { tool: 'Color Picker Tool', url: PATHS.COLOR_PICKER_TOOL },
+ { tool: 'SVG to React/CSS Utility', url: PATHS.SVG_CONVERTER },
+ { tool: 'CSS Minify', url: PATHS.CSS_MINIFY },
+ { tool: 'URL Encode', url: PATHS.URL_ENCODE },
+ ],
+ development_tools_about_details: {
+ about_title: 'What is the Image Resizer tool?',
+ about_description: [
+ {
+ description:
+ 'The Image Resizer helps you change an image’s pixel dimensions (width and height) without uploading it to a server. Everything runs locally in your browser.',
+ },
+ {
+ description:
+ 'Use it to prepare assets for websites, emails, social previews, or product listings, and to quickly generate smaller image variants for performance.',
+ },
+ ],
+ },
+ development_tools_steps_guide: {
+ guide_title: 'How to use the Image Resizer',
+ guide_description: 'Resize an image in a few simple steps:',
+ steps: [
+ {
+ step_key: 'Step 1:',
+ step_title: 'Upload an image',
+ step_description:
+ 'Drag and drop an image file (or choose a file) to load it into the resizer.',
+ },
+ {
+ step_key: 'Step 2:',
+ step_title: 'Set the target size',
+ step_description:
+ 'Enter the width and height in pixels. Enable “Keep aspect ratio” to automatically calculate the other dimension.',
+ },
+ {
+ step_key: 'Step 3:',
+ step_title: 'Pick output format and quality',
+ step_description:
+ 'Choose PNG, JPG, or WebP. For JPG/WebP, adjust quality to balance file size and clarity.',
+ },
+ {
+ step_key: 'Step 4:',
+ step_title: 'Download the resized image',
+ step_description:
+ 'Preview the result and download the resized image with the selected settings.',
+ },
+ ],
+ },
+ development_tools_how_use: {
+ how_use_title: 'How It’s Used',
+ how_use_description: 'Common use cases for resizing images:',
+ point: [
+ {
+ title: 'Preparing web assets',
+ description:
+ 'Resize hero images, thumbnails, and blog illustrations to the exact dimensions your layout needs.',
+ },
+ {
+ title: 'Performance optimization',
+ description:
+ 'Create smaller variants to reduce page weight and improve Core Web Vitals (especially LCP).',
+ },
+ {
+ title: 'Consistent content sizing',
+ description:
+ 'Standardize image sizes for product grids, cards, and social media previews.',
+ },
+ {
+ title: 'Fast QA & debugging',
+ description:
+ 'Quickly generate test images at specific dimensions when validating responsive UI behavior.',
+ },
+ ],
+ },
+ meta_data: {
+ meta_title: 'Image Resizer – Resize Images Online (PNG/JPG/WebP)',
+ meta_description:
+ 'Resize images locally in your browser. Keep aspect ratio, choose PNG/JPG/WebP output, adjust quality, and download the resized image instantly.',
+ og_title: 'Image Resizer – Online Image Resize Tool',
+ og_description:
+ 'Resize images to exact pixel dimensions with optional aspect ratio lock. Export as PNG, JPG, or WebP and download immediately.',
+ og_image: '/images/og-images/Cover.png',
+ },
+ },
+ [`time-calculator`]: {
+ hero_section: {
+ title: 'Time Calculator',
+ description:
+ 'Add, subtract, multiply, divide time, or calculate the time between dates. Useful for planning tasks, estimating durations, and working with timestamps.',
+ },
+ development_tools_list: [
+ { tool: 'Unix Timestamp Converter', url: PATHS.UNIX_TIMESTAMP_CONVERTER },
+ { tool: 'Random Date Generator', url: PATHS.RANDOM_DATE_GENERATOR },
+ { tool: 'Random Time Generator', url: PATHS.RANDOM_CLOCK_TIME_GENERATOR },
+ { tool: 'URL Parser & Query String Editor', url: PATHS.URL_PARSER },
+ { tool: 'JSON Prettifier', url: PATHS.JSON_PRETTIFIER },
+ { tool: 'Code Compare Tool', url: PATHS.CODE_COMPARE_TOOL },
+ ],
+ development_tools_about_details: {
+ about_title: 'What is the Time Calculator?',
+ about_description: [
+ {
+ description:
+ 'The Time Calculator helps you perform common operations on time values—adding, subtracting, multiplying, dividing, and finding the duration between dates.',
+ },
+ {
+ description:
+ 'Use it for planning tasks, estimating project durations, tracking SLAs, or quickly converting totals into a readable time breakdown.',
+ },
+ ],
+ },
+ development_tools_steps_guide: {
+ guide_title: 'How to use the Time Calculator',
+ guide_description: 'Calculate time in a few steps:',
+ steps: [
+ {
+ step_key: 'Step 1:',
+ step_title: 'Choose an operation',
+ step_description:
+ 'Select whether you want to add, subtract, multiply, divide time, or find the time between dates.',
+ },
+ {
+ step_key: 'Step 2:',
+ step_title: 'Enter time values or dates',
+ step_description:
+ 'Add one or more rows of time values (hours, minutes, etc.), or choose start/end dates for a duration calculation.',
+ },
+ {
+ step_key: 'Step 3:',
+ step_title: 'Adjust multipliers/units (optional)',
+ step_description:
+ 'For multiply/divide, set the multiplier or divisor. Choose a result unit to see totals in seconds, hours, days, and more.',
+ },
+ {
+ step_key: 'Step 4:',
+ step_title: 'Copy the output',
+ step_description:
+ 'Copy a pretty formatted result, milliseconds, or seconds for use in docs, tickets, spreadsheets, or code.',
+ },
+ ],
+ },
+ development_tools_how_use: {
+ how_use_title: 'How It’s Used',
+ how_use_description: 'Common scenarios:',
+ point: [
+ {
+ title: 'Planning & estimation',
+ description:
+ 'Add up multiple task durations to estimate total time required.',
+ },
+ {
+ title: 'SLA / time windows',
+ description:
+ 'Compute allowed windows by subtracting or dividing time budgets.',
+ },
+ {
+ title: 'Between two dates',
+ description:
+ 'Find the exact duration between a start and end timestamp.',
+ },
+ {
+ title: 'Engineering & QA',
+ description:
+ 'Convert totals into readable breakdowns when debugging timers and intervals.',
+ },
+ ],
+ },
+ meta_data: {
+ meta_title: 'Time Calculator – Add, Subtract, Multiply & Divide Time',
+ meta_description:
+ 'A free time calculator to add, subtract, multiply, divide time, and calculate the time between dates. Get pretty results and copy seconds/milliseconds.',
+ og_title: 'Time Calculator – Online Tool',
+ og_description:
+ 'Calculate time instantly: add/subtract durations, multiply/divide time, or find the time between dates. Copy pretty output, seconds, or ms.',
+ og_image: '/images/og-images/Cover.png',
+ },
+ },
[`text-to-html-entities-convertor`]: {
hero_section: {
title: 'Text to HTML Entities Converter',
diff --git a/app/page.tsx b/app/page.tsx
index 2413337..09e17c6 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -304,7 +304,7 @@ const Page = () => {
{/* Sidebar */}