├── .gitignore ├── .vscode └── extensions.json ├── LICENSE ├── README.md ├── README.zh_CN.md ├── index.html ├── package-lock.json ├── package.json ├── src ├── App.vue ├── assets │ └── styles │ │ └── styles.css ├── components │ ├── CleanHiddenTextButton.vue │ ├── ClearableTextarea.vue │ ├── CopyButton.vue │ ├── EmojiSelector.vue │ ├── LanguageSelector.vue │ └── TextSelector.vue ├── composables │ └── useCursorPosition.js ├── i18n │ ├── index.js │ └── locales │ │ ├── en.js │ │ └── zh.js ├── main.js ├── store │ └── index.js ├── utils │ ├── cleanText.js │ ├── embedCode.js │ ├── emoji.js │ └── encoding.js └── views │ ├── components │ ├── CarrierTextPanel.vue │ ├── EmbedCodePanel.vue │ ├── EmojiPanel.vue │ ├── FooterSection.vue │ ├── InputPanel.vue │ ├── ModeToggle.vue │ └── OutputPanel.vue │ └── index.vue └── vite.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Vue.volar" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Antkites 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [中文文档](./README.zh_CN.md) | [English](#) 2 | 3 | # Hidden Word 4 | 5 | A Unicode-based text digital watermarking tool for embedding invisible copyright marks and metadata in text content. 6 | 7 | ## Features 8 | 9 | - **Copyright Protection**: Embed invisible watermarks in articles to effectively protect original content 10 | - **Metadata Embedding**: Securely embed structured information in text for content verification 11 | - **Source Tracking**: Verify the original source of content through embedded watermark information 12 | - **Cross-platform Support**: Works on any platform that supports Unicode 13 | - **Website Integration**: Provides standardized embedding solutions to automatically add watermarks to website content 14 | 15 | ## Use Cases 16 | 17 | 1. **Content Creators**: Add digital watermarks to original content to protect intellectual property 18 | 2. **Copyright Management**: Add invisible copyright marks to digital content 19 | 3. **Content Verification**: Embed verification information in public texts to ensure content integrity 20 | 4. **Information Tracing**: Identify and track the dissemination path of digital content 21 | 22 | ## Quick Start 23 | 24 | ### Clone Repository 25 | 26 | ```bash 27 | git clone https://github.com/Ackites/hidden-word.git 28 | 29 | cd hidden-word 30 | ``` 31 | 32 | ### Install Dependencies 33 | 34 | ```bash 35 | npm install 36 | ``` 37 | 38 | ### Development 39 | 40 | ```bash 41 | npm run dev 42 | ``` 43 | 44 | ### Build 45 | 46 | ```bash 47 | npm run build 48 | ``` 49 | 50 | ## License 51 | 52 | [MIT](LICENSE) 53 | 54 | ## Star History 55 | 56 | [![Star History Chart](https://api.star-history.com/svg?repos=Ackites/hidden-word&type=Date)](https://www.star-history.com/#Ackites/hidden-word&Date) -------------------------------------------------------------------------------- /README.zh_CN.md: -------------------------------------------------------------------------------- 1 | # Hidden Word 2 | 3 | 一个基于Unicode的文本数字水印工具,用于在文本内容中嵌入不可见的版权标识和元数据信息。 4 | 5 | ## 功能特点 6 | 7 | - **版权保护**:在文章中嵌入不可见水印,有效保护原创内容 8 | - **元数据嵌入**:在文本中安全地嵌入结构化信息,用于内容验证 9 | - **来源追踪**:通过嵌入的水印信息,可以验证内容的原始来源 10 | - **跨平台支持**:可在任何支持 Unicode 的平台上使用 11 | - **网站集成**:提供标准化的嵌入方案,可自动为网站内容添加水印 12 | 13 | ## 使用场景 14 | 15 | 1. **内容创作者**:为原创内容添加数字水印,保护知识产权 16 | 2. **版权管理**:为数字内容添加不可见的版权标识 17 | 3. **内容验证**:在公开文本中嵌入验证信息,确保内容完整性 18 | 4. **信息溯源**:识别和追踪数字内容的传播路径 19 | 20 | ## 快速开始 21 | 22 | ### 克隆仓库 23 | 24 | ```bash 25 | git clone https://github.com/Ackites/hidden-word.git 26 | 27 | cd hidden-word 28 | ``` 29 | 30 | ### 安装依赖 31 | 32 | ```bash 33 | npm install 34 | ``` 35 | 36 | ### 开发模式 37 | 38 | ```bash 39 | npm run dev 40 | ``` 41 | 42 | ### 构建生产版本 43 | 44 | ```bash 45 | npm run build 46 | ``` 47 | 48 | ## 许可证 49 | 50 | [MIT](LICENSE) 51 | 52 | ## Star History 53 | 54 | [![Star History Chart](https://api.star-history.com/svg?repos=Ackites/hidden-word&type=Date)](https://www.star-history.com/#Ackites/hidden-word&Date) -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 11 | Hidden Word 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hidden-word", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "hidden-word", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "@emoji-mart/data": "^1.2.1", 12 | "@tailwindcss/vite": "^4.0.12", 13 | "emoji-mart": "^5.6.0", 14 | "pinia": "^3.0.1", 15 | "tailwindcss": "^4.0.12", 16 | "vue": "^3.5.13", 17 | "vue-i18n": "^9.14.3" 18 | }, 19 | "devDependencies": { 20 | "@vitejs/plugin-vue": "^5.2.1", 21 | "vite": "^6.2.0" 22 | } 23 | }, 24 | "node_modules/@babel/helper-string-parser": { 25 | "version": "7.25.9", 26 | "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", 27 | "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", 28 | "engines": { 29 | "node": ">=6.9.0" 30 | } 31 | }, 32 | "node_modules/@babel/helper-validator-identifier": { 33 | "version": "7.25.9", 34 | "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", 35 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", 36 | "engines": { 37 | "node": ">=6.9.0" 38 | } 39 | }, 40 | "node_modules/@babel/parser": { 41 | "version": "7.26.10", 42 | "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.10.tgz", 43 | "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", 44 | "dependencies": { 45 | "@babel/types": "^7.26.10" 46 | }, 47 | "bin": { 48 | "parser": "bin/babel-parser.js" 49 | }, 50 | "engines": { 51 | "node": ">=6.0.0" 52 | } 53 | }, 54 | "node_modules/@babel/types": { 55 | "version": "7.26.10", 56 | "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.10.tgz", 57 | "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", 58 | "dependencies": { 59 | "@babel/helper-string-parser": "^7.25.9", 60 | "@babel/helper-validator-identifier": "^7.25.9" 61 | }, 62 | "engines": { 63 | "node": ">=6.9.0" 64 | } 65 | }, 66 | "node_modules/@emoji-mart/data": { 67 | "version": "1.2.1", 68 | "resolved": "https://registry.npmmirror.com/@emoji-mart/data/-/data-1.2.1.tgz", 69 | "integrity": "sha512-no2pQMWiBy6gpBEiqGeU77/bFejDqUTRY7KX+0+iur13op3bqUsXdnwoZs6Xb1zbv0gAj5VvS1PWoUUckSr5Dw==" 70 | }, 71 | "node_modules/@esbuild/aix-ppc64": { 72 | "version": "0.25.1", 73 | "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", 74 | "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", 75 | "cpu": [ 76 | "ppc64" 77 | ], 78 | "optional": true, 79 | "os": [ 80 | "aix" 81 | ], 82 | "engines": { 83 | "node": ">=18" 84 | } 85 | }, 86 | "node_modules/@esbuild/android-arm": { 87 | "version": "0.25.1", 88 | "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.1.tgz", 89 | "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", 90 | "cpu": [ 91 | "arm" 92 | ], 93 | "optional": true, 94 | "os": [ 95 | "android" 96 | ], 97 | "engines": { 98 | "node": ">=18" 99 | } 100 | }, 101 | "node_modules/@esbuild/android-arm64": { 102 | "version": "0.25.1", 103 | "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", 104 | "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", 105 | "cpu": [ 106 | "arm64" 107 | ], 108 | "optional": true, 109 | "os": [ 110 | "android" 111 | ], 112 | "engines": { 113 | "node": ">=18" 114 | } 115 | }, 116 | "node_modules/@esbuild/android-x64": { 117 | "version": "0.25.1", 118 | "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.1.tgz", 119 | "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", 120 | "cpu": [ 121 | "x64" 122 | ], 123 | "optional": true, 124 | "os": [ 125 | "android" 126 | ], 127 | "engines": { 128 | "node": ">=18" 129 | } 130 | }, 131 | "node_modules/@esbuild/darwin-arm64": { 132 | "version": "0.25.1", 133 | "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", 134 | "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", 135 | "cpu": [ 136 | "arm64" 137 | ], 138 | "optional": true, 139 | "os": [ 140 | "darwin" 141 | ], 142 | "engines": { 143 | "node": ">=18" 144 | } 145 | }, 146 | "node_modules/@esbuild/darwin-x64": { 147 | "version": "0.25.1", 148 | "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", 149 | "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", 150 | "cpu": [ 151 | "x64" 152 | ], 153 | "optional": true, 154 | "os": [ 155 | "darwin" 156 | ], 157 | "engines": { 158 | "node": ">=18" 159 | } 160 | }, 161 | "node_modules/@esbuild/freebsd-arm64": { 162 | "version": "0.25.1", 163 | "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", 164 | "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", 165 | "cpu": [ 166 | "arm64" 167 | ], 168 | "optional": true, 169 | "os": [ 170 | "freebsd" 171 | ], 172 | "engines": { 173 | "node": ">=18" 174 | } 175 | }, 176 | "node_modules/@esbuild/freebsd-x64": { 177 | "version": "0.25.1", 178 | "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", 179 | "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", 180 | "cpu": [ 181 | "x64" 182 | ], 183 | "optional": true, 184 | "os": [ 185 | "freebsd" 186 | ], 187 | "engines": { 188 | "node": ">=18" 189 | } 190 | }, 191 | "node_modules/@esbuild/linux-arm": { 192 | "version": "0.25.1", 193 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", 194 | "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", 195 | "cpu": [ 196 | "arm" 197 | ], 198 | "optional": true, 199 | "os": [ 200 | "linux" 201 | ], 202 | "engines": { 203 | "node": ">=18" 204 | } 205 | }, 206 | "node_modules/@esbuild/linux-arm64": { 207 | "version": "0.25.1", 208 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", 209 | "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", 210 | "cpu": [ 211 | "arm64" 212 | ], 213 | "optional": true, 214 | "os": [ 215 | "linux" 216 | ], 217 | "engines": { 218 | "node": ">=18" 219 | } 220 | }, 221 | "node_modules/@esbuild/linux-ia32": { 222 | "version": "0.25.1", 223 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", 224 | "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", 225 | "cpu": [ 226 | "ia32" 227 | ], 228 | "optional": true, 229 | "os": [ 230 | "linux" 231 | ], 232 | "engines": { 233 | "node": ">=18" 234 | } 235 | }, 236 | "node_modules/@esbuild/linux-loong64": { 237 | "version": "0.25.1", 238 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", 239 | "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", 240 | "cpu": [ 241 | "loong64" 242 | ], 243 | "optional": true, 244 | "os": [ 245 | "linux" 246 | ], 247 | "engines": { 248 | "node": ">=18" 249 | } 250 | }, 251 | "node_modules/@esbuild/linux-mips64el": { 252 | "version": "0.25.1", 253 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", 254 | "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", 255 | "cpu": [ 256 | "mips64el" 257 | ], 258 | "optional": true, 259 | "os": [ 260 | "linux" 261 | ], 262 | "engines": { 263 | "node": ">=18" 264 | } 265 | }, 266 | "node_modules/@esbuild/linux-ppc64": { 267 | "version": "0.25.1", 268 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", 269 | "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", 270 | "cpu": [ 271 | "ppc64" 272 | ], 273 | "optional": true, 274 | "os": [ 275 | "linux" 276 | ], 277 | "engines": { 278 | "node": ">=18" 279 | } 280 | }, 281 | "node_modules/@esbuild/linux-riscv64": { 282 | "version": "0.25.1", 283 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", 284 | "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", 285 | "cpu": [ 286 | "riscv64" 287 | ], 288 | "optional": true, 289 | "os": [ 290 | "linux" 291 | ], 292 | "engines": { 293 | "node": ">=18" 294 | } 295 | }, 296 | "node_modules/@esbuild/linux-s390x": { 297 | "version": "0.25.1", 298 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", 299 | "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", 300 | "cpu": [ 301 | "s390x" 302 | ], 303 | "optional": true, 304 | "os": [ 305 | "linux" 306 | ], 307 | "engines": { 308 | "node": ">=18" 309 | } 310 | }, 311 | "node_modules/@esbuild/linux-x64": { 312 | "version": "0.25.1", 313 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", 314 | "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", 315 | "cpu": [ 316 | "x64" 317 | ], 318 | "optional": true, 319 | "os": [ 320 | "linux" 321 | ], 322 | "engines": { 323 | "node": ">=18" 324 | } 325 | }, 326 | "node_modules/@esbuild/netbsd-arm64": { 327 | "version": "0.25.1", 328 | "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", 329 | "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", 330 | "cpu": [ 331 | "arm64" 332 | ], 333 | "optional": true, 334 | "os": [ 335 | "netbsd" 336 | ], 337 | "engines": { 338 | "node": ">=18" 339 | } 340 | }, 341 | "node_modules/@esbuild/netbsd-x64": { 342 | "version": "0.25.1", 343 | "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", 344 | "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", 345 | "cpu": [ 346 | "x64" 347 | ], 348 | "optional": true, 349 | "os": [ 350 | "netbsd" 351 | ], 352 | "engines": { 353 | "node": ">=18" 354 | } 355 | }, 356 | "node_modules/@esbuild/openbsd-arm64": { 357 | "version": "0.25.1", 358 | "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", 359 | "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", 360 | "cpu": [ 361 | "arm64" 362 | ], 363 | "optional": true, 364 | "os": [ 365 | "openbsd" 366 | ], 367 | "engines": { 368 | "node": ">=18" 369 | } 370 | }, 371 | "node_modules/@esbuild/openbsd-x64": { 372 | "version": "0.25.1", 373 | "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", 374 | "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", 375 | "cpu": [ 376 | "x64" 377 | ], 378 | "optional": true, 379 | "os": [ 380 | "openbsd" 381 | ], 382 | "engines": { 383 | "node": ">=18" 384 | } 385 | }, 386 | "node_modules/@esbuild/sunos-x64": { 387 | "version": "0.25.1", 388 | "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", 389 | "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", 390 | "cpu": [ 391 | "x64" 392 | ], 393 | "optional": true, 394 | "os": [ 395 | "sunos" 396 | ], 397 | "engines": { 398 | "node": ">=18" 399 | } 400 | }, 401 | "node_modules/@esbuild/win32-arm64": { 402 | "version": "0.25.1", 403 | "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", 404 | "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", 405 | "cpu": [ 406 | "arm64" 407 | ], 408 | "optional": true, 409 | "os": [ 410 | "win32" 411 | ], 412 | "engines": { 413 | "node": ">=18" 414 | } 415 | }, 416 | "node_modules/@esbuild/win32-ia32": { 417 | "version": "0.25.1", 418 | "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", 419 | "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", 420 | "cpu": [ 421 | "ia32" 422 | ], 423 | "optional": true, 424 | "os": [ 425 | "win32" 426 | ], 427 | "engines": { 428 | "node": ">=18" 429 | } 430 | }, 431 | "node_modules/@esbuild/win32-x64": { 432 | "version": "0.25.1", 433 | "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", 434 | "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", 435 | "cpu": [ 436 | "x64" 437 | ], 438 | "optional": true, 439 | "os": [ 440 | "win32" 441 | ], 442 | "engines": { 443 | "node": ">=18" 444 | } 445 | }, 446 | "node_modules/@intlify/core-base": { 447 | "version": "9.14.3", 448 | "resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.14.3.tgz", 449 | "integrity": "sha512-nbJ7pKTlXFnaXPblyfiH6awAx1C0PWNNuqXAR74yRwgi5A/Re/8/5fErLY0pv4R8+EHj3ZaThMHdnuC/5OBa6g==", 450 | "dependencies": { 451 | "@intlify/message-compiler": "9.14.3", 452 | "@intlify/shared": "9.14.3" 453 | }, 454 | "engines": { 455 | "node": ">= 16" 456 | }, 457 | "funding": { 458 | "url": "https://github.com/sponsors/kazupon" 459 | } 460 | }, 461 | "node_modules/@intlify/message-compiler": { 462 | "version": "9.14.3", 463 | "resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.14.3.tgz", 464 | "integrity": "sha512-ANwC226BQdd+MpJ36rOYkChSESfPwu3Ss2Faw0RHTOknYLoHTX6V6e/JjIKVDMbzs0/H/df/rO6yU0SPiWHqNg==", 465 | "dependencies": { 466 | "@intlify/shared": "9.14.3", 467 | "source-map-js": "^1.0.2" 468 | }, 469 | "engines": { 470 | "node": ">= 16" 471 | }, 472 | "funding": { 473 | "url": "https://github.com/sponsors/kazupon" 474 | } 475 | }, 476 | "node_modules/@intlify/shared": { 477 | "version": "9.14.3", 478 | "resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.14.3.tgz", 479 | "integrity": "sha512-hJXz9LA5VG7qNE00t50bdzDv8Z4q9fpcL81wj4y4duKavrv0KM8YNLTwXNEFINHjTsfrG9TXvPuEjVaAvZ7yWg==", 480 | "engines": { 481 | "node": ">= 16" 482 | }, 483 | "funding": { 484 | "url": "https://github.com/sponsors/kazupon" 485 | } 486 | }, 487 | "node_modules/@jridgewell/sourcemap-codec": { 488 | "version": "1.5.0", 489 | "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 490 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" 491 | }, 492 | "node_modules/@rollup/rollup-android-arm-eabi": { 493 | "version": "4.35.0", 494 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz", 495 | "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==", 496 | "cpu": [ 497 | "arm" 498 | ], 499 | "optional": true, 500 | "os": [ 501 | "android" 502 | ] 503 | }, 504 | "node_modules/@rollup/rollup-android-arm64": { 505 | "version": "4.35.0", 506 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz", 507 | "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==", 508 | "cpu": [ 509 | "arm64" 510 | ], 511 | "optional": true, 512 | "os": [ 513 | "android" 514 | ] 515 | }, 516 | "node_modules/@rollup/rollup-darwin-arm64": { 517 | "version": "4.35.0", 518 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", 519 | "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==", 520 | "cpu": [ 521 | "arm64" 522 | ], 523 | "optional": true, 524 | "os": [ 525 | "darwin" 526 | ] 527 | }, 528 | "node_modules/@rollup/rollup-darwin-x64": { 529 | "version": "4.35.0", 530 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz", 531 | "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==", 532 | "cpu": [ 533 | "x64" 534 | ], 535 | "optional": true, 536 | "os": [ 537 | "darwin" 538 | ] 539 | }, 540 | "node_modules/@rollup/rollup-freebsd-arm64": { 541 | "version": "4.35.0", 542 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz", 543 | "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==", 544 | "cpu": [ 545 | "arm64" 546 | ], 547 | "optional": true, 548 | "os": [ 549 | "freebsd" 550 | ] 551 | }, 552 | "node_modules/@rollup/rollup-freebsd-x64": { 553 | "version": "4.35.0", 554 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz", 555 | "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==", 556 | "cpu": [ 557 | "x64" 558 | ], 559 | "optional": true, 560 | "os": [ 561 | "freebsd" 562 | ] 563 | }, 564 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 565 | "version": "4.35.0", 566 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz", 567 | "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==", 568 | "cpu": [ 569 | "arm" 570 | ], 571 | "optional": true, 572 | "os": [ 573 | "linux" 574 | ] 575 | }, 576 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 577 | "version": "4.35.0", 578 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz", 579 | "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==", 580 | "cpu": [ 581 | "arm" 582 | ], 583 | "optional": true, 584 | "os": [ 585 | "linux" 586 | ] 587 | }, 588 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 589 | "version": "4.35.0", 590 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz", 591 | "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==", 592 | "cpu": [ 593 | "arm64" 594 | ], 595 | "optional": true, 596 | "os": [ 597 | "linux" 598 | ] 599 | }, 600 | "node_modules/@rollup/rollup-linux-arm64-musl": { 601 | "version": "4.35.0", 602 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz", 603 | "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==", 604 | "cpu": [ 605 | "arm64" 606 | ], 607 | "optional": true, 608 | "os": [ 609 | "linux" 610 | ] 611 | }, 612 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 613 | "version": "4.35.0", 614 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz", 615 | "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==", 616 | "cpu": [ 617 | "loong64" 618 | ], 619 | "optional": true, 620 | "os": [ 621 | "linux" 622 | ] 623 | }, 624 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 625 | "version": "4.35.0", 626 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz", 627 | "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==", 628 | "cpu": [ 629 | "ppc64" 630 | ], 631 | "optional": true, 632 | "os": [ 633 | "linux" 634 | ] 635 | }, 636 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 637 | "version": "4.35.0", 638 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz", 639 | "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==", 640 | "cpu": [ 641 | "riscv64" 642 | ], 643 | "optional": true, 644 | "os": [ 645 | "linux" 646 | ] 647 | }, 648 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 649 | "version": "4.35.0", 650 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz", 651 | "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==", 652 | "cpu": [ 653 | "s390x" 654 | ], 655 | "optional": true, 656 | "os": [ 657 | "linux" 658 | ] 659 | }, 660 | "node_modules/@rollup/rollup-linux-x64-gnu": { 661 | "version": "4.35.0", 662 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz", 663 | "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==", 664 | "cpu": [ 665 | "x64" 666 | ], 667 | "optional": true, 668 | "os": [ 669 | "linux" 670 | ] 671 | }, 672 | "node_modules/@rollup/rollup-linux-x64-musl": { 673 | "version": "4.35.0", 674 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz", 675 | "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==", 676 | "cpu": [ 677 | "x64" 678 | ], 679 | "optional": true, 680 | "os": [ 681 | "linux" 682 | ] 683 | }, 684 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 685 | "version": "4.35.0", 686 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz", 687 | "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==", 688 | "cpu": [ 689 | "arm64" 690 | ], 691 | "optional": true, 692 | "os": [ 693 | "win32" 694 | ] 695 | }, 696 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 697 | "version": "4.35.0", 698 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz", 699 | "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==", 700 | "cpu": [ 701 | "ia32" 702 | ], 703 | "optional": true, 704 | "os": [ 705 | "win32" 706 | ] 707 | }, 708 | "node_modules/@rollup/rollup-win32-x64-msvc": { 709 | "version": "4.35.0", 710 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz", 711 | "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==", 712 | "cpu": [ 713 | "x64" 714 | ], 715 | "optional": true, 716 | "os": [ 717 | "win32" 718 | ] 719 | }, 720 | "node_modules/@tailwindcss/node": { 721 | "version": "4.0.12", 722 | "resolved": "https://registry.npmmirror.com/@tailwindcss/node/-/node-4.0.12.tgz", 723 | "integrity": "sha512-a6J11K1Ztdln9OrGfoM75/hChYPcHYGNYimqciMrvKXRmmPaS8XZTHhdvb5a3glz4Kd4ZxE1MnuFE2c0fGGmtg==", 724 | "dependencies": { 725 | "enhanced-resolve": "^5.18.1", 726 | "jiti": "^2.4.2", 727 | "tailwindcss": "4.0.12" 728 | } 729 | }, 730 | "node_modules/@tailwindcss/oxide": { 731 | "version": "4.0.12", 732 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide/-/oxide-4.0.12.tgz", 733 | "integrity": "sha512-DWb+myvJB9xJwelwT9GHaMc1qJj6MDXRDR0CS+T8IdkejAtu8ctJAgV4r1drQJLPeS7mNwq2UHW2GWrudTf63A==", 734 | "engines": { 735 | "node": ">= 10" 736 | }, 737 | "optionalDependencies": { 738 | "@tailwindcss/oxide-android-arm64": "4.0.12", 739 | "@tailwindcss/oxide-darwin-arm64": "4.0.12", 740 | "@tailwindcss/oxide-darwin-x64": "4.0.12", 741 | "@tailwindcss/oxide-freebsd-x64": "4.0.12", 742 | "@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.12", 743 | "@tailwindcss/oxide-linux-arm64-gnu": "4.0.12", 744 | "@tailwindcss/oxide-linux-arm64-musl": "4.0.12", 745 | "@tailwindcss/oxide-linux-x64-gnu": "4.0.12", 746 | "@tailwindcss/oxide-linux-x64-musl": "4.0.12", 747 | "@tailwindcss/oxide-win32-arm64-msvc": "4.0.12", 748 | "@tailwindcss/oxide-win32-x64-msvc": "4.0.12" 749 | } 750 | }, 751 | "node_modules/@tailwindcss/oxide-android-arm64": { 752 | "version": "4.0.12", 753 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.12.tgz", 754 | "integrity": "sha512-dAXCaemu3mHLXcA5GwGlQynX8n7tTdvn5i1zAxRvZ5iC9fWLl5bGnjZnzrQqT7ttxCvRwdVf3IHUnMVdDBO/kQ==", 755 | "cpu": [ 756 | "arm64" 757 | ], 758 | "optional": true, 759 | "os": [ 760 | "android" 761 | ], 762 | "engines": { 763 | "node": ">= 10" 764 | } 765 | }, 766 | "node_modules/@tailwindcss/oxide-darwin-arm64": { 767 | "version": "4.0.12", 768 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.12.tgz", 769 | "integrity": "sha512-vPNI+TpJQ7sizselDXIJdYkx9Cu6JBdtmRWujw9pVIxW8uz3O2PjgGGzL/7A0sXI8XDjSyRChrUnEW9rQygmJQ==", 770 | "cpu": [ 771 | "arm64" 772 | ], 773 | "optional": true, 774 | "os": [ 775 | "darwin" 776 | ], 777 | "engines": { 778 | "node": ">= 10" 779 | } 780 | }, 781 | "node_modules/@tailwindcss/oxide-darwin-x64": { 782 | "version": "4.0.12", 783 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.12.tgz", 784 | "integrity": "sha512-RL/9jM41Fdq4Efr35C5wgLx98BirnrfwuD+zgMFK6Ir68HeOSqBhW9jsEeC7Y/JcGyPd3MEoJVIU4fAb7YLg7A==", 785 | "cpu": [ 786 | "x64" 787 | ], 788 | "optional": true, 789 | "os": [ 790 | "darwin" 791 | ], 792 | "engines": { 793 | "node": ">= 10" 794 | } 795 | }, 796 | "node_modules/@tailwindcss/oxide-freebsd-x64": { 797 | "version": "4.0.12", 798 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.12.tgz", 799 | "integrity": "sha512-7WzWiax+LguJcMEimY0Q4sBLlFXu1tYxVka3+G2M9KmU/3m84J3jAIV4KZWnockbHsbb2XgrEjtlJKVwHQCoRA==", 800 | "cpu": [ 801 | "x64" 802 | ], 803 | "optional": true, 804 | "os": [ 805 | "freebsd" 806 | ], 807 | "engines": { 808 | "node": ">= 10" 809 | } 810 | }, 811 | "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { 812 | "version": "4.0.12", 813 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.12.tgz", 814 | "integrity": "sha512-X9LRC7jjE1QlfIaBbXjY0PGeQP87lz5mEfLSVs2J1yRc9PSg1tEPS9NBqY4BU9v5toZgJgzKeaNltORyTs22TQ==", 815 | "cpu": [ 816 | "arm" 817 | ], 818 | "optional": true, 819 | "os": [ 820 | "linux" 821 | ], 822 | "engines": { 823 | "node": ">= 10" 824 | } 825 | }, 826 | "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { 827 | "version": "4.0.12", 828 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.12.tgz", 829 | "integrity": "sha512-i24IFNq2402zfDdoWKypXz0ZNS2G4NKaA82tgBlE2OhHIE+4mg2JDb5wVfyP6R+MCm5grgXvurcIcKWvo44QiQ==", 830 | "cpu": [ 831 | "arm64" 832 | ], 833 | "optional": true, 834 | "os": [ 835 | "linux" 836 | ], 837 | "engines": { 838 | "node": ">= 10" 839 | } 840 | }, 841 | "node_modules/@tailwindcss/oxide-linux-arm64-musl": { 842 | "version": "4.0.12", 843 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.12.tgz", 844 | "integrity": "sha512-LmOdshJBfAGIBG0DdBWhI0n5LTMurnGGJCHcsm9F//ISfsHtCnnYIKgYQui5oOz1SUCkqsMGfkAzWyNKZqbGNw==", 845 | "cpu": [ 846 | "arm64" 847 | ], 848 | "optional": true, 849 | "os": [ 850 | "linux" 851 | ], 852 | "engines": { 853 | "node": ">= 10" 854 | } 855 | }, 856 | "node_modules/@tailwindcss/oxide-linux-x64-gnu": { 857 | "version": "4.0.12", 858 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.12.tgz", 859 | "integrity": "sha512-OSK667qZRH30ep8RiHbZDQfqkXjnzKxdn0oRwWzgCO8CoTxV+MvIkd0BWdQbYtYuM1wrakARV/Hwp0eA/qzdbw==", 860 | "cpu": [ 861 | "x64" 862 | ], 863 | "optional": true, 864 | "os": [ 865 | "linux" 866 | ], 867 | "engines": { 868 | "node": ">= 10" 869 | } 870 | }, 871 | "node_modules/@tailwindcss/oxide-linux-x64-musl": { 872 | "version": "4.0.12", 873 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.12.tgz", 874 | "integrity": "sha512-uylhWq6OWQ8krV8Jk+v0H/3AZKJW6xYMgNMyNnUbbYXWi7hIVdxRKNUB5UvrlC3RxtgsK5EAV2i1CWTRsNcAnA==", 875 | "cpu": [ 876 | "x64" 877 | ], 878 | "optional": true, 879 | "os": [ 880 | "linux" 881 | ], 882 | "engines": { 883 | "node": ">= 10" 884 | } 885 | }, 886 | "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { 887 | "version": "4.0.12", 888 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.12.tgz", 889 | "integrity": "sha512-XDLnhMoXZEEOir1LK43/gHHwK84V1GlV8+pAncUAIN2wloeD+nNciI9WRIY/BeFTqES22DhTIGoilSO39xDb2g==", 890 | "cpu": [ 891 | "arm64" 892 | ], 893 | "optional": true, 894 | "os": [ 895 | "win32" 896 | ], 897 | "engines": { 898 | "node": ">= 10" 899 | } 900 | }, 901 | "node_modules/@tailwindcss/oxide-win32-x64-msvc": { 902 | "version": "4.0.12", 903 | "resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.12.tgz", 904 | "integrity": "sha512-I/BbjCLpKDQucvtn6rFuYLst1nfFwSMYyPzkx/095RE+tuzk5+fwXuzQh7T3fIBTcbn82qH/sFka7yPGA50tLw==", 905 | "cpu": [ 906 | "x64" 907 | ], 908 | "optional": true, 909 | "os": [ 910 | "win32" 911 | ], 912 | "engines": { 913 | "node": ">= 10" 914 | } 915 | }, 916 | "node_modules/@tailwindcss/vite": { 917 | "version": "4.0.12", 918 | "resolved": "https://registry.npmmirror.com/@tailwindcss/vite/-/vite-4.0.12.tgz", 919 | "integrity": "sha512-JM3gp601UJiryIZ9R2bSqalzcOy15RCybQ1Q+BJqDEwVyo4LkWKeqQAcrpHapWXY31OJFTuOUVBFDWMhzHm2Bg==", 920 | "dependencies": { 921 | "@tailwindcss/node": "4.0.12", 922 | "@tailwindcss/oxide": "4.0.12", 923 | "lightningcss": "^1.29.1", 924 | "tailwindcss": "4.0.12" 925 | }, 926 | "peerDependencies": { 927 | "vite": "^5.2.0 || ^6" 928 | } 929 | }, 930 | "node_modules/@types/estree": { 931 | "version": "1.0.6", 932 | "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.6.tgz", 933 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" 934 | }, 935 | "node_modules/@vitejs/plugin-vue": { 936 | "version": "5.2.1", 937 | "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz", 938 | "integrity": "sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==", 939 | "dev": true, 940 | "engines": { 941 | "node": "^18.0.0 || >=20.0.0" 942 | }, 943 | "peerDependencies": { 944 | "vite": "^5.0.0 || ^6.0.0", 945 | "vue": "^3.2.25" 946 | } 947 | }, 948 | "node_modules/@vue/compiler-core": { 949 | "version": "3.5.13", 950 | "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.13.tgz", 951 | "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", 952 | "dependencies": { 953 | "@babel/parser": "^7.25.3", 954 | "@vue/shared": "3.5.13", 955 | "entities": "^4.5.0", 956 | "estree-walker": "^2.0.2", 957 | "source-map-js": "^1.2.0" 958 | } 959 | }, 960 | "node_modules/@vue/compiler-dom": { 961 | "version": "3.5.13", 962 | "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", 963 | "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", 964 | "dependencies": { 965 | "@vue/compiler-core": "3.5.13", 966 | "@vue/shared": "3.5.13" 967 | } 968 | }, 969 | "node_modules/@vue/compiler-sfc": { 970 | "version": "3.5.13", 971 | "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", 972 | "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", 973 | "dependencies": { 974 | "@babel/parser": "^7.25.3", 975 | "@vue/compiler-core": "3.5.13", 976 | "@vue/compiler-dom": "3.5.13", 977 | "@vue/compiler-ssr": "3.5.13", 978 | "@vue/shared": "3.5.13", 979 | "estree-walker": "^2.0.2", 980 | "magic-string": "^0.30.11", 981 | "postcss": "^8.4.48", 982 | "source-map-js": "^1.2.0" 983 | } 984 | }, 985 | "node_modules/@vue/compiler-ssr": { 986 | "version": "3.5.13", 987 | "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", 988 | "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", 989 | "dependencies": { 990 | "@vue/compiler-dom": "3.5.13", 991 | "@vue/shared": "3.5.13" 992 | } 993 | }, 994 | "node_modules/@vue/devtools-api": { 995 | "version": "7.7.2", 996 | "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-7.7.2.tgz", 997 | "integrity": "sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==", 998 | "dependencies": { 999 | "@vue/devtools-kit": "^7.7.2" 1000 | } 1001 | }, 1002 | "node_modules/@vue/devtools-kit": { 1003 | "version": "7.7.2", 1004 | "resolved": "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.7.2.tgz", 1005 | "integrity": "sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==", 1006 | "dependencies": { 1007 | "@vue/devtools-shared": "^7.7.2", 1008 | "birpc": "^0.2.19", 1009 | "hookable": "^5.5.3", 1010 | "mitt": "^3.0.1", 1011 | "perfect-debounce": "^1.0.0", 1012 | "speakingurl": "^14.0.1", 1013 | "superjson": "^2.2.1" 1014 | } 1015 | }, 1016 | "node_modules/@vue/devtools-shared": { 1017 | "version": "7.7.2", 1018 | "resolved": "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.7.2.tgz", 1019 | "integrity": "sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==", 1020 | "dependencies": { 1021 | "rfdc": "^1.4.1" 1022 | } 1023 | }, 1024 | "node_modules/@vue/reactivity": { 1025 | "version": "3.5.13", 1026 | "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.13.tgz", 1027 | "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==", 1028 | "dependencies": { 1029 | "@vue/shared": "3.5.13" 1030 | } 1031 | }, 1032 | "node_modules/@vue/runtime-core": { 1033 | "version": "3.5.13", 1034 | "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.13.tgz", 1035 | "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==", 1036 | "dependencies": { 1037 | "@vue/reactivity": "3.5.13", 1038 | "@vue/shared": "3.5.13" 1039 | } 1040 | }, 1041 | "node_modules/@vue/runtime-dom": { 1042 | "version": "3.5.13", 1043 | "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz", 1044 | "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==", 1045 | "dependencies": { 1046 | "@vue/reactivity": "3.5.13", 1047 | "@vue/runtime-core": "3.5.13", 1048 | "@vue/shared": "3.5.13", 1049 | "csstype": "^3.1.3" 1050 | } 1051 | }, 1052 | "node_modules/@vue/server-renderer": { 1053 | "version": "3.5.13", 1054 | "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.13.tgz", 1055 | "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==", 1056 | "dependencies": { 1057 | "@vue/compiler-ssr": "3.5.13", 1058 | "@vue/shared": "3.5.13" 1059 | }, 1060 | "peerDependencies": { 1061 | "vue": "3.5.13" 1062 | } 1063 | }, 1064 | "node_modules/@vue/shared": { 1065 | "version": "3.5.13", 1066 | "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz", 1067 | "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==" 1068 | }, 1069 | "node_modules/birpc": { 1070 | "version": "0.2.19", 1071 | "resolved": "https://registry.npmmirror.com/birpc/-/birpc-0.2.19.tgz", 1072 | "integrity": "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==", 1073 | "funding": { 1074 | "url": "https://github.com/sponsors/antfu" 1075 | } 1076 | }, 1077 | "node_modules/copy-anything": { 1078 | "version": "3.0.5", 1079 | "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-3.0.5.tgz", 1080 | "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", 1081 | "dependencies": { 1082 | "is-what": "^4.1.8" 1083 | }, 1084 | "engines": { 1085 | "node": ">=12.13" 1086 | }, 1087 | "funding": { 1088 | "url": "https://github.com/sponsors/mesqueeb" 1089 | } 1090 | }, 1091 | "node_modules/csstype": { 1092 | "version": "3.1.3", 1093 | "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", 1094 | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" 1095 | }, 1096 | "node_modules/detect-libc": { 1097 | "version": "2.0.3", 1098 | "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.3.tgz", 1099 | "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", 1100 | "engines": { 1101 | "node": ">=8" 1102 | } 1103 | }, 1104 | "node_modules/emoji-mart": { 1105 | "version": "5.6.0", 1106 | "resolved": "https://registry.npmmirror.com/emoji-mart/-/emoji-mart-5.6.0.tgz", 1107 | "integrity": "sha512-eJp3QRe79pjwa+duv+n7+5YsNhRcMl812EcFVwrnRvYKoNPoQb5qxU8DG6Bgwji0akHdp6D4Ln6tYLG58MFSow==" 1108 | }, 1109 | "node_modules/enhanced-resolve": { 1110 | "version": "5.18.1", 1111 | "resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", 1112 | "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", 1113 | "dependencies": { 1114 | "graceful-fs": "^4.2.4", 1115 | "tapable": "^2.2.0" 1116 | }, 1117 | "engines": { 1118 | "node": ">=10.13.0" 1119 | } 1120 | }, 1121 | "node_modules/entities": { 1122 | "version": "4.5.0", 1123 | "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", 1124 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 1125 | "engines": { 1126 | "node": ">=0.12" 1127 | }, 1128 | "funding": { 1129 | "url": "https://github.com/fb55/entities?sponsor=1" 1130 | } 1131 | }, 1132 | "node_modules/esbuild": { 1133 | "version": "0.25.1", 1134 | "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.1.tgz", 1135 | "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", 1136 | "hasInstallScript": true, 1137 | "bin": { 1138 | "esbuild": "bin/esbuild" 1139 | }, 1140 | "engines": { 1141 | "node": ">=18" 1142 | }, 1143 | "optionalDependencies": { 1144 | "@esbuild/aix-ppc64": "0.25.1", 1145 | "@esbuild/android-arm": "0.25.1", 1146 | "@esbuild/android-arm64": "0.25.1", 1147 | "@esbuild/android-x64": "0.25.1", 1148 | "@esbuild/darwin-arm64": "0.25.1", 1149 | "@esbuild/darwin-x64": "0.25.1", 1150 | "@esbuild/freebsd-arm64": "0.25.1", 1151 | "@esbuild/freebsd-x64": "0.25.1", 1152 | "@esbuild/linux-arm": "0.25.1", 1153 | "@esbuild/linux-arm64": "0.25.1", 1154 | "@esbuild/linux-ia32": "0.25.1", 1155 | "@esbuild/linux-loong64": "0.25.1", 1156 | "@esbuild/linux-mips64el": "0.25.1", 1157 | "@esbuild/linux-ppc64": "0.25.1", 1158 | "@esbuild/linux-riscv64": "0.25.1", 1159 | "@esbuild/linux-s390x": "0.25.1", 1160 | "@esbuild/linux-x64": "0.25.1", 1161 | "@esbuild/netbsd-arm64": "0.25.1", 1162 | "@esbuild/netbsd-x64": "0.25.1", 1163 | "@esbuild/openbsd-arm64": "0.25.1", 1164 | "@esbuild/openbsd-x64": "0.25.1", 1165 | "@esbuild/sunos-x64": "0.25.1", 1166 | "@esbuild/win32-arm64": "0.25.1", 1167 | "@esbuild/win32-ia32": "0.25.1", 1168 | "@esbuild/win32-x64": "0.25.1" 1169 | } 1170 | }, 1171 | "node_modules/estree-walker": { 1172 | "version": "2.0.2", 1173 | "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", 1174 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" 1175 | }, 1176 | "node_modules/fsevents": { 1177 | "version": "2.3.3", 1178 | "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", 1179 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1180 | "hasInstallScript": true, 1181 | "optional": true, 1182 | "os": [ 1183 | "darwin" 1184 | ], 1185 | "engines": { 1186 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1187 | } 1188 | }, 1189 | "node_modules/graceful-fs": { 1190 | "version": "4.2.11", 1191 | "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz", 1192 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" 1193 | }, 1194 | "node_modules/hookable": { 1195 | "version": "5.5.3", 1196 | "resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz", 1197 | "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==" 1198 | }, 1199 | "node_modules/is-what": { 1200 | "version": "4.1.16", 1201 | "resolved": "https://registry.npmmirror.com/is-what/-/is-what-4.1.16.tgz", 1202 | "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", 1203 | "engines": { 1204 | "node": ">=12.13" 1205 | }, 1206 | "funding": { 1207 | "url": "https://github.com/sponsors/mesqueeb" 1208 | } 1209 | }, 1210 | "node_modules/jiti": { 1211 | "version": "2.4.2", 1212 | "resolved": "https://registry.npmmirror.com/jiti/-/jiti-2.4.2.tgz", 1213 | "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", 1214 | "bin": { 1215 | "jiti": "lib/jiti-cli.mjs" 1216 | } 1217 | }, 1218 | "node_modules/lightningcss": { 1219 | "version": "1.29.2", 1220 | "resolved": "https://registry.npmmirror.com/lightningcss/-/lightningcss-1.29.2.tgz", 1221 | "integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==", 1222 | "dependencies": { 1223 | "detect-libc": "^2.0.3" 1224 | }, 1225 | "engines": { 1226 | "node": ">= 12.0.0" 1227 | }, 1228 | "funding": { 1229 | "type": "opencollective", 1230 | "url": "https://opencollective.com/parcel" 1231 | }, 1232 | "optionalDependencies": { 1233 | "lightningcss-darwin-arm64": "1.29.2", 1234 | "lightningcss-darwin-x64": "1.29.2", 1235 | "lightningcss-freebsd-x64": "1.29.2", 1236 | "lightningcss-linux-arm-gnueabihf": "1.29.2", 1237 | "lightningcss-linux-arm64-gnu": "1.29.2", 1238 | "lightningcss-linux-arm64-musl": "1.29.2", 1239 | "lightningcss-linux-x64-gnu": "1.29.2", 1240 | "lightningcss-linux-x64-musl": "1.29.2", 1241 | "lightningcss-win32-arm64-msvc": "1.29.2", 1242 | "lightningcss-win32-x64-msvc": "1.29.2" 1243 | } 1244 | }, 1245 | "node_modules/lightningcss-darwin-arm64": { 1246 | "version": "1.29.2", 1247 | "resolved": "https://registry.npmmirror.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz", 1248 | "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==", 1249 | "cpu": [ 1250 | "arm64" 1251 | ], 1252 | "optional": true, 1253 | "os": [ 1254 | "darwin" 1255 | ], 1256 | "engines": { 1257 | "node": ">= 12.0.0" 1258 | }, 1259 | "funding": { 1260 | "type": "opencollective", 1261 | "url": "https://opencollective.com/parcel" 1262 | } 1263 | }, 1264 | "node_modules/lightningcss-darwin-x64": { 1265 | "version": "1.29.2", 1266 | "resolved": "https://registry.npmmirror.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz", 1267 | "integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==", 1268 | "cpu": [ 1269 | "x64" 1270 | ], 1271 | "optional": true, 1272 | "os": [ 1273 | "darwin" 1274 | ], 1275 | "engines": { 1276 | "node": ">= 12.0.0" 1277 | }, 1278 | "funding": { 1279 | "type": "opencollective", 1280 | "url": "https://opencollective.com/parcel" 1281 | } 1282 | }, 1283 | "node_modules/lightningcss-freebsd-x64": { 1284 | "version": "1.29.2", 1285 | "resolved": "https://registry.npmmirror.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz", 1286 | "integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==", 1287 | "cpu": [ 1288 | "x64" 1289 | ], 1290 | "optional": true, 1291 | "os": [ 1292 | "freebsd" 1293 | ], 1294 | "engines": { 1295 | "node": ">= 12.0.0" 1296 | }, 1297 | "funding": { 1298 | "type": "opencollective", 1299 | "url": "https://opencollective.com/parcel" 1300 | } 1301 | }, 1302 | "node_modules/lightningcss-linux-arm-gnueabihf": { 1303 | "version": "1.29.2", 1304 | "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz", 1305 | "integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==", 1306 | "cpu": [ 1307 | "arm" 1308 | ], 1309 | "optional": true, 1310 | "os": [ 1311 | "linux" 1312 | ], 1313 | "engines": { 1314 | "node": ">= 12.0.0" 1315 | }, 1316 | "funding": { 1317 | "type": "opencollective", 1318 | "url": "https://opencollective.com/parcel" 1319 | } 1320 | }, 1321 | "node_modules/lightningcss-linux-arm64-gnu": { 1322 | "version": "1.29.2", 1323 | "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz", 1324 | "integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==", 1325 | "cpu": [ 1326 | "arm64" 1327 | ], 1328 | "optional": true, 1329 | "os": [ 1330 | "linux" 1331 | ], 1332 | "engines": { 1333 | "node": ">= 12.0.0" 1334 | }, 1335 | "funding": { 1336 | "type": "opencollective", 1337 | "url": "https://opencollective.com/parcel" 1338 | } 1339 | }, 1340 | "node_modules/lightningcss-linux-arm64-musl": { 1341 | "version": "1.29.2", 1342 | "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz", 1343 | "integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==", 1344 | "cpu": [ 1345 | "arm64" 1346 | ], 1347 | "optional": true, 1348 | "os": [ 1349 | "linux" 1350 | ], 1351 | "engines": { 1352 | "node": ">= 12.0.0" 1353 | }, 1354 | "funding": { 1355 | "type": "opencollective", 1356 | "url": "https://opencollective.com/parcel" 1357 | } 1358 | }, 1359 | "node_modules/lightningcss-linux-x64-gnu": { 1360 | "version": "1.29.2", 1361 | "resolved": "https://registry.npmmirror.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz", 1362 | "integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==", 1363 | "cpu": [ 1364 | "x64" 1365 | ], 1366 | "optional": true, 1367 | "os": [ 1368 | "linux" 1369 | ], 1370 | "engines": { 1371 | "node": ">= 12.0.0" 1372 | }, 1373 | "funding": { 1374 | "type": "opencollective", 1375 | "url": "https://opencollective.com/parcel" 1376 | } 1377 | }, 1378 | "node_modules/lightningcss-linux-x64-musl": { 1379 | "version": "1.29.2", 1380 | "resolved": "https://registry.npmmirror.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz", 1381 | "integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==", 1382 | "cpu": [ 1383 | "x64" 1384 | ], 1385 | "optional": true, 1386 | "os": [ 1387 | "linux" 1388 | ], 1389 | "engines": { 1390 | "node": ">= 12.0.0" 1391 | }, 1392 | "funding": { 1393 | "type": "opencollective", 1394 | "url": "https://opencollective.com/parcel" 1395 | } 1396 | }, 1397 | "node_modules/lightningcss-win32-arm64-msvc": { 1398 | "version": "1.29.2", 1399 | "resolved": "https://registry.npmmirror.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz", 1400 | "integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==", 1401 | "cpu": [ 1402 | "arm64" 1403 | ], 1404 | "optional": true, 1405 | "os": [ 1406 | "win32" 1407 | ], 1408 | "engines": { 1409 | "node": ">= 12.0.0" 1410 | }, 1411 | "funding": { 1412 | "type": "opencollective", 1413 | "url": "https://opencollective.com/parcel" 1414 | } 1415 | }, 1416 | "node_modules/lightningcss-win32-x64-msvc": { 1417 | "version": "1.29.2", 1418 | "resolved": "https://registry.npmmirror.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz", 1419 | "integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==", 1420 | "cpu": [ 1421 | "x64" 1422 | ], 1423 | "optional": true, 1424 | "os": [ 1425 | "win32" 1426 | ], 1427 | "engines": { 1428 | "node": ">= 12.0.0" 1429 | }, 1430 | "funding": { 1431 | "type": "opencollective", 1432 | "url": "https://opencollective.com/parcel" 1433 | } 1434 | }, 1435 | "node_modules/magic-string": { 1436 | "version": "0.30.17", 1437 | "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz", 1438 | "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", 1439 | "dependencies": { 1440 | "@jridgewell/sourcemap-codec": "^1.5.0" 1441 | } 1442 | }, 1443 | "node_modules/mitt": { 1444 | "version": "3.0.1", 1445 | "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz", 1446 | "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" 1447 | }, 1448 | "node_modules/nanoid": { 1449 | "version": "3.3.9", 1450 | "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.9.tgz", 1451 | "integrity": "sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==", 1452 | "funding": [ 1453 | { 1454 | "type": "github", 1455 | "url": "https://github.com/sponsors/ai" 1456 | } 1457 | ], 1458 | "bin": { 1459 | "nanoid": "bin/nanoid.cjs" 1460 | }, 1461 | "engines": { 1462 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1463 | } 1464 | }, 1465 | "node_modules/perfect-debounce": { 1466 | "version": "1.0.0", 1467 | "resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz", 1468 | "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==" 1469 | }, 1470 | "node_modules/picocolors": { 1471 | "version": "1.1.1", 1472 | "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", 1473 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" 1474 | }, 1475 | "node_modules/pinia": { 1476 | "version": "3.0.1", 1477 | "resolved": "https://registry.npmmirror.com/pinia/-/pinia-3.0.1.tgz", 1478 | "integrity": "sha512-WXglsDzztOTH6IfcJ99ltYZin2mY8XZCXujkYWVIJlBjqsP6ST7zw+Aarh63E1cDVYeyUcPCxPHzJpEOmzB6Wg==", 1479 | "dependencies": { 1480 | "@vue/devtools-api": "^7.7.2" 1481 | }, 1482 | "funding": { 1483 | "url": "https://github.com/sponsors/posva" 1484 | }, 1485 | "peerDependencies": { 1486 | "typescript": ">=4.4.4", 1487 | "vue": "^2.7.0 || ^3.5.11" 1488 | }, 1489 | "peerDependenciesMeta": { 1490 | "typescript": { 1491 | "optional": true 1492 | } 1493 | } 1494 | }, 1495 | "node_modules/postcss": { 1496 | "version": "8.5.3", 1497 | "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.3.tgz", 1498 | "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", 1499 | "funding": [ 1500 | { 1501 | "type": "opencollective", 1502 | "url": "https://opencollective.com/postcss/" 1503 | }, 1504 | { 1505 | "type": "tidelift", 1506 | "url": "https://tidelift.com/funding/github/npm/postcss" 1507 | }, 1508 | { 1509 | "type": "github", 1510 | "url": "https://github.com/sponsors/ai" 1511 | } 1512 | ], 1513 | "dependencies": { 1514 | "nanoid": "^3.3.8", 1515 | "picocolors": "^1.1.1", 1516 | "source-map-js": "^1.2.1" 1517 | }, 1518 | "engines": { 1519 | "node": "^10 || ^12 || >=14" 1520 | } 1521 | }, 1522 | "node_modules/rfdc": { 1523 | "version": "1.4.1", 1524 | "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz", 1525 | "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" 1526 | }, 1527 | "node_modules/rollup": { 1528 | "version": "4.35.0", 1529 | "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.35.0.tgz", 1530 | "integrity": "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==", 1531 | "dependencies": { 1532 | "@types/estree": "1.0.6" 1533 | }, 1534 | "bin": { 1535 | "rollup": "dist/bin/rollup" 1536 | }, 1537 | "engines": { 1538 | "node": ">=18.0.0", 1539 | "npm": ">=8.0.0" 1540 | }, 1541 | "optionalDependencies": { 1542 | "@rollup/rollup-android-arm-eabi": "4.35.0", 1543 | "@rollup/rollup-android-arm64": "4.35.0", 1544 | "@rollup/rollup-darwin-arm64": "4.35.0", 1545 | "@rollup/rollup-darwin-x64": "4.35.0", 1546 | "@rollup/rollup-freebsd-arm64": "4.35.0", 1547 | "@rollup/rollup-freebsd-x64": "4.35.0", 1548 | "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", 1549 | "@rollup/rollup-linux-arm-musleabihf": "4.35.0", 1550 | "@rollup/rollup-linux-arm64-gnu": "4.35.0", 1551 | "@rollup/rollup-linux-arm64-musl": "4.35.0", 1552 | "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", 1553 | "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", 1554 | "@rollup/rollup-linux-riscv64-gnu": "4.35.0", 1555 | "@rollup/rollup-linux-s390x-gnu": "4.35.0", 1556 | "@rollup/rollup-linux-x64-gnu": "4.35.0", 1557 | "@rollup/rollup-linux-x64-musl": "4.35.0", 1558 | "@rollup/rollup-win32-arm64-msvc": "4.35.0", 1559 | "@rollup/rollup-win32-ia32-msvc": "4.35.0", 1560 | "@rollup/rollup-win32-x64-msvc": "4.35.0", 1561 | "fsevents": "~2.3.2" 1562 | } 1563 | }, 1564 | "node_modules/source-map-js": { 1565 | "version": "1.2.1", 1566 | "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", 1567 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 1568 | "engines": { 1569 | "node": ">=0.10.0" 1570 | } 1571 | }, 1572 | "node_modules/speakingurl": { 1573 | "version": "14.0.1", 1574 | "resolved": "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz", 1575 | "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", 1576 | "engines": { 1577 | "node": ">=0.10.0" 1578 | } 1579 | }, 1580 | "node_modules/superjson": { 1581 | "version": "2.2.2", 1582 | "resolved": "https://registry.npmmirror.com/superjson/-/superjson-2.2.2.tgz", 1583 | "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", 1584 | "dependencies": { 1585 | "copy-anything": "^3.0.2" 1586 | }, 1587 | "engines": { 1588 | "node": ">=16" 1589 | } 1590 | }, 1591 | "node_modules/tailwindcss": { 1592 | "version": "4.0.12", 1593 | "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-4.0.12.tgz", 1594 | "integrity": "sha512-bT0hJo91FtncsAMSsMzUkoo/iEU0Xs5xgFgVC9XmdM9bw5MhZuQFjPNl6wxAE0SiQF/YTZJa+PndGWYSDtuxAg==" 1595 | }, 1596 | "node_modules/tapable": { 1597 | "version": "2.2.1", 1598 | "resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz", 1599 | "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", 1600 | "engines": { 1601 | "node": ">=6" 1602 | } 1603 | }, 1604 | "node_modules/vite": { 1605 | "version": "6.2.1", 1606 | "resolved": "https://registry.npmmirror.com/vite/-/vite-6.2.1.tgz", 1607 | "integrity": "sha512-n2GnqDb6XPhlt9B8olZPrgMD/es/Nd1RdChF6CBD/fHW6pUyUTt2sQW2fPRX5GiD9XEa6+8A6A4f2vT6pSsE7Q==", 1608 | "dependencies": { 1609 | "esbuild": "^0.25.0", 1610 | "postcss": "^8.5.3", 1611 | "rollup": "^4.30.1" 1612 | }, 1613 | "bin": { 1614 | "vite": "bin/vite.js" 1615 | }, 1616 | "engines": { 1617 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 1618 | }, 1619 | "funding": { 1620 | "url": "https://github.com/vitejs/vite?sponsor=1" 1621 | }, 1622 | "optionalDependencies": { 1623 | "fsevents": "~2.3.3" 1624 | }, 1625 | "peerDependencies": { 1626 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", 1627 | "jiti": ">=1.21.0", 1628 | "less": "*", 1629 | "lightningcss": "^1.21.0", 1630 | "sass": "*", 1631 | "sass-embedded": "*", 1632 | "stylus": "*", 1633 | "sugarss": "*", 1634 | "terser": "^5.16.0", 1635 | "tsx": "^4.8.1", 1636 | "yaml": "^2.4.2" 1637 | }, 1638 | "peerDependenciesMeta": { 1639 | "@types/node": { 1640 | "optional": true 1641 | }, 1642 | "jiti": { 1643 | "optional": true 1644 | }, 1645 | "less": { 1646 | "optional": true 1647 | }, 1648 | "lightningcss": { 1649 | "optional": true 1650 | }, 1651 | "sass": { 1652 | "optional": true 1653 | }, 1654 | "sass-embedded": { 1655 | "optional": true 1656 | }, 1657 | "stylus": { 1658 | "optional": true 1659 | }, 1660 | "sugarss": { 1661 | "optional": true 1662 | }, 1663 | "terser": { 1664 | "optional": true 1665 | }, 1666 | "tsx": { 1667 | "optional": true 1668 | }, 1669 | "yaml": { 1670 | "optional": true 1671 | } 1672 | } 1673 | }, 1674 | "node_modules/vue": { 1675 | "version": "3.5.13", 1676 | "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.13.tgz", 1677 | "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", 1678 | "dependencies": { 1679 | "@vue/compiler-dom": "3.5.13", 1680 | "@vue/compiler-sfc": "3.5.13", 1681 | "@vue/runtime-dom": "3.5.13", 1682 | "@vue/server-renderer": "3.5.13", 1683 | "@vue/shared": "3.5.13" 1684 | }, 1685 | "peerDependencies": { 1686 | "typescript": "*" 1687 | }, 1688 | "peerDependenciesMeta": { 1689 | "typescript": { 1690 | "optional": true 1691 | } 1692 | } 1693 | }, 1694 | "node_modules/vue-i18n": { 1695 | "version": "9.14.3", 1696 | "resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.14.3.tgz", 1697 | "integrity": "sha512-C+E0KE8ihKjdYCQx8oUkXX+8tBItrYNMnGJuzEPevBARQFUN2tKez6ZVOvBrWH0+KT5wEk3vOWjNk7ygb2u9ig==", 1698 | "dependencies": { 1699 | "@intlify/core-base": "9.14.3", 1700 | "@intlify/shared": "9.14.3", 1701 | "@vue/devtools-api": "^6.5.0" 1702 | }, 1703 | "engines": { 1704 | "node": ">= 16" 1705 | }, 1706 | "funding": { 1707 | "url": "https://github.com/sponsors/kazupon" 1708 | }, 1709 | "peerDependencies": { 1710 | "vue": "^3.0.0" 1711 | } 1712 | }, 1713 | "node_modules/vue-i18n/node_modules/@vue/devtools-api": { 1714 | "version": "6.6.4", 1715 | "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", 1716 | "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" 1717 | } 1718 | } 1719 | } 1720 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hidden-word", 3 | "private": true, 4 | "version": "1.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@emoji-mart/data": "^1.2.1", 13 | "@tailwindcss/vite": "^4.0.12", 14 | "emoji-mart": "^5.6.0", 15 | "pinia": "^3.0.1", 16 | "tailwindcss": "^4.0.12", 17 | "vue": "^3.5.13", 18 | "vue-i18n": "^9.14.3" 19 | }, 20 | "devDependencies": { 21 | "@vitejs/plugin-vue": "^5.2.1", 22 | "vite": "^6.2.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /src/assets/styles/styles.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | /* 自定义滚动条样式 */ 4 | ::-webkit-scrollbar { 5 | width: 8px; 6 | height: 8px; 7 | } 8 | 9 | ::-webkit-scrollbar-track { 10 | background: #f1f5f9; 11 | border-radius: 10px; 12 | } 13 | 14 | ::-webkit-scrollbar-thumb { 15 | background: #cbd5e1; 16 | border-radius: 10px; 17 | } 18 | 19 | ::-webkit-scrollbar-thumb:hover { 20 | background: #94a3b8; 21 | } 22 | 23 | /* 确保Firefox也有自定义滚动条 */ 24 | * { 25 | scrollbar-width: thin; 26 | scrollbar-color: #cbd5e1 #f1f5f9; 27 | } 28 | -------------------------------------------------------------------------------- /src/components/CleanHiddenTextButton.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 44 | -------------------------------------------------------------------------------- /src/components/ClearableTextarea.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 61 | -------------------------------------------------------------------------------- /src/components/CopyButton.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 56 | -------------------------------------------------------------------------------- /src/components/EmojiSelector.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 41 | -------------------------------------------------------------------------------- /src/components/LanguageSelector.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 48 | -------------------------------------------------------------------------------- /src/components/TextSelector.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 27 | -------------------------------------------------------------------------------- /src/composables/useCursorPosition.js: -------------------------------------------------------------------------------- 1 | import {nextTick} from 'vue'; 2 | import {useAppStore} from '@/store/index.js'; 3 | 4 | /** 5 | * 用于管理文本输入区域的光标位置和文本插入功能的组合式函数 6 | * @param {Object} options 配置选项 7 | * @param {string} [options.selector] 用于选择textarea元素的CSS选择器,默认为'.carrierTextarea textarea' 8 | * @param {Object} [options.modelValue] defineModel返回的响应式对象 9 | * @param {Function} [options.onPositionChange] 可选的光标位置变化回调函数 10 | * @returns {Object} 包含光标位置状态和处理方法的对象 11 | */ 12 | export function useCursorPosition(options) { 13 | const {selector = '.carrierTextarea textarea', modelValue, onPositionChange} = options || {}; 14 | const store = useAppStore(); 15 | 16 | const textareaRef = { 17 | get value() { 18 | return document.querySelector(selector); 19 | } 20 | }; 21 | 22 | const handleTextareaSelect = (event) => { 23 | const newPosition = { 24 | start: event.target.selectionStart, 25 | end: event.target.selectionEnd 26 | }; 27 | 28 | store.updateCursorPosition(newPosition); 29 | 30 | if (onPositionChange) { 31 | onPositionChange(newPosition); 32 | } 33 | }; 34 | 35 | const getCurrentText = () => { 36 | if (modelValue !== undefined) { 37 | return modelValue.value; 38 | } 39 | return store.carrierText; 40 | }; 41 | 42 | const updateCurrentText = (newText) => { 43 | if (modelValue !== undefined) { 44 | modelValue.value = newText; 45 | return; 46 | } 47 | store.updateCarrierText(newText); 48 | }; 49 | 50 | const insertTextAtCursor = (text) => { 51 | const currentText = getCurrentText(); 52 | const position = store.cursorPositions; 53 | const textarea = textareaRef.value; 54 | 55 | if (position.start !== undefined && position.end !== undefined) { 56 | const before = currentText.substring(0, position.start); 57 | const after = currentText.substring(position.end); 58 | updateCurrentText(before + text + after); 59 | 60 | const newPosition = position.start + text.length; 61 | 62 | store.updateCursorPosition({ 63 | start: newPosition, 64 | end: newPosition 65 | }); 66 | 67 | nextTick(() => { 68 | if (textarea && typeof textarea.focus === 'function' && typeof textarea.setSelectionRange === 'function') { 69 | textarea.focus(); 70 | textarea.setSelectionRange(newPosition, newPosition); 71 | } 72 | }); 73 | } else { 74 | updateCurrentText(currentText + text); 75 | 76 | nextTick(() => { 77 | const newPosition = currentText.length + text.length; 78 | if (textarea && typeof textarea.focus === 'function' && typeof textarea.setSelectionRange === 'function') { 79 | textarea.focus(); 80 | textarea.setSelectionRange(newPosition, newPosition); 81 | } 82 | }); 83 | } 84 | }; 85 | 86 | return { 87 | textareaRef, 88 | handleTextareaSelect, 89 | insertTextAtCursor 90 | }; 91 | } 92 | -------------------------------------------------------------------------------- /src/i18n/index.js: -------------------------------------------------------------------------------- 1 | import {createI18n} from 'vue-i18n'; 2 | import zh from './locales/zh.js'; 3 | import en from './locales/en.js'; 4 | 5 | const i18n = createI18n({ 6 | legacy: false, // 使用组合式API 7 | locale: localStorage.getItem('locale') || 'zh', // 默认语言 8 | fallbackLocale: 'zh', // 回退语言 9 | messages: { 10 | zh, 11 | en 12 | } 13 | }); 14 | 15 | export default i18n; 16 | -------------------------------------------------------------------------------- /src/i18n/locales/en.js: -------------------------------------------------------------------------------- 1 | export default { 2 | appTitle: 'Hidden Word', 3 | appDescription: 'Hide secret messages in plain text', 4 | mode: { 5 | decode: 'Decode', 6 | encode: 'Encode' 7 | }, 8 | carrier: { 9 | title: 'Original Text', 10 | placeholder: 'Enter or select preset text', 11 | presets: 'Preset Text' 12 | }, 13 | emoji: { 14 | title: 'Select Emoji', 15 | alphabet: 'Or Select Alphabet' 16 | }, 17 | input: { 18 | encodeTitle: 'Text to Hide', 19 | decodeTitle: 'Text with Hidden Message', 20 | encodePlaceholder: 'Enter text to hide', 21 | decodePlaceholder: 'Paste text with hidden message' 22 | }, 23 | output: { 24 | encodeTitle: 'Encoding Result', 25 | decodeTitle: 'Decoding Result', 26 | placeholder: 'Result will be displayed here' 27 | }, 28 | error: { 29 | encode: 'Encoding error: Invalid input', 30 | decode: 'Decoding error: Invalid input' 31 | }, 32 | copy: { 33 | default: 'Copy', 34 | success: 'Copied!' 35 | }, 36 | clean: { 37 | default: 'Clean Hidden Text', 38 | success: 'Cleaned!' 39 | }, 40 | footer: { 41 | description: 'Hidden Text Tool - Hide secret messages in plain text' 42 | }, 43 | language: { 44 | title: 'Language', 45 | zh: 'Chinese', 46 | en: 'English' 47 | }, 48 | embed: { 49 | title: 'Embed Code', 50 | description: 'Embed this code into your website to automatically encrypt all text content.', 51 | usingInputText: 'Using content from "Text to Hide" as the hidden text in embed code' 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /src/i18n/locales/zh.js: -------------------------------------------------------------------------------- 1 | export default { 2 | appTitle: 'Hidden Word', 3 | appDescription: '将秘密信息隐藏在普通文本中', 4 | mode: { 5 | decode: '解码', 6 | encode: '编码' 7 | }, 8 | carrier: { 9 | title: '原始文本', 10 | placeholder: '输入或选择预设文本', 11 | presets: '预设文本' 12 | }, 13 | emoji: { 14 | title: '选择表情', 15 | alphabet: '或选择字母' 16 | }, 17 | input: { 18 | encodeTitle: '要隐藏的文本', 19 | decodeTitle: '包含隐藏信息的文本', 20 | encodePlaceholder: '输入要隐藏的文本', 21 | decodePlaceholder: '粘贴包含隐藏信息的文本' 22 | }, 23 | output: { 24 | encodeTitle: '编码结果', 25 | decodeTitle: '解码结果', 26 | placeholder: '结果将显示在这里' 27 | }, 28 | error: { 29 | encode: '编码错误: 无效输入', 30 | decode: '解码错误: 无效输入' 31 | }, 32 | copy: { 33 | default: '复制', 34 | success: '已复制!' 35 | }, 36 | clean: { 37 | default: '清除隐藏文本', 38 | success: '已清除!' 39 | }, 40 | footer: { 41 | description: '隐藏文字工具 - 将秘密信息隐藏在普通文本中' 42 | }, 43 | language: { 44 | title: '语言', 45 | zh: '中文', 46 | en: '英文' 47 | }, 48 | embed: { 49 | title: '嵌入代码', 50 | description: '将此代码嵌入到您的网站中,可以自动加密网站上的所有文本内容。', 51 | usingInputText: '使用"要隐藏的文本"中的内容作为嵌入代码的隐藏文本' 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import {createApp} from 'vue' 2 | import {createPinia} from 'pinia' 3 | import App from './App.vue' 4 | import './assets/styles/styles.css' 5 | import i18n from './i18n' 6 | 7 | const app = createApp(App) 8 | const pinia = createPinia() 9 | 10 | app.use(pinia) 11 | app.use(i18n) 12 | app.mount('#app') 13 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import {defineStore} from 'pinia'; 2 | import {computed, ref, watch} from 'vue'; 3 | import {decode, encode} from '../utils/encoding.js'; 4 | import {useI18n} from 'vue-i18n'; 5 | 6 | /** 7 | * 主应用状态存储 8 | */ 9 | export const useAppStore = defineStore('app', () => { 10 | // 状态 11 | const mode = ref('encode'); // encode 或 decode 12 | const inputText = ref(''); 13 | const carrierText = ref(''); // 载体文本 14 | const outputText = ref(''); 15 | const errorText = ref(''); 16 | const {t} = useI18n(); 17 | 18 | // 光标位置状态 19 | const cursorPositions = ref({ 20 | start: 0, 21 | end: 0, 22 | }); 23 | 24 | const isEncoding = computed(() => mode.value === 'encode'); 25 | 26 | function toggleMode() { 27 | mode.value = isEncoding.value ? 'decode' : 'encode'; 28 | inputText.value = ''; 29 | outputText.value = ''; 30 | errorText.value = ''; 31 | } 32 | 33 | watch([mode, inputText, carrierText], () => { 34 | try { 35 | if (isEncoding.value) { 36 | if (inputText.value && carrierText.value) { 37 | outputText.value = encode(inputText.value, carrierText.value); 38 | } else { 39 | outputText.value = ''; 40 | } 41 | } else { 42 | if (inputText.value) { 43 | outputText.value = decode(inputText.value); 44 | } else { 45 | outputText.value = ''; 46 | } 47 | } 48 | errorText.value = ''; 49 | } catch (e) { 50 | outputText.value = ''; 51 | errorText.value = isEncoding.value ? t('error.encode') : t('error.decode'); 52 | } 53 | }); 54 | 55 | function updateCursorPosition(newPosition) { 56 | cursorPositions.value.start = newPosition.start; 57 | cursorPositions.value.end = newPosition.end; 58 | } 59 | 60 | function updateCarrierText(newText) { 61 | carrierText.value = newText; 62 | } 63 | 64 | return { 65 | mode, 66 | inputText, 67 | carrierText, 68 | outputText, 69 | errorText, 70 | cursorPositions, 71 | isEncoding, 72 | toggleMode, 73 | updateCursorPosition, 74 | updateCarrierText 75 | }; 76 | }); 77 | -------------------------------------------------------------------------------- /src/utils/cleanText.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 清除文本中的隐藏内容(变体选择器) 3 | * @param {string} text - 包含隐藏内容的文本 4 | * @returns {string} - 清除隐藏内容后的文本 5 | */ 6 | export function cleanHiddenText(text) { 7 | if (!text) return ''; 8 | 9 | const VARIATION_SELECTOR_START = 0xfe00; 10 | const VARIATION_SELECTOR_END = 0xfe0f; 11 | const VARIATION_SELECTOR_SUPPLEMENT_START = 0xe0100; 12 | const VARIATION_SELECTOR_SUPPLEMENT_END = 0xe01ef; 13 | 14 | const chars = Array.from(text); 15 | let result = ''; 16 | 17 | for (let i = 0; i < chars.length; i++) { 18 | const char = chars[i]; 19 | const codePoint = char.codePointAt(0); 20 | 21 | // 添加非变体选择器字符到结果中 22 | if (!( 23 | (codePoint >= VARIATION_SELECTOR_START && codePoint <= VARIATION_SELECTOR_END) || 24 | (codePoint >= VARIATION_SELECTOR_SUPPLEMENT_START && codePoint <= VARIATION_SELECTOR_SUPPLEMENT_END) 25 | )) { 26 | result += char; 27 | } 28 | } 29 | 30 | return result; 31 | } -------------------------------------------------------------------------------- /src/utils/embedCode.js: -------------------------------------------------------------------------------- 1 | export function generateEmbedCode(customMessage = 'Hidden Word 已加密此内容') { 2 | // 压缩后的基本代码 3 | const code = `(function(){const a=0xfe00,b=0xfe0f,c=0xe0100,d=0xe01ef;function e(n){return n>=0&&n<16?String.fromCodePoint(a+n):n>=16&&n<256?String.fromCodePoint(c+n-16):null}function f(n){return n>=a&&n<=b?n-a:n>=c&&n<=d?n-c+16:null}function g(t,h){const i=new TextEncoder().encode(t);if(!h||h.length===0)h="A";const j=Array.from(h);let k="";if(i.length<=j.length){const l=[];for(let m=0;m0;m--){const n=Math.floor(Math.random()*(m+1));[l[m],l[n]]=[l[n],l[m]]}const o=l.slice(0,i.length);o.sort((a,b)=>a-b);let p=0;for(let m=0;m{const x=v.nodeValue;if(x.trim().length>0)v.nodeValue=g(s,x)})}document.readyState==='loading'?document.addEventListener('DOMContentLoaded',r):r();`; 7 | 8 | return code + autoEncryptFunction + '})();'; 9 | } 10 | 11 | export function generateHtmlSnippet(customMessage = 'Hidden Word 已加密此内容') { 12 | const jsCode = generateEmbedCode(customMessage); 13 | return ``; 14 | } -------------------------------------------------------------------------------- /src/utils/emoji.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 可用于编码的表情列表 3 | */ 4 | export const EMOJI_LIST = [ 5 | "😀", 6 | "😂", 7 | "🥰", 8 | "😎", 9 | "🤔", 10 | "👍", 11 | "👎", 12 | "👏", 13 | "😅", 14 | "🤝", 15 | "🎉", 16 | "🎂", 17 | "🍕", 18 | "🌈", 19 | "🌞", 20 | "🌙", 21 | "🔥", 22 | "💯", 23 | "🚀", 24 | "👀", 25 | "💀", 26 | "🥹", 27 | "...", 28 | ]; 29 | 30 | /** 31 | * 可用于编码的字母列表 32 | */ 33 | export const ALPHABET_LIST = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; 34 | 35 | /** 36 | * 常用的载体文本列表 37 | */ 38 | export const CARRIER_TEXT_LIST = [ 39 | "你好,世界", 40 | "Hello World", 41 | "这是一段普通文本", 42 | "This is a normal text", 43 | "隐藏信息的艺术", 44 | "The art of hiding information", 45 | ]; -------------------------------------------------------------------------------- /src/utils/encoding.js: -------------------------------------------------------------------------------- 1 | const VARIATION_SELECTOR_START = 0xfe00; 2 | const VARIATION_SELECTOR_END = 0xfe0f; 3 | 4 | const VARIATION_SELECTOR_SUPPLEMENT_START = 0xe0100; 5 | const VARIATION_SELECTOR_SUPPLEMENT_END = 0xe01ef; 6 | 7 | /** 8 | * 将字节转换为变体选择器 9 | * @param {number} byte - 要转换的字节 10 | * @returns {string|null} - 变体选择器字符或null 11 | */ 12 | export function toVariationSelector(byte) { 13 | if (byte >= 0 && byte < 16) { 14 | return String.fromCodePoint(VARIATION_SELECTOR_START + byte); 15 | } else if (byte >= 16 && byte < 256) { 16 | return String.fromCodePoint(VARIATION_SELECTOR_SUPPLEMENT_START + byte - 16); 17 | } else { 18 | return null; 19 | } 20 | } 21 | 22 | /** 23 | * 从变体选择器转换为字节 24 | * @param {number} codePoint - 变体选择器的码点 25 | * @returns {number|null} - 字节或null 26 | */ 27 | export function fromVariationSelector(codePoint) { 28 | if (codePoint >= VARIATION_SELECTOR_START && codePoint <= VARIATION_SELECTOR_END) { 29 | return codePoint - VARIATION_SELECTOR_START; 30 | } else if ( 31 | codePoint >= VARIATION_SELECTOR_SUPPLEMENT_START && 32 | codePoint <= VARIATION_SELECTOR_SUPPLEMENT_END 33 | ) { 34 | return codePoint - VARIATION_SELECTOR_SUPPLEMENT_START + 16; 35 | } else { 36 | return null; 37 | } 38 | } 39 | 40 | /** 41 | * 将文本编码到一段文本中 42 | * @param {string} text - 要隐藏的文本 43 | * @param {string} carrier - 承载隐藏文本的文本 44 | * @returns {string} - 编码后的文本 45 | */ 46 | export function encode(text, carrier) { 47 | // 将字符串转换为utf-8字节 48 | const bytes = new TextEncoder().encode(text); 49 | 50 | // 如果carrier是空字符串,使用默认字符 51 | if (!carrier || carrier.length === 0) { 52 | carrier = "A"; 53 | } 54 | 55 | // 将字节分布到carrier的每个字符中 56 | const carrierChars = Array.from(carrier); 57 | let result = ""; 58 | 59 | // 如果隐藏文字字节少于载体文本,使用随机算法分散 60 | if (bytes.length <= carrierChars.length) { 61 | // 创建一个随机位置数组,用于随机分布字节 62 | const positions = []; 63 | for (let i = 0; i < carrierChars.length; i++) { 64 | positions.push(i); 65 | } 66 | 67 | // 随机打乱位置数组 68 | for (let i = positions.length - 1; i > 0; i--) { 69 | const j = Math.floor(Math.random() * (i + 1)); 70 | [positions[i], positions[j]] = [positions[j], positions[i]]; 71 | } 72 | 73 | // 选择前bytes.length个位置用于插入变体选择器 74 | const selectedPositions = positions.slice(0, bytes.length); 75 | selectedPositions.sort((a, b) => a - b); // 重新排序,以便按顺序处理 76 | 77 | // 构建结果字符串,在选定的位置插入变体选择器 78 | let byteIndex = 0; 79 | for (let i = 0; i < carrierChars.length; i++) { 80 | console.log(result); 81 | result += carrierChars[i]; 82 | 83 | // 检查当前位置是否是选定的位置之一 84 | if (selectedPositions.includes(i) && byteIndex < bytes.length) { 85 | const selector = toVariationSelector(bytes[byteIndex]); 86 | if (selector) { 87 | result += selector; 88 | } 89 | byteIndex++; 90 | } 91 | } 92 | } else { 93 | // 如果隐藏文字字节多于载体文本,将多余的字节叠加到最后一个字符 94 | let byteIndex = 0; 95 | 96 | // 先处理能均匀分配到载体字符的字节 97 | for (let i = 0; i < carrierChars.length; i++) { 98 | result += carrierChars[i]; 99 | 100 | // 如果还有字节需要处理 101 | if (byteIndex < bytes.length) { 102 | const selector = toVariationSelector(bytes[byteIndex]); 103 | if (selector) { 104 | result += selector; 105 | } 106 | byteIndex++; 107 | } 108 | } 109 | 110 | // 将剩余的字节全部叠加到最后一个字符 111 | while (byteIndex < bytes.length) { 112 | const selector = toVariationSelector(bytes[byteIndex]); 113 | if (selector) { 114 | result += selector; 115 | } 116 | byteIndex++; 117 | } 118 | } 119 | 120 | return result; 121 | } 122 | 123 | /** 124 | * 从编码文本中解码隐藏的文本 125 | * @param {string} encodedText - 编码后的文本 126 | * @returns {string} - 解码后的文本 127 | */ 128 | export function decode(encodedText) { 129 | const decoded = []; 130 | const chars = Array.from(encodedText); 131 | 132 | // 遍历每个字符,检查其后是否有变体选择器 133 | for (let i = 0; i < chars.length; i++) { 134 | // 检查当前字符后的所有连续变体选择器 135 | while (i + 1 < chars.length) { 136 | const nextChar = chars[i + 1]; 137 | const byte = fromVariationSelector(nextChar.codePointAt(0)); 138 | 139 | if (byte !== null) { 140 | decoded.push(byte); 141 | i++; // 跳过已处理的变体选择器 142 | } else { 143 | break; // 如果不是变体选择器,退出内部循环 144 | } 145 | } 146 | } 147 | 148 | // 将字节数组转换回字符串 149 | const decodedArray = new Uint8Array(decoded); 150 | return new TextDecoder().decode(decodedArray); 151 | } 152 | -------------------------------------------------------------------------------- /src/views/components/CarrierTextPanel.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 46 | -------------------------------------------------------------------------------- /src/views/components/EmbedCodePanel.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 68 | -------------------------------------------------------------------------------- /src/views/components/EmojiPanel.vue: -------------------------------------------------------------------------------- 1 | 78 | 79 | 117 | -------------------------------------------------------------------------------- /src/views/components/FooterSection.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 71 | -------------------------------------------------------------------------------- /src/views/components/InputPanel.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 42 | -------------------------------------------------------------------------------- /src/views/components/ModeToggle.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 42 | -------------------------------------------------------------------------------- /src/views/components/OutputPanel.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 50 | -------------------------------------------------------------------------------- /src/views/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 62 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import tailwindcss from '@tailwindcss/vite' 4 | import {fileURLToPath, URL} from 'node:url' 5 | 6 | 7 | // https://vite.dev/config/ 8 | export default defineConfig({ 9 | plugins: [vue(), tailwindcss(),], 10 | resolve: { 11 | alias: { 12 | '@': fileURLToPath(new URL('./src', import.meta.url)) 13 | } 14 | }, 15 | server: { 16 | host: '0.0.0.0' 17 | }, 18 | base: process.env.NODE_ENV === 'production' ? './' : '/' 19 | }) 20 | --------------------------------------------------------------------------------