This commit is contained in:
star7th
2025-04-20 07:27:18 +08:00
parent 8decc5bf1d
commit d3d96df0f5
10 changed files with 2266 additions and 28 deletions
+1246 -25
View File
@@ -17,6 +17,7 @@
"@uiw/react-json-view": "^2.0.0-alpha.30",
"compressorjs": "^1.2.1",
"crypto-js": "^4.2.0",
"fabric": "^6.6.4",
"iconv-lite": "^0.6.3",
"marked": "^15.0.7",
"nanoid": "^5.1.5",
@@ -973,6 +974,27 @@
"@lezer/common": "^1.0.0"
}
},
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.11",
"resolved": "https://registry.npmmirror.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
"integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
"license": "BSD-3-Clause",
"optional": true,
"dependencies": {
"detect-libc": "^2.0.0",
"https-proxy-agent": "^5.0.0",
"make-dir": "^3.1.0",
"node-fetch": "^2.6.7",
"nopt": "^5.0.0",
"npmlog": "^5.0.1",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"tar": "^6.1.11"
},
"bin": {
"node-pre-gyp": "bin/node-pre-gyp"
}
},
"node_modules/@marijn/find-cluster-break": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
@@ -1256,6 +1278,16 @@
"tslib": "^2.8.0"
}
},
"node_modules/@tootallnate/once": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/@tootallnate/once/-/once-2.0.0.tgz",
"integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 10"
}
},
"node_modules/@tybys/wasm-util": {
"version": "0.9.0",
"resolved": "https://registry.npmmirror.com/@tybys/wasm-util/-/wasm-util-0.9.0.tgz",
@@ -1744,6 +1776,21 @@
"win32"
]
},
"node_modules/abab": {
"version": "2.0.6",
"resolved": "https://registry.npmmirror.com/abab/-/abab-2.0.6.tgz",
"integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
"deprecated": "Use your platform's native atob() and btoa() methods instead",
"license": "BSD-3-Clause",
"optional": true
},
"node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"license": "ISC",
"optional": true
},
"node_modules/acorn": {
"version": "8.14.1",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.14.1.tgz",
@@ -1756,6 +1803,17 @@
"node": ">=0.4.0"
}
},
"node_modules/acorn-globals": {
"version": "7.0.1",
"resolved": "https://registry.npmmirror.com/acorn-globals/-/acorn-globals-7.0.1.tgz",
"integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==",
"license": "MIT",
"optional": true,
"dependencies": {
"acorn": "^8.1.0",
"acorn-walk": "^8.0.2"
}
},
"node_modules/acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
@@ -1766,6 +1824,32 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/acorn-walk": {
"version": "8.3.4",
"resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.3.4.tgz",
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
"license": "MIT",
"optional": true,
"dependencies": {
"acorn": "^8.11.0"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
@@ -1833,6 +1917,28 @@
"node": ">= 8"
}
},
"node_modules/aproba": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/aproba/-/aproba-2.0.0.tgz",
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
"license": "ISC",
"optional": true
},
"node_modules/are-we-there-yet": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"dependencies": {
"delegates": "^1.0.0",
"readable-stream": "^3.6.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/arg": {
"version": "5.0.2",
"resolved": "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz",
@@ -2031,6 +2137,13 @@
"node": ">= 0.4"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT",
"optional": true
},
"node_modules/autoprefixer": {
"version": "10.4.21",
"resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.21.tgz",
@@ -2108,7 +2221,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"devOptional": true,
"license": "MIT"
},
"node_modules/binary-extensions": {
@@ -2134,7 +2247,7 @@
"version": "1.1.11",
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -2221,7 +2334,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -2288,6 +2401,22 @@
],
"license": "CC-BY-4.0"
},
"node_modules/canvas": {
"version": "2.11.2",
"resolved": "https://registry.npmmirror.com/canvas/-/canvas-2.11.2.tgz",
"integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.0",
"nan": "^2.17.0",
"simple-get": "^3.0.3"
},
"engines": {
"node": ">=6"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
@@ -2343,6 +2472,16 @@
"node": ">= 6"
}
},
"node_modules/chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"license": "ISC",
"optional": true,
"engines": {
"node": ">=10"
}
},
"node_modules/client-only": {
"version": "0.0.1",
"resolved": "https://registry.npmmirror.com/client-only/-/client-only-0.0.1.tgz",
@@ -2414,6 +2553,29 @@
"simple-swizzle": "^0.2.2"
}
},
"node_modules/color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmmirror.com/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"license": "ISC",
"optional": true,
"bin": {
"color-support": "bin.js"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"optional": true,
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz",
@@ -2438,9 +2600,16 @@
"version": "0.0.1",
"resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true,
"devOptional": true,
"license": "MIT"
},
"node_modules/console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
"license": "ISC",
"optional": true
},
"node_modules/crelt": {
"version": "1.0.6",
"resolved": "https://registry.npmmirror.com/crelt/-/crelt-1.0.6.tgz",
@@ -2481,6 +2650,33 @@
"node": ">=4"
}
},
"node_modules/cssom": {
"version": "0.5.0",
"resolved": "https://registry.npmmirror.com/cssom/-/cssom-0.5.0.tgz",
"integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==",
"license": "MIT",
"optional": true
},
"node_modules/cssstyle": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/cssstyle/-/cssstyle-2.3.0.tgz",
"integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
"license": "MIT",
"optional": true,
"dependencies": {
"cssom": "~0.3.6"
},
"engines": {
"node": ">=8"
}
},
"node_modules/cssstyle/node_modules/cssom": {
"version": "0.3.8",
"resolved": "https://registry.npmmirror.com/cssom/-/cssom-0.3.8.tgz",
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
"license": "MIT",
"optional": true
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
@@ -2495,6 +2691,21 @@
"dev": true,
"license": "BSD-2-Clause"
},
"node_modules/data-urls": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/data-urls/-/data-urls-3.0.2.tgz",
"integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"abab": "^2.0.6",
"whatwg-mimetype": "^3.0.0",
"whatwg-url": "^11.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/data-view-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
@@ -2553,7 +2764,7 @@
"version": "4.4.0",
"resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -2567,6 +2778,26 @@
}
}
},
"node_modules/decimal.js": {
"version": "10.5.0",
"resolved": "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.5.0.tgz",
"integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
"license": "MIT",
"optional": true
},
"node_modules/decompress-response": {
"version": "4.2.1",
"resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-4.2.1.tgz",
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
"license": "MIT",
"optional": true,
"dependencies": {
"mimic-response": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz",
@@ -2610,6 +2841,23 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
"license": "MIT",
"optional": true
},
"node_modules/detect-libc": {
"version": "2.0.3",
"resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.3.tgz",
@@ -2656,11 +2904,25 @@
"node": ">=0.10.0"
}
},
"node_modules/domexception": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/domexception/-/domexception-4.0.0.tgz",
"integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
"deprecated": "Use your platform's native DOMException instead",
"license": "MIT",
"optional": true,
"dependencies": {
"webidl-conversions": "^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
@@ -2692,6 +2954,19 @@
"dev": true,
"license": "MIT"
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"optional": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/es-abstract": {
"version": "1.23.9",
"resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.23.9.tgz",
@@ -2762,7 +3037,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -2772,7 +3047,7 @@
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -2810,7 +3085,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
@@ -2823,7 +3098,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -2889,6 +3164,28 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/escodegen": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/escodegen/-/escodegen-2.1.0.tgz",
"integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
"license": "BSD-2-Clause",
"optional": true,
"dependencies": {
"esprima": "^4.0.1",
"estraverse": "^5.2.0",
"esutils": "^2.0.2"
},
"bin": {
"escodegen": "bin/escodegen.js",
"esgenerate": "bin/esgenerate.js"
},
"engines": {
"node": ">=6.0"
},
"optionalDependencies": {
"source-map": "~0.6.1"
}
},
"node_modules/eslint": {
"version": "9.22.0",
"resolved": "https://registry.npmmirror.com/eslint/-/eslint-9.22.0.tgz",
@@ -3275,6 +3572,20 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"license": "BSD-2-Clause",
"optional": true,
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/esquery": {
"version": "1.6.0",
"resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.6.0.tgz",
@@ -3314,7 +3625,7 @@
"version": "5.3.0",
"resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
"devOptional": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
@@ -3324,12 +3635,25 @@
"version": "2.0.3",
"resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true,
"devOptional": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/fabric": {
"version": "6.6.4",
"resolved": "https://registry.npmmirror.com/fabric/-/fabric-6.6.4.tgz",
"integrity": "sha512-GJ+9CsTo4oDGO6eEsSYaxgaZnndsiVr/pl8itfLkaBuxH4ek9+hxKfpjzrIaiSGzoZ8jVxUP8pFJaCronLxukA==",
"license": "MIT",
"engines": {
"node": ">=16.20.0"
},
"optionalDependencies": {
"canvas": "^2.11.2",
"jsdom": "^20.0.1"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -3503,6 +3827,22 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/form-data": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.2.tgz",
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
"license": "MIT",
"optional": true,
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fraction.js": {
"version": "4.3.7",
"resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz",
@@ -3517,6 +3857,39 @@
"url": "https://github.com/sponsors/rawify"
}
},
"node_modules/fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"license": "ISC",
"optional": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/fs-minipass/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"license": "ISC",
"optional": true
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
@@ -3536,7 +3909,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"devOptional": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -3573,11 +3946,85 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gauge": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/gauge/-/gauge-3.0.2.tgz",
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.2",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.1",
"object-assign": "^4.1.1",
"signal-exit": "^3.0.0",
"string-width": "^4.2.3",
"strip-ansi": "^6.0.1",
"wide-align": "^1.1.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/gauge/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=8"
}
},
"node_modules/gauge/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT",
"optional": true
},
"node_modules/gauge/node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"license": "ISC",
"optional": true
},
"node_modules/gauge/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"optional": true,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/gauge/node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"optional": true,
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
@@ -3602,7 +4049,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
@@ -3737,7 +4184,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -3809,7 +4256,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -3822,7 +4269,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
@@ -3834,11 +4281,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
"license": "ISC",
"optional": true
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"devOptional": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
@@ -3847,6 +4301,48 @@
"node": ">= 0.4"
}
},
"node_modules/html-encoding-sniffer": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
"integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
"license": "MIT",
"optional": true,
"dependencies": {
"whatwg-encoding": "^2.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/http-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
"integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
"license": "MIT",
"optional": true,
"dependencies": {
"@tootallnate/once": "2",
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/https-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"license": "MIT",
"optional": true,
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
@@ -3902,6 +4398,25 @@
"node": ">=0.8.19"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"license": "ISC",
"optional": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC",
"optional": true
},
"node_modules/internal-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.1.0.tgz",
@@ -4124,7 +4639,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -4202,6 +4717,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-potential-custom-element-name": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
"license": "MIT",
"optional": true
},
"node_modules/is-reference": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/is-reference/-/is-reference-3.0.3.tgz",
@@ -4432,6 +4954,52 @@
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/jsdom": {
"version": "20.0.3",
"resolved": "https://registry.npmmirror.com/jsdom/-/jsdom-20.0.3.tgz",
"integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"abab": "^2.0.6",
"acorn": "^8.8.1",
"acorn-globals": "^7.0.0",
"cssom": "^0.5.0",
"cssstyle": "^2.3.0",
"data-urls": "^3.0.2",
"decimal.js": "^10.4.2",
"domexception": "^4.0.0",
"escodegen": "^2.0.0",
"form-data": "^4.0.0",
"html-encoding-sniffer": "^3.0.0",
"http-proxy-agent": "^5.0.0",
"https-proxy-agent": "^5.0.1",
"is-potential-custom-element-name": "^1.0.1",
"nwsapi": "^2.2.2",
"parse5": "^7.1.1",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
"tough-cookie": "^4.1.2",
"w3c-xmlserializer": "^4.0.0",
"webidl-conversions": "^7.0.0",
"whatwg-encoding": "^2.0.0",
"whatwg-mimetype": "^3.0.0",
"whatwg-url": "^11.0.0",
"ws": "^8.11.0",
"xml-name-validator": "^4.0.0"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
"canvas": "^2.5.0"
},
"peerDependenciesMeta": {
"canvas": {
"optional": true
}
}
},
"node_modules/jsep": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/jsep/-/jsep-1.4.0.tgz",
@@ -4658,6 +5226,32 @@
"@jridgewell/sourcemap-codec": "^1.5.0"
}
},
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"license": "MIT",
"optional": true,
"dependencies": {
"semver": "^6.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/make-dir/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"license": "ISC",
"optional": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/marked": {
"version": "15.0.7",
"resolved": "https://registry.npmmirror.com/marked/-/marked-15.0.7.tgz",
@@ -4674,7 +5268,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -4710,11 +5304,47 @@
"node": ">=8.6"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"optional": true,
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mimic-response": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-2.1.0.tgz",
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"devOptional": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -4743,11 +5373,51 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmmirror.com/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"license": "MIT",
"optional": true,
"dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/minizlib/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"license": "MIT",
"optional": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"devOptional": true,
"license": "MIT"
},
"node_modules/mz": {
@@ -4762,6 +5432,13 @@
"thenify-all": "^1.0.0"
}
},
"node_modules/nan": {
"version": "2.22.2",
"resolved": "https://registry.npmmirror.com/nan/-/nan-2.22.2.tgz",
"integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==",
"license": "MIT",
"optional": true
},
"node_modules/nanoid": {
"version": "5.1.5",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-5.1.5.tgz",
@@ -4893,6 +5570,52 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"optional": true,
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/node-fetch/node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT",
"optional": true
},
"node_modules/node-fetch/node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"license": "BSD-2-Clause",
"optional": true
},
"node_modules/node-fetch/node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"optional": true,
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/node-releases": {
"version": "2.0.19",
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz",
@@ -4900,6 +5623,22 @@
"dev": true,
"license": "MIT"
},
"node_modules/nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"abbrev": "1"
},
"bin": {
"nopt": "bin/nopt.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -4920,6 +5659,27 @@
"node": ">=0.10.0"
}
},
"node_modules/npmlog": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/npmlog/-/npmlog-5.0.1.tgz",
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"dependencies": {
"are-we-there-yet": "^2.0.0",
"console-control-strings": "^1.1.0",
"gauge": "^3.0.0",
"set-blocking": "^2.0.0"
}
},
"node_modules/nwsapi": {
"version": "2.2.20",
"resolved": "https://registry.npmmirror.com/nwsapi/-/nwsapi-2.2.20.tgz",
"integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==",
"license": "MIT",
"optional": true
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
@@ -5052,6 +5812,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"license": "ISC",
"optional": true,
"dependencies": {
"wrappy": "1"
}
},
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz",
@@ -5140,6 +5910,19 @@
"node": ">=6"
}
},
"node_modules/parse5": {
"version": "7.2.1",
"resolved": "https://registry.npmmirror.com/parse5/-/parse5-7.2.1.tgz",
"integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"entities": "^4.5.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
@@ -5150,6 +5933,16 @@
"node": ">=8"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
@@ -5423,11 +6216,24 @@
"react-is": "^16.13.1"
}
},
"node_modules/psl": {
"version": "1.15.0",
"resolved": "https://registry.npmmirror.com/psl/-/psl-1.15.0.tgz",
"integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
"license": "MIT",
"optional": true,
"dependencies": {
"punycode": "^2.3.1"
},
"funding": {
"url": "https://github.com/sponsors/lupomontero"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -5439,6 +6245,13 @@
"integrity": "sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==",
"license": "MIT"
},
"node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
"license": "MIT",
"optional": true
},
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -5511,6 +6324,21 @@
"pify": "^2.3.0"
}
},
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"optional": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
@@ -5584,6 +6412,13 @@
"node": ">=0.10.0"
}
},
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"license": "MIT",
"optional": true
},
"node_modules/resolve": {
"version": "1.22.10",
"resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.10.tgz",
@@ -5636,6 +6471,45 @@
"node": ">=0.10.0"
}
},
"node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"deprecated": "Rimraf versions prior to v4 are no longer supported",
"license": "ISC",
"optional": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rimraf/node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"license": "ISC",
"optional": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rspack-resolver": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/rspack-resolver/-/rspack-resolver-1.2.2.tgz",
@@ -5703,6 +6577,27 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"optional": true
},
"node_modules/safe-push-apply": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
@@ -5744,6 +6639,19 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/saxes": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/saxes/-/saxes-6.0.0.tgz",
"integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
"license": "ISC",
"optional": true,
"dependencies": {
"xmlchars": "^2.2.0"
},
"engines": {
"node": ">=v12.22.7"
}
},
"node_modules/scheduler": {
"version": "0.25.0",
"resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.25.0.tgz",
@@ -5763,6 +6671,13 @@
"node": ">=10"
}
},
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"license": "ISC",
"optional": true
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
@@ -5964,6 +6879,39 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/simple-concat": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz",
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"optional": true
},
"node_modules/simple-get": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/simple-get/-/simple-get-3.1.1.tgz",
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
"license": "MIT",
"optional": true,
"dependencies": {
"decompress-response": "^4.2.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
},
"node_modules/simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
@@ -5974,6 +6922,16 @@
"is-arrayish": "^0.3.1"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"license": "BSD-3-Clause",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -5998,6 +6956,16 @@
"node": ">=10.0.0"
}
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"license": "MIT",
"optional": true,
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz",
@@ -6341,6 +7309,13 @@
"node": ">=18"
}
},
"node_modules/symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz",
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"license": "MIT",
"optional": true
},
"node_modules/tailwindcss": {
"version": "3.4.17",
"resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.17.tgz",
@@ -6419,6 +7394,34 @@
"jiti": "bin/jiti.js"
}
},
"node_modules/tar": {
"version": "6.2.1",
"resolved": "https://registry.npmmirror.com/tar/-/tar-6.2.1.tgz",
"integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
"license": "ISC",
"optional": true,
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^5.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/tar/node_modules/minipass": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/minipass/-/minipass-5.0.0.tgz",
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"license": "ISC",
"optional": true,
"engines": {
"node": ">=8"
}
},
"node_modules/thenify": {
"version": "3.3.1",
"resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz",
@@ -6500,6 +7503,35 @@
"node": ">=8.0"
}
},
"node_modules/tough-cookie": {
"version": "4.1.4",
"resolved": "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-4.1.4.tgz",
"integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
"license": "BSD-3-Clause",
"optional": true,
"dependencies": {
"psl": "^1.1.33",
"punycode": "^2.1.1",
"universalify": "^0.2.0",
"url-parse": "^1.5.3"
},
"engines": {
"node": ">=6"
}
},
"node_modules/tr46": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/tr46/-/tr46-3.0.0.tgz",
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
"license": "MIT",
"optional": true,
"dependencies": {
"punycode": "^2.1.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/ts-api-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-2.0.1.tgz",
@@ -6679,6 +7711,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/universalify": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.2.0.tgz",
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
@@ -6720,11 +7762,22 @@
"punycode": "^2.1.0"
}
},
"node_modules/url-parse": {
"version": "1.5.10",
"resolved": "https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true,
"devOptional": true,
"license": "MIT"
},
"node_modules/vanilla-jsoneditor": {
@@ -6798,6 +7851,66 @@
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
"license": "MIT"
},
"node_modules/w3c-xmlserializer": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
"integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
"license": "MIT",
"optional": true,
"dependencies": {
"xml-name-validator": "^4.0.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"license": "BSD-2-Clause",
"optional": true,
"engines": {
"node": ">=12"
}
},
"node_modules/whatwg-encoding": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
"integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
"license": "MIT",
"optional": true,
"dependencies": {
"iconv-lite": "0.6.3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/whatwg-mimetype": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
"integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12"
}
},
"node_modules/whatwg-url": {
"version": "11.0.0",
"resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-11.0.0.tgz",
"integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"tr46": "^3.0.0",
"webidl-conversions": "^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
@@ -6903,6 +8016,61 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/wide-align": {
"version": "1.1.5",
"resolved": "https://registry.npmmirror.com/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
"license": "ISC",
"optional": true,
"dependencies": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
"node_modules/wide-align/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=8"
}
},
"node_modules/wide-align/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT",
"optional": true
},
"node_modules/wide-align/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"optional": true,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/wide-align/node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"optional": true,
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/word-wrap": {
"version": "1.2.5",
"resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz",
@@ -7008,6 +8176,59 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC",
"optional": true
},
"node_modules/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.18.1.tgz",
"integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xml-name-validator": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
"integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
"license": "Apache-2.0",
"optional": true,
"engines": {
"node": ">=12"
}
},
"node_modules/xmlchars": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"license": "MIT",
"optional": true
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC",
"optional": true
},
"node_modules/yaml": {
"version": "2.7.0",
"resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.7.0.tgz",
+1
View File
@@ -18,6 +18,7 @@
"@uiw/react-json-view": "^2.0.0-alpha.30",
"compressorjs": "^1.2.1",
"crypto-js": "^4.2.0",
"fabric": "^6.6.4",
"iconv-lite": "^0.6.3",
"marked": "^15.0.7",
"nanoid": "^5.1.5",
+879
View File
@@ -0,0 +1,879 @@
'use client';
import React, { useState, useRef, useEffect, ChangeEvent } from 'react';
import { Canvas, Image as FabricImage, Text, Object as FabricObject, Shadow } from 'fabric';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faUpload, faDownload, faTrash,
faImage, faFont, faLayerGroup, faShield
} from '@fortawesome/free-solid-svg-icons';
import ToolHeader from '@/components/ToolHeader';
import { useLanguage } from '@/context/LanguageContext';
// 页面样式
const styles = {
container: "min-h-screen flex flex-col max-w-[1440px] mx-auto p-4 md:p-6",
card: "card p-6 mb-6",
inputLabel: "block text-secondary text-sm font-bold mb-2",
fileUploadBtn: "btn-primary flex items-center justify-center cursor-pointer",
fileName: "ml-3 text-secondary text-sm",
heading: "text-lg font-semibold mb-2 text-primary",
settingsContainer: "space-y-4",
rangeInput: "w-full accent-[rgb(var(--color-primary))]",
textInput: "search-input w-full",
infoPanel: "bg-block p-4 rounded-lg border border-purple-glow/15",
infoPanelRow: "flex justify-between mb-2",
infoLabel: "text-secondary",
infoValue: "font-medium text-primary",
successValue: "font-medium text-success",
actionBtn: "w-full",
actionBtnDisabled: "btn-secondary opacity-50 cursor-not-allowed w-full",
imageContainer: "bg-block rounded-lg p-4 min-h-64 flex items-center justify-center border border-purple-glow/15",
image: "max-w-full max-h-96 object-contain",
placeholder: "text-tertiary",
radioGroup: "flex flex-wrap gap-2 mb-4",
radioItem: "flex items-center",
radioLabel: "ml-2 text-secondary",
tabButton: "px-4 py-2 rounded-t-lg",
tabButtonActive: "bg-block border-b-2 border-primary text-primary",
tabButtonInactive: "text-secondary hover:text-primary"
};
// 位置选项
type WatermarkPosition =
'top-left' | 'top-center' | 'top-right' |
'middle-left' | 'middle-center' | 'middle-right' |
'bottom-left' | 'bottom-center' | 'bottom-right' | 'tile';
// 保护级别
type ProtectionLevel = 'standard' | 'enhanced' | 'professional';
// 水印类型
type WatermarkType = 'text' | 'image';
export default function ImageWatermark() {
const { t } = useLanguage();
const [originalImage, setOriginalImage] = useState<string | null>(null);
const [watermarkedImage, setWatermarkedImage] = useState<string | null>(null);
const [fileName, setFileName] = useState<string>('');
const [processing, setProcessing] = useState<boolean>(false);
// 水印设置
const [watermarkType, setWatermarkType] = useState<WatermarkType>('text');
const [watermarkText, setWatermarkText] = useState<string>('我是水印文本');
const [fontFamily, setFontFamily] = useState<string>('system-ui, -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, \'Helvetica Neue\', Arial, sans-serif');
const [fontSize, setFontSize] = useState<number>(24);
const [fontColor, setFontColor] = useState<string>('#ffffff');
const [fontOpacity, setFontOpacity] = useState<number>(60);
const [fontWeight, setFontWeight] = useState<string>('normal');
// 图片水印设置
const [watermarkImageSrc, setWatermarkImageSrc] = useState<string | null>(null);
const [imageOpacity, setImageOpacity] = useState<number>(50);
const [imageScale, setImageScale] = useState<number>(50);
// 位置设置
const [position, setPosition] = useState<WatermarkPosition>('bottom-right');
const [offsetX, setOffsetX] = useState<number>(10);
const [offsetY, setOffsetY] = useState<number>(10);
const [rotation, setRotation] = useState<number>(0);
// 高级设置
const [protectionLevel, setProtectionLevel] = useState<ProtectionLevel>('standard');
// DOM引用
const fileInputRef = useRef<HTMLInputElement>(null);
const watermarkImageInputRef = useRef<HTMLInputElement>(null);
const canvasRef = useRef<Canvas | null>(null);
const canvasContainerRef = useRef<HTMLDivElement>(null);
// 处理图片上传
const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) return;
setFileName(file.name);
setWatermarkedImage(null);
const reader = new FileReader();
reader.onload = (e) => {
setOriginalImage(e.target?.result as string);
};
reader.readAsDataURL(file);
};
// 处理水印图片上传
const handleWatermarkImageChange = (event: ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
setWatermarkImageSrc(e.target?.result as string);
};
reader.readAsDataURL(file);
};
// 根据位置计算水印坐标
const getPositionCoordinates = (
canvasWidth: number,
canvasHeight: number,
watermarkWidth: number,
watermarkHeight: number
): { x: number, y: number } => {
const padding = { x: offsetX, y: offsetY };
switch(position) {
case 'top-left':
return { x: padding.x, y: padding.y };
case 'top-center':
return { x: canvasWidth / 2 - watermarkWidth / 2, y: padding.y };
case 'top-right':
return { x: canvasWidth - watermarkWidth - padding.x, y: padding.y };
case 'middle-left':
return { x: padding.x, y: canvasHeight / 2 - watermarkHeight / 2 };
case 'middle-center':
return { x: canvasWidth / 2 - watermarkWidth / 2, y: canvasHeight / 2 - watermarkHeight / 2 };
case 'middle-right':
return { x: canvasWidth - watermarkWidth - padding.x, y: canvasHeight / 2 - watermarkHeight / 2 };
case 'bottom-left':
return { x: padding.x, y: canvasHeight - watermarkHeight - padding.y };
case 'bottom-center':
return { x: canvasWidth / 2 - watermarkWidth / 2, y: canvasHeight - watermarkHeight - padding.y };
case 'bottom-right':
return { x: canvasWidth - watermarkWidth - padding.x, y: canvasHeight - watermarkHeight - padding.y };
default:
return { x: padding.x, y: padding.y };
}
};
// 初始化Canvas
useEffect(() => {
if (!originalImage || !canvasContainerRef.current) return;
// 清理之前的Canvas
if (canvasRef.current) {
canvasRef.current.dispose();
}
const img = new window.Image();
img.src = originalImage;
img.onload = () => {
if (!canvasContainerRef.current) return;
// 创建新的Canvas实例
const canvas = new Canvas('watermark-canvas', {
width: img.width,
height: img.height
});
canvasRef.current = canvas;
// 添加原始图片到Canvas - 修复类型问题
FabricImage.fromURL(originalImage).then(imgObj => {
canvas.add(imgObj);
canvas.renderAll();
});
};
return () => {
if (canvasRef.current) {
canvasRef.current.dispose();
}
};
}, [originalImage]);
// 应用水印
const applyWatermark = () => {
if (!canvasRef.current || !originalImage) return;
setProcessing(true);
const canvas = canvasRef.current;
// 移除之前的水印
const objects = canvas.getObjects();
if (objects.length > 1) {
for (let i = 1; i < objects.length; i++) {
canvas.remove(objects[i]);
}
}
// 根据保护级别添加额外处理
const applyProtectionEffects = (watermarkObj: FabricObject) => {
if (protectionLevel === 'standard') {
// 标准级别不做额外处理
return watermarkObj;
} else if (protectionLevel === 'enhanced') {
// 增强级别: 增加阴影和轻微变形
watermarkObj.set({
shadow: new Shadow({
color: 'rgba(0,0,0,0.3)',
blur: 3,
offsetX: 2,
offsetY: 2
}),
skewX: Math.random() * 5 - 2.5,
});
return watermarkObj;
} else {
// 专业级别: 更多随机效果和扭曲
watermarkObj.set({
shadow: new Shadow({
color: 'rgba(0,0,0,0.4)',
blur: 5,
offsetX: 3,
offsetY: 3
}),
skewX: Math.random() * 8 - 4,
skewY: Math.random() * 3 - 1.5,
opacity: fontOpacity / 100 * (0.9 + Math.random() * 0.2)
});
return watermarkObj;
}
};
const addWatermark = () => {
if (!canvas) return;
if (position === 'tile') {
// 实现平铺水印
addTiledWatermark();
} else {
// 添加单个水印
addSingleWatermark();
}
// 完成渲染
setTimeout(() => {
const dataUrl = canvas.toDataURL({
format: 'png',
quality: 1,
multiplier: 1
});
setWatermarkedImage(dataUrl);
setProcessing(false);
}, 300);
};
const addSingleWatermark = () => {
const canvas = canvasRef.current;
if (!canvas) return;
if (watermarkType === 'text') {
// 添加文字水印
const text = new Text(watermarkText, {
fontFamily,
fontSize,
fill: fontColor,
opacity: fontOpacity / 100,
fontWeight,
angle: rotation,
});
const { x, y } = getPositionCoordinates(
canvas.getWidth(),
canvas.getHeight(),
text.width || 0,
text.height || 0
);
text.set({ left: x, top: y });
applyProtectionEffects(text);
canvas.add(text);
} else if (watermarkType === 'image' && watermarkImageSrc) {
// 添加图片水印 - 修复类型问题
FabricImage.fromURL(watermarkImageSrc).then(imgObj => {
const scale = imageScale / 100;
imgObj.scale(scale);
imgObj.set({
opacity: imageOpacity / 100,
angle: rotation
});
const { x, y } = getPositionCoordinates(
canvas.getWidth(),
canvas.getHeight(),
(imgObj.width || 0) * scale,
(imgObj.height || 0) * scale
);
imgObj.set({ left: x, top: y });
applyProtectionEffects(imgObj);
canvas.add(imgObj);
canvas.renderAll();
});
}
};
const addTiledWatermark = () => {
const canvas = canvasRef.current;
if (!canvas) return;
// 平铺水印实现...
if (watermarkType === 'text') {
// 文字水印平铺
// 根据文字长度和字体大小计算合理的平铺间距
const textObj = new Text(watermarkText, {
fontFamily,
fontSize,
fontWeight
});
// 计算实际文字宽度和高度
const textWidth = textObj.width || fontSize * watermarkText.length;
const textHeight = textObj.height || fontSize * 1.2;
// 设置合理的间距,基于文字大小和内容
const spacingX = Math.max(textWidth * 1.5, fontSize * 8);
const spacingY = Math.max(textHeight * 2.5, fontSize * 6);
// 创建平铺模式
const canvasWidth = canvas.getWidth();
const canvasHeight = canvas.getHeight();
// 添加随机性,使平铺更自然
for (let x = 0; x < canvasWidth; x += spacingX) {
for (let y = 0; y < canvasHeight; y += spacingY) {
// 添加轻微的随机偏移,使水印不完全对齐
const randomOffsetX = Math.random() * fontSize - fontSize/2;
const randomOffsetY = Math.random() * fontSize - fontSize/2;
const textClone = new Text(watermarkText, {
fontFamily,
fontSize,
fill: fontColor,
opacity: fontOpacity / 100,
fontWeight,
angle: rotation,
left: x + offsetX + randomOffsetX,
top: y + offsetY + randomOffsetY
});
applyProtectionEffects(textClone);
canvas.add(textClone);
}
}
} else if (watermarkType === 'image' && watermarkImageSrc) {
// 为避免嵌套过深,先获取一次图片信息
FabricImage.fromURL(watermarkImageSrc).then(imgObj => {
const scale = imageScale / 100;
// 增加图片之间的间距,防止重叠
const imgWidth = (imgObj.width || 0) * scale;
const imgHeight = (imgObj.height || 0) * scale;
// 设置间距为图片尺寸的两倍
const spacingX = imgWidth * 2.5;
const spacingY = imgHeight * 2.5;
const canvasWidth = canvas.getWidth();
const canvasHeight = canvas.getHeight();
let tilesAdded = 0;
const totalTiles = Math.ceil(canvasWidth / spacingX) * Math.ceil(canvasHeight / spacingY);
// 创建平铺模式,添加轻微随机性
for (let x = 0; x < canvasWidth; x += spacingX) {
for (let y = 0; y < canvasHeight; y += spacingY) {
// 为每个位置创建新的图片实例
const currentX = x;
const currentY = y;
// 添加轻微的随机偏移
const randomOffsetX = Math.random() * imgWidth * 0.4 - imgWidth * 0.2;
const randomOffsetY = Math.random() * imgHeight * 0.4 - imgHeight * 0.2;
FabricImage.fromURL(watermarkImageSrc).then(tileImgObj => {
tileImgObj.scale(scale);
tileImgObj.set({
left: currentX + offsetX + randomOffsetX,
top: currentY + offsetY + randomOffsetY,
opacity: imageOpacity / 100,
angle: rotation
});
applyProtectionEffects(tileImgObj);
canvas.add(tileImgObj);
tilesAdded++;
// 只在最后一个水印添加后再渲染
if (tilesAdded >= totalTiles) {
canvas.renderAll();
}
});
}
}
});
}
};
// 执行水印添加
addWatermark();
};
// 下载处理后的图片
const downloadImage = () => {
if (!watermarkedImage) return;
const link = document.createElement('a');
const ext = fileName.split('.').pop() || 'png';
const newFileName = fileName.replace(/\.[^/.]+$/, '') + '.watermarked.' + ext;
link.href = watermarkedImage;
link.download = newFileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
// 重置所有
const resetAll = () => {
setOriginalImage(null);
setWatermarkedImage(null);
setFileName('');
setWatermarkImageSrc(null);
if (fileInputRef.current) {
fileInputRef.current.value = '';
}
if (watermarkImageInputRef.current) {
watermarkImageInputRef.current.value = '';
}
};
// 渲染UI
return (
<div className={styles.container}>
{/* 工具头部 */}
<ToolHeader
icon={faImage}
toolCode="image_watermark"
title={t('tools.image_watermark.title')}
description={t('tools.image_watermark.description')}
/>
{/* 主要内容区 */}
<div className={styles.card}>
<div className="mb-6">
<label className={styles.inputLabel}>
{t('tools.image_watermark.select_image')}
</label>
<div className="flex items-center">
<label className={styles.fileUploadBtn}>
<FontAwesomeIcon icon={faUpload} className="mr-2 icon" />
{t('tools.image_watermark.choose_file')}
<input
type="file"
className="hidden"
accept="image/*"
onChange={handleFileChange}
ref={fileInputRef}
/>
</label>
{fileName && (
<span className={styles.fileName}>{fileName}</span>
)}
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* 左侧设置区域 */}
<div>
{originalImage && (
<>
<h3 className={styles.heading}>{t('tools.image_watermark.watermark_settings')}</h3>
{/* 水印类型选择 */}
<div className="mb-4">
<label className={styles.inputLabel}>
{t('tools.image_watermark.watermark_type')}
</label>
<div className={styles.radioGroup}>
<div className={styles.radioItem}>
<input
type="radio"
id="text-watermark"
name="watermark-type"
checked={watermarkType === 'text'}
onChange={() => setWatermarkType('text')}
/>
<label htmlFor="text-watermark" className={styles.radioLabel}>
<FontAwesomeIcon icon={faFont} className="mr-1" />
{t('tools.image_watermark.text_watermark')}
</label>
</div>
<div className={styles.radioItem}>
<input
type="radio"
id="image-watermark"
name="watermark-type"
checked={watermarkType === 'image'}
onChange={() => setWatermarkType('image')}
/>
<label htmlFor="image-watermark" className={styles.radioLabel}>
<FontAwesomeIcon icon={faImage} className="mr-1" />
{t('tools.image_watermark.image_watermark')}
</label>
</div>
</div>
</div>
{/* 文字水印设置 */}
{watermarkType === 'text' && (
<div className="mb-4 space-y-4">
<h4 className="text-secondary font-medium">
{t('tools.image_watermark.text_settings')}
</h4>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.watermark_text')}
</label>
<input
type="text"
className={styles.textInput}
value={watermarkText}
onChange={(e) => setWatermarkText(e.target.value)}
/>
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.font_family')}
</label>
<select
className={styles.textInput}
value={fontFamily}
onChange={(e) => setFontFamily(e.target.value)}
>
<option value="system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif"></option>
<option value="Arial, Helvetica, sans-serif">Arial</option>
<option value="'Segoe UI', Tahoma, Geneva, Verdana, sans-serif">Segoe UI</option>
<option value="'PingFang SC', 'Microsoft YaHei', 'Heiti SC', sans-serif"></option>
<option value="'SimSun', 'STSong', serif"></option>
<option value="'Times New Roman', Times, serif">Times New Roman</option>
<option value="Georgia, Cambria, 'Times New Roman', Times, serif">Georgia</option>
<option value="'Courier New', Courier, monospace">Courier New</option>
</select>
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.font_size')} ({fontSize}px)
</label>
<input
type="range"
min="8"
max="72"
value={fontSize}
onChange={(e) => setFontSize(parseInt(e.target.value))}
className={styles.rangeInput}
/>
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.font_color')}
</label>
<input
type="color"
className="w-full h-8 rounded cursor-pointer"
value={fontColor}
onChange={(e) => setFontColor(e.target.value)}
/>
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.font_opacity')} ({fontOpacity}%)
</label>
<input
type="range"
min="1"
max="100"
value={fontOpacity}
onChange={(e) => setFontOpacity(parseInt(e.target.value))}
className={styles.rangeInput}
/>
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.font_weight')}
</label>
<select
className={styles.textInput}
value={fontWeight}
onChange={(e) => setFontWeight(e.target.value)}
>
<option value="normal">Normal</option>
<option value="bold">Bold</option>
</select>
</div>
</div>
)}
{/* 图片水印设置 */}
{watermarkType === 'image' && (
<div className="mb-4 space-y-4">
<h4 className="text-secondary font-medium">
{t('tools.image_watermark.image_settings')}
</h4>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.select_watermark_image')}
</label>
<label className={styles.fileUploadBtn}>
<FontAwesomeIcon icon={faUpload} className="mr-2 icon" />
{t('tools.image_watermark.choose_file')}
<input
type="file"
className="hidden"
accept="image/*"
onChange={handleWatermarkImageChange}
ref={watermarkImageInputRef}
/>
</label>
{watermarkImageSrc && (
<div className="mt-2 max-w-[150px] max-h-[100px] overflow-hidden rounded border border-purple-glow/20">
<img src={watermarkImageSrc} alt="Watermark" className="max-w-full object-contain" />
</div>
)}
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.image_opacity')} ({imageOpacity}%)
</label>
<input
type="range"
min="1"
max="100"
value={imageOpacity}
onChange={(e) => setImageOpacity(parseInt(e.target.value))}
className={styles.rangeInput}
/>
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.image_scale')} ({imageScale}%)
</label>
<input
type="range"
min="1"
max="100"
value={imageScale}
onChange={(e) => setImageScale(parseInt(e.target.value))}
className={styles.rangeInput}
/>
</div>
</div>
)}
{/* 位置设置 */}
<div className="mb-4 space-y-4">
<h4 className="text-secondary font-medium">
{t('tools.image_watermark.position_settings')}
</h4>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.position')}
</label>
<div className="grid grid-cols-3 gap-2 mb-2">
{[
'top-left', 'top-center', 'top-right',
'middle-left', 'middle-center', 'middle-right',
'bottom-left', 'bottom-center', 'bottom-right'
].map((pos) => (
<button
key={pos}
type="button"
className={`p-2 rounded text-sm cursor-pointer transition-all duration-200 ${
position === pos
? 'bg-gradient-to-r from-[rgb(var(--color-primary))] to-[rgb(var(--color-primary-hover))] text-white shadow-md'
: 'bg-block border border-purple-glow/20 hover:border-primary/50 hover:bg-primary/10'
}`}
onClick={() => setPosition(pos as WatermarkPosition)}
>
{t(`tools.image_watermark.${pos.replace('-', '_')}`)}
</button>
))}
</div>
<div className="flex items-center mt-2">
<button
type="button"
className={`p-2 w-full rounded text-sm cursor-pointer transition-all duration-200 ${
position === 'tile'
? 'bg-gradient-to-r from-[rgb(var(--color-primary))] to-[rgb(var(--color-primary-hover))] text-white shadow-md'
: 'bg-block border border-purple-glow/20 hover:border-primary/50 hover:bg-primary/10'
}`}
onClick={() => setPosition(position === 'tile' ? 'bottom-right' : 'tile')}
>
{t('tools.image_watermark.tile')}
</button>
</div>
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.offset_x')} ({offsetX}px)
</label>
<input
type="range"
min="0"
max="100"
value={offsetX}
onChange={(e) => setOffsetX(parseInt(e.target.value))}
className={styles.rangeInput}
/>
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.offset_y')} ({offsetY}px)
</label>
<input
type="range"
min="0"
max="100"
value={offsetY}
onChange={(e) => setOffsetY(parseInt(e.target.value))}
className={styles.rangeInput}
/>
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.rotation')} ({rotation}°)
</label>
<input
type="range"
min="0"
max="360"
value={rotation}
onChange={(e) => setRotation(parseInt(e.target.value))}
className={styles.rangeInput}
/>
</div>
</div>
{/* 高级设置 */}
<div className="mb-4">
<div className="flex justify-between items-center mb-2">
<h4 className="text-secondary font-medium">
{t('tools.image_watermark.advanced_settings')}
</h4>
<FontAwesomeIcon icon={faShield} className="text-primary/70" />
</div>
<div>
<label className={styles.inputLabel}>
{t('tools.image_watermark.protection_level')}
</label>
<div className="grid grid-cols-3 gap-2">
{['standard', 'enhanced', 'professional'].map((level) => (
<button
key={level}
type="button"
className={`p-2 rounded text-sm cursor-pointer transition-all duration-200 ${
protectionLevel === level
? 'bg-gradient-to-r from-[rgb(var(--color-primary))] to-[rgb(var(--color-primary-hover))] text-white shadow-md'
: 'bg-block border border-purple-glow/20 hover:border-primary/50 hover:bg-primary/10'
}`}
onClick={() => {
setProtectionLevel(level as ProtectionLevel);
console.log('防护级别已设置为:', level);
}}
>
{t(`tools.image_watermark.${level}`)}
</button>
))}
</div>
</div>
</div>
{/* 操作按钮 */}
<div className="grid grid-cols-2 gap-4">
<button
className="btn-primary"
onClick={applyWatermark}
disabled={processing}
>
{processing ? (
<span>{t('tools.image_watermark.applying')}</span>
) : (
<span>
<FontAwesomeIcon icon={faLayerGroup} className="mr-2" />
{t('tools.image_watermark.apply_watermark')}
</span>
)}
</button>
<button
className="btn-secondary"
onClick={resetAll}
>
<FontAwesomeIcon icon={faTrash} className="mr-2" />
{t('tools.image_watermark.reset')}
</button>
</div>
</>
)}
</div>
{/* 右侧预览区域 */}
<div>
{/* 原始图片预览 */}
<div className="mb-4">
<h3 className={styles.heading}>
{t('tools.image_watermark.original_image')}
</h3>
<div className={styles.imageContainer}>
{originalImage ? (
<img src={originalImage} alt="Original" className={styles.image} />
) : (
<div className={styles.placeholder}>
{t('tools.image_watermark.no_image_selected')}
</div>
)}
</div>
</div>
{/* 水印处理图片预览 */}
<div className="mb-4">
<h3 className={styles.heading}>
{t('tools.image_watermark.watermarked_image')}
</h3>
<div className={styles.imageContainer}>
{watermarkedImage ? (
<img src={watermarkedImage} alt="Watermarked" className={styles.image} />
) : (
<div className={styles.placeholder}>
{t('tools.image_watermark.no_watermarked_image')}
</div>
)}
</div>
</div>
{/* 下载按钮 */}
{watermarkedImage && (
<button
className="btn-primary w-full"
onClick={downloadImage}
>
<FontAwesomeIcon icon={faDownload} className="mr-2" />
{t('tools.image_watermark.download_image')}
</button>
)}
</div>
</div>
</div>
{/* Canvas容器 - 隐藏,仅用于处理 */}
<div ref={canvasContainerRef} className="hidden">
<canvas id="watermark-canvas"></canvas>
</div>
</div>
);
}
+2 -1
View File
@@ -28,7 +28,8 @@ export const en = {
url_encoder: tools.url_encoder.en,
number_base_converter: tools.number_base_converter.en,
yml_properties_converter: tools.yml_properties_converter.en,
base64_to_image: tools.base64_to_image.en
base64_to_image: tools.base64_to_image.en,
image_watermark: tools.image_watermark.en
}
};
@@ -0,0 +1,59 @@
export const imageWatermarkEn = {
title: 'Image Watermark',
description: 'Add text or image watermarks to photos with various styles and anti-forgery features',
select_image: 'Select Image',
choose_file: 'Choose File',
watermark_settings: 'Watermark Settings',
watermark_type: 'Watermark Type',
text_watermark: 'Text Watermark',
image_watermark: 'Image Watermark',
text_settings: 'Text Settings',
watermark_text: 'Watermark Text',
font_family: 'Font Family',
font_size: 'Font Size',
font_color: 'Font Color',
font_opacity: 'Opacity',
font_weight: 'Font Weight',
image_settings: 'Image Settings',
select_watermark_image: 'Select Watermark Image',
image_opacity: 'Image Opacity',
image_scale: 'Image Scale',
position_settings: 'Position Settings',
position: 'Position',
top_left: 'Top Left',
top_center: 'Top Center',
top_right: 'Top Right',
middle_left: 'Middle Left',
middle_center: 'Middle Center',
middle_right: 'Middle Right',
bottom_left: 'Bottom Left',
bottom_center: 'Bottom Center',
bottom_right: 'Bottom Right',
tile: 'Tile',
offset_x: 'Horizontal Offset',
offset_y: 'Vertical Offset',
rotation: 'Rotation Angle',
advanced_settings: 'Advanced Settings',
protection_level: 'Protection Level',
standard: 'Standard',
enhanced: 'Enhanced',
professional: 'Professional',
apply_watermark: 'Apply Watermark',
applying: 'Processing...',
download_image: 'Download Image',
reset: 'Reset',
original_image: 'Original Image',
watermarked_image: 'Watermarked Image',
no_image_selected: 'No Image Selected',
no_watermarked_image: 'No Watermarked Image',
processing_failed: 'Processing Failed',
watermark_guide: 'Usage Guide',
guide_1: 'Add text or image watermarks with adjustable position, opacity, and size',
guide_2: 'Enhanced protection level provides better anti-forgery effects',
guide_3: 'Rotation and tiling effects increase watermark removal difficulty',
guide_4: 'All processing is done in the browser, images are not uploaded to servers',
guide_5: 'Preview watermark effects in real-time for easy adjustments',
guide_6: 'Professional protection level offers stronger copyright protection'
};
export default imageWatermarkEn;
@@ -0,0 +1,9 @@
import imageWatermarkEn from './en';
import imageWatermarkZh from './zh';
const imageWatermark = {
en: imageWatermarkEn,
zh: imageWatermarkZh
};
export default imageWatermark;
@@ -0,0 +1,59 @@
export const imageWatermarkZh = {
title: '图片水印',
description: '为图片添加文字或图片水印,支持多种样式和防伪功能',
select_image: '选择图片',
choose_file: '选择文件',
watermark_settings: '水印设置',
watermark_type: '水印类型',
text_watermark: '文字水印',
image_watermark: '图片水印',
text_settings: '文字设置',
watermark_text: '水印文字',
font_family: '字体',
font_size: '字体大小',
font_color: '字体颜色',
font_opacity: '不透明度',
font_weight: '字体粗细',
image_settings: '图片设置',
select_watermark_image: '选择水印图片',
image_opacity: '图片不透明度',
image_scale: '图片缩放',
position_settings: '位置设置',
position: '位置',
top_left: '左上',
top_center: '中上',
top_right: '右上',
middle_left: '左中',
middle_center: '居中',
middle_right: '右中',
bottom_left: '左下',
bottom_center: '中下',
bottom_right: '右下',
tile: '平铺',
offset_x: '水平偏移',
offset_y: '垂直偏移',
rotation: '旋转角度',
advanced_settings: '高级设置',
protection_level: '防护级别',
standard: '标准',
enhanced: '增强',
professional: '专业',
apply_watermark: '应用水印',
applying: '处理中...',
download_image: '下载图片',
reset: '重置',
original_image: '原始图片',
watermarked_image: '添加水印后',
no_image_selected: '未选择图片',
no_watermarked_image: '未添加水印',
processing_failed: '处理失败',
watermark_guide: '使用说明',
guide_1: '支持添加文字或图片水印,可调整位置、透明度和大小',
guide_2: '增强防护级别可提供更好的防伪效果',
guide_3: '支持旋转和平铺效果,增加水印识别难度',
guide_4: '所有处理在浏览器中完成,不会上传图片到服务器',
guide_5: '可实时预览水印效果,简单调整达到理想效果',
guide_6: '专业级防护提供更强的版权保护能力'
};
export default imageWatermarkZh;
+3 -1
View File
@@ -23,6 +23,7 @@ import urlEncoder from './url_encoder';
import numberBaseConverter from './number_base_converter';
import ymlPropertiesConverter from './yml_properties_converter';
import base64ToImage from './base64_to_image';
import imageWatermark from './image_watermark';
export const tools = {
json_formatter: jsonFormatter,
@@ -49,7 +50,8 @@ export const tools = {
url_encoder: urlEncoder,
number_base_converter: numberBaseConverter,
yml_properties_converter: ymlPropertiesConverter,
base64_to_image: base64ToImage
base64_to_image: base64ToImage,
image_watermark: imageWatermark
};
export default tools;
+2 -1
View File
@@ -28,7 +28,8 @@ export const zh = {
url_encoder: tools.url_encoder.zh,
number_base_converter: tools.number_base_converter.zh,
yml_properties_converter: tools.yml_properties_converter.zh,
base64_to_image: tools.base64_to_image.zh
base64_to_image: tools.base64_to_image.zh,
image_watermark: tools.image_watermark.zh
}
};
+6
View File
@@ -159,6 +159,12 @@ const tools: Tool[] = [
icon: faImage,
category: ['image', 'encoding'],
keywords: ['base64', 'base64转图片', '图片转base64', '图片', '解码', '编码', '转换', 'base64 to image', 'image to base64', 'image decoder', 'image encoder', 'tupian', 'tp', 'jm', 'bm', 'zhuanhuan', 'zh', 'base64转换']
},
{
code: 'image_watermark',
icon: faImage,
category: ['image'],
keywords: ['图片水印', '水印', '水印添加', '图片', '文字水印', '图片水印', 'watermark', 'image watermark', 'tupian shuiyin', 'tpshuiyin', 'shuiyin', 'sy', 'tp']
}
] as Tool[];