├── .env ├── .github └── workflows │ └── release.yaml ├── .gitignore ├── .nvmrc ├── LICENSE ├── README-zh.md ├── README.md ├── assets ├── extension.gif ├── extension.mp4 └── icons │ ├── icon.png │ ├── icon_128.png │ ├── icon_16.png │ ├── icon_32.png │ └── icon_48.png ├── biome.json ├── bun.lock ├── chrome-extension ├── biome.json ├── build.ts ├── package.json ├── src │ └── background │ │ └── index.ts └── tsconfig.json ├── package.json ├── packages ├── bundle-utils │ ├── biome.json │ ├── build.ts │ ├── dev.ts │ ├── package.json │ └── src │ │ └── index.ts └── constants │ ├── biome.json │ ├── build.ts │ ├── package.json │ └── src │ └── index.ts ├── pages └── content │ ├── biome.json │ ├── build.ts │ ├── index.d.ts │ ├── package.json │ ├── src │ ├── App.tsx │ ├── components │ │ ├── CopyButton.tsx │ │ ├── LanguageSelect.tsx │ │ ├── PanelItem.tsx │ │ ├── SpeechButton.tsx │ │ ├── TooltipHeader.tsx │ │ ├── icons │ │ │ └── index.tsx │ │ └── ui │ │ │ └── Button.tsx │ ├── constants.ts │ ├── content.css │ ├── hooks │ │ ├── useLatest.ts │ │ ├── useSpeech.ts │ │ ├── useTheme.ts │ │ ├── useTransltor.ts │ │ └── useUpdateEffect.ts │ ├── main.tsx │ ├── store │ │ └── index.ts │ ├── tailwind.css │ └── utils │ │ ├── dom.ts │ │ ├── format.ts │ │ ├── locale.ts │ │ ├── selection.ts │ │ └── translator.ts │ └── tsconfig.json ├── scripts ├── build-manifest.ts ├── manifest.ts └── zip.ts └── tsconfig.json /.env: -------------------------------------------------------------------------------- 1 | WS_PORT=3030 -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Realase 2 | 3 | permissions: 4 | contents: write 5 | 6 | on: 7 | push: 8 | tags: 9 | - 'v*.*.*' 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | - name: Set bun 18 | uses: oven-sh/setup-bun@v2 19 | with: 20 | bun-version: latest 21 | - name: Install dependencies 22 | run: bun install 23 | - name: Build 24 | run: | 25 | bun run build --tag ${{ github.ref_name }} 26 | - name: Get previous tag 27 | id: prev_tag 28 | run: | 29 | git fetch --tags 30 | PREV_TAG=$(git tag --sort=-version:refname | head -2 | tail -1) 31 | echo "prev_tag=${PREV_TAG:-HEAD}" >> $GITHUB_OUTPUT 32 | - name: Release 33 | uses: softprops/action-gh-release@v2 34 | with: 35 | body: | 36 | Change log: https://github.com/Plumbiu/ai-translator/compare/${{ steps.prev_tag.outputs.prev_tag }}...${{ github.ref_name }} 37 | 38 | See the assets to download this version. 39 | files: | 40 | build/*.zip 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | 38 | /analyze 39 | test.js 40 | test.html 41 | dist 42 | 43 | pnpm-lock.yaml 44 | manifest.json -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v20.19.2 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Plumbiu 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-zh.md: -------------------------------------------------------------------------------- 1 | # ai-translator 2 | 3 | [下载](https://github.com/Plumbiu/ai-translator/releases) | [English](./README.md) 4 | 5 | ![extension](./assets/extension.gif) 6 | 7 | # 工作原理 8 | 9 | 这个项目使用了谷歌内置的 AI: 10 | 11 | - [translator](https://developer.chrome.com/docs/ai/translator-api) 12 | - [Language detection](https://developer.chrome.com/docs/ai/language-detection) 13 | 14 | # Thanks 15 | 16 | - [fancy-translator](https://github.com/daidr/fancy-translator): 作者 [daidr](https://github.com/daidr) 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ai-translator 2 | 3 | [Download](https://github.com/Plumbiu/zh-translator/releases) | [简体中文](./README-zh.md) 4 | 5 | ![extension](./assets/extension.gif) 6 | 7 | # How it works? 8 | 9 | This project use chrome built-in AI: 10 | 11 | - [translator](https://developer.chrome.com/docs/ai/translator-api) 12 | - [Language detection](https://developer.chrome.com/docs/ai/language-detection) 13 | 14 | # Thanks 15 | 16 | - [fancy-translator](https://github.com/daidr/fancy-translator): By [daidr](https://github.com/daidr) 17 | -------------------------------------------------------------------------------- /assets/extension.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Plumbiu/ai-translator/dca85e0f24bb55ecee4ebe57abcc0cafd793533a/assets/extension.gif -------------------------------------------------------------------------------- /assets/extension.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Plumbiu/ai-translator/dca85e0f24bb55ecee4ebe57abcc0cafd793533a/assets/extension.mp4 -------------------------------------------------------------------------------- /assets/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Plumbiu/ai-translator/dca85e0f24bb55ecee4ebe57abcc0cafd793533a/assets/icons/icon.png -------------------------------------------------------------------------------- /assets/icons/icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Plumbiu/ai-translator/dca85e0f24bb55ecee4ebe57abcc0cafd793533a/assets/icons/icon_128.png -------------------------------------------------------------------------------- /assets/icons/icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Plumbiu/ai-translator/dca85e0f24bb55ecee4ebe57abcc0cafd793533a/assets/icons/icon_16.png -------------------------------------------------------------------------------- /assets/icons/icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Plumbiu/ai-translator/dca85e0f24bb55ecee4ebe57abcc0cafd793533a/assets/icons/icon_32.png -------------------------------------------------------------------------------- /assets/icons/icon_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Plumbiu/ai-translator/dca85e0f24bb55ecee4ebe57abcc0cafd793533a/assets/icons/icon_48.png -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://biomejs.dev/schemas/2.2.3/schema.json", 3 | "vcs": { 4 | "enabled": true, 5 | "clientKind": "git", 6 | "useIgnoreFile": true 7 | }, 8 | "files": { 9 | "ignoreUnknown": true, 10 | "includes": [ 11 | "**", 12 | "!**/node_modules", 13 | "!**/patches", 14 | "!**/.next", 15 | "!**/public", 16 | "!**/bun.lock", 17 | "!**/dist", 18 | "!**/build", 19 | "!**/tailwind.css" 20 | ] 21 | }, 22 | "formatter": { 23 | "enabled": true, 24 | "indentStyle": "space", 25 | "indentWidth": 2, 26 | "lineEnding": "lf", 27 | "lineWidth": 80, 28 | "attributePosition": "auto" 29 | }, 30 | "assist": { 31 | "actions": { 32 | "source": { 33 | "organizeImports": "on", 34 | "useSortedKeys": "off" 35 | } 36 | } 37 | }, 38 | "linter": { 39 | "enabled": true, 40 | "rules": { 41 | "complexity": { 42 | "noBannedTypes": "off", 43 | "noEmptyTypeParameters": "error", 44 | "noExcessiveCognitiveComplexity": "off", 45 | "noExcessiveNestedTestSuites": "error", 46 | "noExtraBooleanCast": "error", 47 | "noForEach": "off", 48 | "noImportantStyles": "off", 49 | "noStaticOnlyClass": "off", 50 | "noThisInStatic": "error", 51 | "noUselessCatch": "error", 52 | "noUselessConstructor": "error", 53 | "noUselessEmptyExport": "error", 54 | "noUselessFragments": "error", 55 | "noUselessLabel": "error", 56 | "noUselessLoneBlockStatements": "error", 57 | "noUselessRename": "error", 58 | "noUselessStringConcat": "error", 59 | "noUselessSwitchCase": "error", 60 | "noUselessTernary": "error", 61 | "noUselessThisAlias": "error", 62 | "noUselessTypeConstraint": "error", 63 | "noUselessUndefinedInitialization": "error", 64 | "noVoid": "error", 65 | "useArrowFunction": "off", 66 | "useDateNow": "error", 67 | "useFlatMap": "error", 68 | "useLiteralKeys": "error", 69 | "useOptionalChain": "error", 70 | "useRegexLiterals": "error", 71 | "useSimpleNumberKeys": "error", 72 | "useSimplifiedLogicExpression": "off", 73 | "noAdjacentSpacesInRegex": "error", 74 | "noFlatMapIdentity": "error", 75 | "noUselessContinue": "error", 76 | "noUselessEscapeInRegex": "error", 77 | "noUselessStringRaw": "error", 78 | "noCommaOperator": "error", 79 | "useNumericLiterals": "error", 80 | "useWhile": "error" 81 | }, 82 | "correctness": { 83 | "noChildrenProp": "error", 84 | "noConstantCondition": "error", 85 | "noConstantMathMinMaxClamp": "error", 86 | "noConstAssign": "error", 87 | "noConstructorReturn": "error", 88 | "noEmptyCharacterClassInRegex": "error", 89 | "noEmptyPattern": "error", 90 | "noGlobalObjectCalls": "error", 91 | "noInnerDeclarations": "error", 92 | "noInvalidBuiltinInstantiation": "error", 93 | "noInvalidConstructorSuper": "error", 94 | "noInvalidDirectionInLinearGradient": "error", 95 | "noInvalidGridAreas": "error", 96 | "noInvalidPositionAtImportRule": "error", 97 | "noInvalidUseBeforeDeclaration": "error", 98 | "noNodejsModules": "off", 99 | "noNonoctalDecimalEscape": "error", 100 | "noPrecisionLoss": "error", 101 | "noRenderReturnValue": "error", 102 | "noSelfAssign": "error", 103 | "noSetterReturn": "error", 104 | "noStringCaseMismatch": "error", 105 | "noSwitchDeclarations": "error", 106 | "noUndeclaredDependencies": "off", 107 | "noUndeclaredVariables": "off", 108 | "noUnknownFunction": "error", 109 | "noUnknownMediaFeatureName": "error", 110 | "noUnknownProperty": "error", 111 | "noUnknownUnit": "error", 112 | "noUnmatchableAnbSelector": "error", 113 | "noUnreachable": "error", 114 | "noUnreachableSuper": "error", 115 | "noUnsafeFinally": "error", 116 | "noUnsafeOptionalChaining": "error", 117 | "noUnusedFunctionParameters": "error", 118 | "noUnusedImports": "error", 119 | "noUnusedLabels": "error", 120 | "noUnusedPrivateClassMembers": "error", 121 | "noUnusedVariables": "off", 122 | "noVoidElementsWithChildren": "error", 123 | "noVoidTypeReturn": "error", 124 | "useExhaustiveDependencies": "off", 125 | "useHookAtTopLevel": "error", 126 | "useImportExtensions": "off", 127 | "useIsNan": "error", 128 | "useJsxKeyInIterable": "error", 129 | "useValidForDirection": "error", 130 | "useYield": "error", 131 | "noMissingVarFunction": "error", 132 | "noUnknownPseudoClass": "off", 133 | "noUnknownPseudoElement": "error", 134 | "noUnknownTypeSelector": "off", 135 | "useValidTypeof": "error" 136 | }, 137 | "nursery": { 138 | "noSecrets": "off", 139 | "useExplicitType": "off", 140 | "useSortedClasses": "error" 141 | }, 142 | "performance": { 143 | "noAccumulatingSpread": "error", 144 | "noBarrelFile": "off", 145 | "noDelete": "error", 146 | "noReExportAll": "off", 147 | "useTopLevelRegex": "off", 148 | "noDynamicNamespaceImportAccess": "error", 149 | "noImgElement": "off", 150 | "noNamespaceImport": "off" 151 | }, 152 | "security": { 153 | "noDangerouslySetInnerHtml": "off", 154 | "noDangerouslySetInnerHtmlWithChildren": "off", 155 | "noGlobalEval": "error", 156 | "noBlankTarget": "error" 157 | }, 158 | "suspicious": { 159 | "noApproximativeNumericConstant": "error", 160 | "noArrayIndexKey": "off", 161 | "noAssignInExpressions": "off", 162 | "noAsyncPromiseExecutor": "error", 163 | "noCatchAssign": "error", 164 | "noClassAssign": "error", 165 | "noCommentText": "error", 166 | "noCompareNegZero": "error", 167 | "noConfusingLabels": "error", 168 | "noConfusingVoidType": "error", 169 | "noConsole": "off", 170 | "noConstEnum": "error", 171 | "noControlCharactersInRegex": "error", 172 | "noDebugger": "error", 173 | "noDoubleEquals": "error", 174 | "noDuplicateAtImportRules": "error", 175 | "noDuplicateCase": "error", 176 | "noDuplicateClassMembers": "error", 177 | "noDuplicateFontNames": "off", 178 | "noDuplicateJsxProps": "error", 179 | "noDuplicateObjectKeys": "error", 180 | "noDuplicateParameters": "error", 181 | "noDuplicateSelectorsKeyframeBlock": "error", 182 | "noDuplicateTestHooks": "error", 183 | "noEmptyBlock": "error", 184 | "noEmptyBlockStatements": "off", 185 | "noEmptyInterface": "error", 186 | "noEvolvingTypes": "error", 187 | "noExplicitAny": "off", 188 | "noExportsInTest": "error", 189 | "noExtraNonNullAssertion": "error", 190 | "noFallthroughSwitchClause": "error", 191 | "noFocusedTests": "off", 192 | "noFunctionAssign": "error", 193 | "noGlobalAssign": "error", 194 | "noGlobalIsFinite": "error", 195 | "noGlobalIsNan": "error", 196 | "noImplicitAnyLet": "error", 197 | "noImportAssign": "error", 198 | "noImportantInKeyframe": "error", 199 | "noLabelVar": "error", 200 | "noMisleadingCharacterClass": "error", 201 | "noMisleadingInstantiator": "error", 202 | "noMisplacedAssertion": "off", 203 | "noMisrefactoredShorthandAssign": "error", 204 | "noPrototypeBuiltins": "error", 205 | "noReactSpecificProps": "off", 206 | "noRedeclare": "error", 207 | "noRedundantUseStrict": "error", 208 | "noSelfCompare": "error", 209 | "noShadowRestrictedNames": "off", 210 | "noShorthandPropertyOverrides": "error", 211 | "noSkippedTests": "off", 212 | "noSparseArray": "error", 213 | "noSuspiciousSemicolonInJsx": "error", 214 | "noThenProperty": "error", 215 | "noUnsafeDeclarationMerging": "error", 216 | "noUnsafeNegation": "error", 217 | "useDefaultSwitchClauseLast": "error", 218 | "useErrorMessage": "error", 219 | "useGetterReturn": "error", 220 | "useIsArray": "error", 221 | "useNamespaceKeyword": "error", 222 | "useNumberToFixedDigitsArgument": "error", 223 | "noWith": "error", 224 | "noDocumentCookie": "error", 225 | "noDocumentImportInPage": "error", 226 | "noDuplicateCustomProperties": "error", 227 | "noDuplicateElseIf": "error", 228 | "noDuplicateProperties": "error", 229 | "noHeadImportInDocument": "error", 230 | "noIrregularWhitespace": "error", 231 | "noOctalEscape": "error", 232 | "noTemplateCurlyInString": "error", 233 | "useGoogleFontDisplay": "error", 234 | "useGuardForIn": "error", 235 | "useStrictMode": "error", 236 | "noVar": "error" 237 | }, 238 | "style": { 239 | "noDefaultExport": "off", 240 | "noDoneCallback": "error", 241 | "noImplicitBoolean": "off", 242 | "noInferrableTypes": "error", 243 | "noNamespace": "error", 244 | "noNegationElse": "error", 245 | "noNonNullAssertion": "off", 246 | "noParameterAssign": "off", 247 | "noParameterProperties": "error", 248 | "noRestrictedGlobals": "error", 249 | "noShoutyConstants": "error", 250 | "noUnusedTemplateLiteral": "error", 251 | "noUselessElse": "error", 252 | "noYodaExpression": "error", 253 | "useBlockStatements": "error", 254 | "useCollapsedElseIf": "error", 255 | "useConsistentArrayType": "error", 256 | "useConsistentBuiltinInstantiation": "error", 257 | "useConst": "error", 258 | "useDefaultParameterLast": "error", 259 | "useDefaultSwitchClause": "error", 260 | "useEnumInitializers": "error", 261 | "useExplicitLengthCheck": "off", 262 | "useExponentiationOperator": "error", 263 | "useExportType": "error", 264 | "useFilenamingConvention": "off", 265 | "useForOf": "off", 266 | "useFragmentSyntax": "error", 267 | "useImportType": "error", 268 | "useLiteralEnumMembers": "error", 269 | "useNamingConvention": "off", 270 | "useNodeAssertStrict": "error", 271 | "useNodejsImportProtocol": "error", 272 | "useNumberNamespace": "error", 273 | "useSelfClosingElements": "error", 274 | "useShorthandAssign": "error", 275 | "useShorthandFunctionType": "error", 276 | "useSingleVarDeclarator": "error", 277 | "useTemplate": "off", 278 | "useThrowNewError": "error", 279 | "useThrowOnlyError": "error", 280 | "useArrayLiterals": "error", 281 | "noCommonJs": "off", 282 | "noDescendingSpecificity": "off", 283 | "noEnum": "off", 284 | "noExportedImports": "off", 285 | "noHeadElement": "error", 286 | "noNestedTernary": "off", 287 | "noProcessEnv": "off", 288 | "noRestrictedImports": "error", 289 | "noRestrictedTypes": "error", 290 | "noSubstr": "error", 291 | "noValueAtRule": "error", 292 | "useAtIndex": "off", 293 | "useCollapsedIf": "error", 294 | "useComponentExportOnlyModules": "off", 295 | "useConsistentCurlyBraces": "off", 296 | "useConsistentMemberAccessibility": "error", 297 | "useDeprecatedReason": "error", 298 | "useTrimStartEnd": "error" 299 | }, 300 | "a11y": { 301 | "noAccessKey": "error", 302 | "noAriaHiddenOnFocusable": "error", 303 | "noAriaUnsupportedElements": "error", 304 | "noAutofocus": "error", 305 | "noDistractingElements": "error", 306 | "noHeaderScope": "error", 307 | "noInteractiveElementToNoninteractiveRole": "error", 308 | "noLabelWithoutControl": "error", 309 | "noNoninteractiveElementToInteractiveRole": "error", 310 | "noNoninteractiveTabindex": "error", 311 | "noPositiveTabindex": "error", 312 | "noRedundantAlt": "error", 313 | "noRedundantRoles": "error", 314 | "noSvgWithoutTitle": "off", 315 | "useAnchorContent": "error", 316 | "useAriaActivedescendantWithTabindex": "error", 317 | "useAriaPropsForRole": "error", 318 | "useButtonType": "error", 319 | "useFocusableInteractive": "error", 320 | "useGenericFontNames": "error", 321 | "useHeadingContent": "error", 322 | "useHtmlLang": "error", 323 | "useIframeTitle": "error", 324 | "useKeyWithClickEvents": "off", 325 | "useKeyWithMouseEvents": "error", 326 | "useMediaCaption": "error", 327 | "useSemanticElements": "error", 328 | "useValidAnchor": "error", 329 | "useValidAriaProps": "error", 330 | "useValidAriaRole": "error", 331 | "useValidAriaValues": "error", 332 | "useValidLang": "error", 333 | "noStaticElementInteractions": "off", 334 | "useAriaPropsSupportedByRole": "error", 335 | "useValidAutocomplete": "error" 336 | } 337 | }, 338 | "includes": [ 339 | "**/*.ts", 340 | "**/*.tsx", 341 | "!**/node_modules", 342 | "!**/patches", 343 | "!**/.next", 344 | "!**/public", 345 | "!**/bun.lock", 346 | "!**/dist/**", 347 | "!**/build/**", 348 | "!**/tailwind.css" 349 | ] 350 | }, 351 | "javascript": { 352 | "linter": { 353 | "enabled": true 354 | }, 355 | "formatter": { 356 | "enabled": true, 357 | "quoteStyle": "single", 358 | "jsxQuoteStyle": "double", 359 | "trailingCommas": "all", 360 | "semicolons": "asNeeded", 361 | "bracketSameLine": false, 362 | "bracketSpacing": true, 363 | "lineEnding": "lf" 364 | } 365 | }, 366 | "json": { 367 | "formatter": { 368 | "enabled": true 369 | } 370 | } 371 | } 372 | -------------------------------------------------------------------------------- /bun.lock: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1, 3 | "workspaces": { 4 | "": { 5 | "name": "ai-translator", 6 | "dependencies": { 7 | "daisyui": "^5.1.10", 8 | "tailwindcss": "^4.1.13", 9 | }, 10 | "devDependencies": { 11 | "@biomejs/biome": "2.2.3", 12 | "@libs/bundle-utils": "workspace:*", 13 | "@tailwindcss/postcss": "^4.1.13", 14 | "@types/adm-zip": "0.5.7", 15 | "@types/bun": "^1.2.21", 16 | "@types/chrome": "latest", 17 | "@types/dom-chromium-ai": "0.0.9", 18 | "@types/minimist": "^1.2.5", 19 | "@types/react": "^18.3.18", 20 | "@types/react-dom": "^18.3.5", 21 | "adm-zip": "0.5.16", 22 | "cssnano": "^7.1.1", 23 | "minimist": "^1.2.8", 24 | "picocolors": "^1.1.1", 25 | "postcss": "^8.5.6", 26 | "simple-git-hooks": "^2.13.1", 27 | }, 28 | }, 29 | "chrome-extension": { 30 | "name": "@ai-translator/chrome-extension", 31 | "dependencies": { 32 | "@libs/constants": "workspace:*", 33 | }, 34 | }, 35 | "packages/bundle-utils": { 36 | "name": "@libs/bundle-utils", 37 | "version": "1.0.0", 38 | "devDependencies": { 39 | "bun-plugin-dts": "^0.3.0", 40 | }, 41 | }, 42 | "packages/constants": { 43 | "name": "@libs/constants", 44 | "version": "1.0.0", 45 | }, 46 | "pages/content": { 47 | "name": "@ai-translator/content", 48 | "version": "1.0.0", 49 | "dependencies": { 50 | "@floating-ui/dom": "^1.7.4", 51 | "@libs/constants": "workspace:*", 52 | "clsx": "^2.1.1", 53 | "react": "^18.3.1", 54 | "react-dom": "^18.3.1", 55 | "simplebar-react": "^3.3.2", 56 | "zustand": "^5.0.8", 57 | }, 58 | }, 59 | }, 60 | "packages": { 61 | "@ai-translator/chrome-extension": ["@ai-translator/chrome-extension@workspace:chrome-extension"], 62 | 63 | "@ai-translator/content": ["@ai-translator/content@workspace:pages/content"], 64 | 65 | "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "https://mirrors.cloud.tencent.com/npm/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], 66 | 67 | "@biomejs/biome": ["@biomejs/biome@2.2.3", "https://mirrors.cloud.tencent.com/npm/@biomejs/biome/-/biome-2.2.3.tgz", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.2.3", "@biomejs/cli-darwin-x64": "2.2.3", "@biomejs/cli-linux-arm64": "2.2.3", "@biomejs/cli-linux-arm64-musl": "2.2.3", "@biomejs/cli-linux-x64": "2.2.3", "@biomejs/cli-linux-x64-musl": "2.2.3", "@biomejs/cli-win32-arm64": "2.2.3", "@biomejs/cli-win32-x64": "2.2.3" }, "bin": { "biome": "bin/biome" } }, "sha512-9w0uMTvPrIdvUrxazZ42Ib7t8Y2yoGLKLdNne93RLICmaHw7mcLv4PPb5LvZLJF3141gQHiCColOh/v6VWlWmg=="], 68 | 69 | "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.2.3", "https://mirrors.cloud.tencent.com/npm/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.3.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-OrqQVBpadB5eqzinXN4+Q6honBz+tTlKVCsbEuEpljK8ASSItzIRZUA02mTikl3H/1nO2BMPFiJ0nkEZNy3B1w=="], 70 | 71 | "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.2.3", "https://mirrors.cloud.tencent.com/npm/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.3.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-OCdBpb1TmyfsTgBAM1kPMXyYKTohQ48WpiN9tkt9xvU6gKVKHY4oVwteBebiOqyfyzCNaSiuKIPjmHjUZ2ZNMg=="], 72 | 73 | "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.2.3", "https://mirrors.cloud.tencent.com/npm/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.3.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-g/Uta2DqYpECxG+vUmTAmUKlVhnGEcY7DXWgKP8ruLRa8Si1QHsWknPY3B/wCo0KgYiFIOAZ9hjsHfNb9L85+g=="], 74 | 75 | "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.2.3", "https://mirrors.cloud.tencent.com/npm/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.3.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-q3w9jJ6JFPZPeqyvwwPeaiS/6NEszZ+pXKF+IczNo8Xj6fsii45a4gEEicKyKIytalV+s829ACZujQlXAiVLBQ=="], 76 | 77 | "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.2.3", "https://mirrors.cloud.tencent.com/npm/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.3.tgz", { "os": "linux", "cpu": "x64" }, "sha512-LEtyYL1fJsvw35CxrbQ0gZoxOG3oZsAjzfRdvRBRHxOpQ91Q5doRVjvWW/wepgSdgk5hlaNzfeqpyGmfSD0Eyw=="], 78 | 79 | "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.2.3", "https://mirrors.cloud.tencent.com/npm/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.3.tgz", { "os": "linux", "cpu": "x64" }, "sha512-y76Dn4vkP1sMRGPFlNc+OTETBhGPJ90jY3il6jAfur8XWrYBQV3swZ1Jo0R2g+JpOeeoA0cOwM7mJG6svDz79w=="], 80 | 81 | "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.2.3", "https://mirrors.cloud.tencent.com/npm/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.3.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-Ms9zFYzjcJK7LV+AOMYnjN3pV3xL8Prxf9aWdDVL74onLn5kcvZ1ZMQswE5XHtnd/r/0bnUd928Rpbs14BzVmA=="], 82 | 83 | "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.2.3", "https://mirrors.cloud.tencent.com/npm/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.3.tgz", { "os": "win32", "cpu": "x64" }, "sha512-gvCpewE7mBwBIpqk1YrUqNR4mCiyJm6UI3YWQQXkedSSEwzRdodRpaKhbdbHw1/hmTWOVXQ+Eih5Qctf4TCVOQ=="], 84 | 85 | "@floating-ui/core": ["@floating-ui/core@1.7.3", "https://mirrors.cloud.tencent.com/npm/@floating-ui/core/-/core-1.7.3.tgz", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="], 86 | 87 | "@floating-ui/dom": ["@floating-ui/dom@1.7.4", "https://mirrors.cloud.tencent.com/npm/@floating-ui/dom/-/dom-1.7.4.tgz", { "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA=="], 88 | 89 | "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "https://mirrors.cloud.tencent.com/npm/@floating-ui/utils/-/utils-0.2.10.tgz", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="], 90 | 91 | "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "https://mirrors.cloud.tencent.com/npm/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], 92 | 93 | "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "https://mirrors.cloud.tencent.com/npm/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], 94 | 95 | "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "https://mirrors.cloud.tencent.com/npm/@jridgewell/remapping/-/remapping-2.3.5.tgz", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], 96 | 97 | "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "https://mirrors.cloud.tencent.com/npm/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], 98 | 99 | "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "https://mirrors.cloud.tencent.com/npm/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], 100 | 101 | "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "https://mirrors.cloud.tencent.com/npm/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], 102 | 103 | "@libs/bundle-utils": ["@libs/bundle-utils@workspace:packages/bundle-utils"], 104 | 105 | "@libs/constants": ["@libs/constants@workspace:packages/constants"], 106 | 107 | "@tailwindcss/node": ["@tailwindcss/node@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/node/-/node-4.1.13.tgz", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.5.1", "lightningcss": "1.30.1", "magic-string": "^0.30.18", "source-map-js": "^1.2.1", "tailwindcss": "4.1.13" } }, "sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw=="], 108 | 109 | "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide/-/oxide-4.1.13.tgz", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.13", "@tailwindcss/oxide-darwin-arm64": "4.1.13", "@tailwindcss/oxide-darwin-x64": "4.1.13", "@tailwindcss/oxide-freebsd-x64": "4.1.13", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.13", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.13", "@tailwindcss/oxide-linux-arm64-musl": "4.1.13", "@tailwindcss/oxide-linux-x64-gnu": "4.1.13", "@tailwindcss/oxide-linux-x64-musl": "4.1.13", "@tailwindcss/oxide-wasm32-wasi": "4.1.13", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.13", "@tailwindcss/oxide-win32-x64-msvc": "4.1.13" } }, "sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA=="], 110 | 111 | "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.13.tgz", { "os": "android", "cpu": "arm64" }, "sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew=="], 112 | 113 | "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.13.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ=="], 114 | 115 | "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.13.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw=="], 116 | 117 | "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.13.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ=="], 118 | 119 | "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.13.tgz", { "os": "linux", "cpu": "arm" }, "sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw=="], 120 | 121 | "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.13.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ=="], 122 | 123 | "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.13.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg=="], 124 | 125 | "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.13.tgz", { "os": "linux", "cpu": "x64" }, "sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ=="], 126 | 127 | "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.13.tgz", { "os": "linux", "cpu": "x64" }, "sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ=="], 128 | 129 | "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.13.tgz", { "dependencies": { "@emnapi/core": "^1.4.5", "@emnapi/runtime": "^1.4.5", "@emnapi/wasi-threads": "^1.0.4", "@napi-rs/wasm-runtime": "^0.2.12", "@tybys/wasm-util": "^0.10.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA=="], 130 | 131 | "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.13.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg=="], 132 | 133 | "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.13.tgz", { "os": "win32", "cpu": "x64" }, "sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw=="], 134 | 135 | "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.13", "https://mirrors.cloud.tencent.com/npm/@tailwindcss/postcss/-/postcss-4.1.13.tgz", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.13", "@tailwindcss/oxide": "4.1.13", "postcss": "^8.4.41", "tailwindcss": "4.1.13" } }, "sha512-HLgx6YSFKJT7rJqh9oJs/TkBFhxuMOfUKSBEPYwV+t78POOBsdQ7crhZLzwcH3T0UyUuOzU/GK5pk5eKr3wCiQ=="], 136 | 137 | "@types/adm-zip": ["@types/adm-zip@0.5.7", "https://mirrors.cloud.tencent.com/npm/@types/adm-zip/-/adm-zip-0.5.7.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-DNEs/QvmyRLurdQPChqq0Md4zGvPwHerAJYWk9l2jCbD1VPpnzRJorOdiq4zsw09NFbYnhfsoEhWtxIzXpn2yw=="], 138 | 139 | "@types/bun": ["@types/bun@1.2.21", "https://mirrors.cloud.tencent.com/npm/@types/bun/-/bun-1.2.21.tgz", { "dependencies": { "bun-types": "1.2.21" } }, "sha512-NiDnvEqmbfQ6dmZ3EeUO577s4P5bf4HCTXtI6trMc6f6RzirY5IrF3aIookuSpyslFzrnvv2lmEWv5HyC1X79A=="], 140 | 141 | "@types/chrome": ["@types/chrome@0.1.6", "https://mirrors.cloud.tencent.com/npm/@types/chrome/-/chrome-0.1.6.tgz", { "dependencies": { "@types/filesystem": "*", "@types/har-format": "*" } }, "sha512-Rnv8CDthTPA4/ojSWw5A//7Ew7P2pAJECxAR8YeOhehaUKZ7WX5fHIZbEw8m6bTRNzFyhxhzUb6T3gjKMry+2w=="], 142 | 143 | "@types/dom-chromium-ai": ["@types/dom-chromium-ai@0.0.9", "https://mirrors.cloud.tencent.com/npm/@types/dom-chromium-ai/-/dom-chromium-ai-0.0.9.tgz", {}, "sha512-wZNak+04m29hwXqtnDqNUl3TGcU9pvWhemtBpVtN2TKnWQKprJ8KQjaldbMVfdL44UHnUfv9V51rRh7tV8HY7w=="], 144 | 145 | "@types/filesystem": ["@types/filesystem@0.0.36", "https://mirrors.cloud.tencent.com/npm/@types/filesystem/-/filesystem-0.0.36.tgz", { "dependencies": { "@types/filewriter": "*" } }, "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA=="], 146 | 147 | "@types/filewriter": ["@types/filewriter@0.0.33", "https://mirrors.cloud.tencent.com/npm/@types/filewriter/-/filewriter-0.0.33.tgz", {}, "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g=="], 148 | 149 | "@types/har-format": ["@types/har-format@1.2.16", "https://mirrors.cloud.tencent.com/npm/@types/har-format/-/har-format-1.2.16.tgz", {}, "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A=="], 150 | 151 | "@types/minimist": ["@types/minimist@1.2.5", "https://mirrors.cloud.tencent.com/npm/@types/minimist/-/minimist-1.2.5.tgz", {}, "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag=="], 152 | 153 | "@types/node": ["@types/node@24.3.1", "https://mirrors.cloud.tencent.com/npm/@types/node/-/node-24.3.1.tgz", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g=="], 154 | 155 | "@types/prop-types": ["@types/prop-types@15.7.15", "https://mirrors.cloud.tencent.com/npm/@types/prop-types/-/prop-types-15.7.15.tgz", {}, "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw=="], 156 | 157 | "@types/react": ["@types/react@18.3.24", "https://mirrors.cloud.tencent.com/npm/@types/react/-/react-18.3.24.tgz", { "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "sha512-0dLEBsA1kI3OezMBF8nSsb7Nk19ZnsyE1LLhB8r27KbgU5H4pvuqZLdtE+aUkJVoXgTVuA+iLIwmZ0TuK4tx6A=="], 158 | 159 | "@types/react-dom": ["@types/react-dom@18.3.7", "https://mirrors.cloud.tencent.com/npm/@types/react-dom/-/react-dom-18.3.7.tgz", { "peerDependencies": { "@types/react": "^18.0.0" } }, "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ=="], 160 | 161 | "adm-zip": ["adm-zip@0.5.16", "https://mirrors.cloud.tencent.com/npm/adm-zip/-/adm-zip-0.5.16.tgz", {}, "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ=="], 162 | 163 | "ansi-regex": ["ansi-regex@5.0.1", "https://mirrors.cloud.tencent.com/npm/ansi-regex/-/ansi-regex-5.0.1.tgz", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], 164 | 165 | "ansi-styles": ["ansi-styles@4.3.0", "https://mirrors.cloud.tencent.com/npm/ansi-styles/-/ansi-styles-4.3.0.tgz", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], 166 | 167 | "boolbase": ["boolbase@1.0.0", "https://mirrors.cloud.tencent.com/npm/boolbase/-/boolbase-1.0.0.tgz", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], 168 | 169 | "browserslist": ["browserslist@4.25.4", "https://mirrors.cloud.tencent.com/npm/browserslist/-/browserslist-4.25.4.tgz", { "dependencies": { "caniuse-lite": "^1.0.30001737", "electron-to-chromium": "^1.5.211", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg=="], 170 | 171 | "bun-plugin-dts": ["bun-plugin-dts@0.3.0", "https://mirrors.cloud.tencent.com/npm/bun-plugin-dts/-/bun-plugin-dts-0.3.0.tgz", { "dependencies": { "common-path-prefix": "^3.0.0", "dts-bundle-generator": "^9.5.1", "get-tsconfig": "^4.8.1" } }, "sha512-QpiAOKfPcdOToxySOqRY8FwL+brTvyXEHWzrSCRKt4Pv7Z4pnUrhK9tFtM7Ndm7ED09B/0cGXnHJKqmekr/ERw=="], 172 | 173 | "bun-types": ["bun-types@1.2.21", "https://mirrors.cloud.tencent.com/npm/bun-types/-/bun-types-1.2.21.tgz", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-sa2Tj77Ijc/NTLS0/Odjq/qngmEPZfbfnOERi0KRUYhT9R8M4VBioWVmMWE5GrYbKMc+5lVybXygLdibHaqVqw=="], 174 | 175 | "caniuse-api": ["caniuse-api@3.0.0", "https://mirrors.cloud.tencent.com/npm/caniuse-api/-/caniuse-api-3.0.0.tgz", { "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw=="], 176 | 177 | "caniuse-lite": ["caniuse-lite@1.0.30001741", "https://mirrors.cloud.tencent.com/npm/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz", {}, "sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw=="], 178 | 179 | "chownr": ["chownr@3.0.0", "https://mirrors.cloud.tencent.com/npm/chownr/-/chownr-3.0.0.tgz", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], 180 | 181 | "cliui": ["cliui@8.0.1", "https://mirrors.cloud.tencent.com/npm/cliui/-/cliui-8.0.1.tgz", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], 182 | 183 | "clsx": ["clsx@2.1.1", "https://mirrors.cloud.tencent.com/npm/clsx/-/clsx-2.1.1.tgz", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], 184 | 185 | "color-convert": ["color-convert@2.0.1", "https://mirrors.cloud.tencent.com/npm/color-convert/-/color-convert-2.0.1.tgz", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], 186 | 187 | "color-name": ["color-name@1.1.4", "https://mirrors.cloud.tencent.com/npm/color-name/-/color-name-1.1.4.tgz", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], 188 | 189 | "colord": ["colord@2.9.3", "https://mirrors.cloud.tencent.com/npm/colord/-/colord-2.9.3.tgz", {}, "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw=="], 190 | 191 | "commander": ["commander@11.1.0", "https://mirrors.cloud.tencent.com/npm/commander/-/commander-11.1.0.tgz", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], 192 | 193 | "common-path-prefix": ["common-path-prefix@3.0.0", "https://mirrors.cloud.tencent.com/npm/common-path-prefix/-/common-path-prefix-3.0.0.tgz", {}, "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w=="], 194 | 195 | "css-declaration-sorter": ["css-declaration-sorter@7.2.0", "https://mirrors.cloud.tencent.com/npm/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", { "peerDependencies": { "postcss": "^8.0.9" } }, "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow=="], 196 | 197 | "css-select": ["css-select@5.2.2", "https://mirrors.cloud.tencent.com/npm/css-select/-/css-select-5.2.2.tgz", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], 198 | 199 | "css-tree": ["css-tree@3.1.0", "https://mirrors.cloud.tencent.com/npm/css-tree/-/css-tree-3.1.0.tgz", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="], 200 | 201 | "css-what": ["css-what@6.2.2", "https://mirrors.cloud.tencent.com/npm/css-what/-/css-what-6.2.2.tgz", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], 202 | 203 | "cssesc": ["cssesc@3.0.0", "https://mirrors.cloud.tencent.com/npm/cssesc/-/cssesc-3.0.0.tgz", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], 204 | 205 | "cssnano": ["cssnano@7.1.1", "https://mirrors.cloud.tencent.com/npm/cssnano/-/cssnano-7.1.1.tgz", { "dependencies": { "cssnano-preset-default": "^7.0.9", "lilconfig": "^3.1.3" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-fm4D8ti0dQmFPeF8DXSAA//btEmqCOgAc/9Oa3C1LW94h5usNrJEfrON7b4FkPZgnDEn6OUs5NdxiJZmAtGOpQ=="], 206 | 207 | "cssnano-preset-default": ["cssnano-preset-default@7.0.9", "https://mirrors.cloud.tencent.com/npm/cssnano-preset-default/-/cssnano-preset-default-7.0.9.tgz", { "dependencies": { "browserslist": "^4.25.1", "css-declaration-sorter": "^7.2.0", "cssnano-utils": "^5.0.1", "postcss-calc": "^10.1.1", "postcss-colormin": "^7.0.4", "postcss-convert-values": "^7.0.7", "postcss-discard-comments": "^7.0.4", "postcss-discard-duplicates": "^7.0.2", "postcss-discard-empty": "^7.0.1", "postcss-discard-overridden": "^7.0.1", "postcss-merge-longhand": "^7.0.5", "postcss-merge-rules": "^7.0.6", "postcss-minify-font-values": "^7.0.1", "postcss-minify-gradients": "^7.0.1", "postcss-minify-params": "^7.0.4", "postcss-minify-selectors": "^7.0.5", "postcss-normalize-charset": "^7.0.1", "postcss-normalize-display-values": "^7.0.1", "postcss-normalize-positions": "^7.0.1", "postcss-normalize-repeat-style": "^7.0.1", "postcss-normalize-string": "^7.0.1", "postcss-normalize-timing-functions": "^7.0.1", "postcss-normalize-unicode": "^7.0.4", "postcss-normalize-url": "^7.0.1", "postcss-normalize-whitespace": "^7.0.1", "postcss-ordered-values": "^7.0.2", "postcss-reduce-initial": "^7.0.4", "postcss-reduce-transforms": "^7.0.1", "postcss-svgo": "^7.1.0", "postcss-unique-selectors": "^7.0.4" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-tCD6AAFgYBOVpMBX41KjbvRh9c2uUjLXRyV7KHSIrwHiq5Z9o0TFfUCoM3TwVrRsRteN3sVXGNvjVNxYzkpTsA=="], 208 | 209 | "cssnano-utils": ["cssnano-utils@5.0.1", "https://mirrors.cloud.tencent.com/npm/cssnano-utils/-/cssnano-utils-5.0.1.tgz", { "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg=="], 210 | 211 | "csso": ["csso@5.0.5", "https://mirrors.cloud.tencent.com/npm/csso/-/csso-5.0.5.tgz", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="], 212 | 213 | "csstype": ["csstype@3.1.3", "https://mirrors.cloud.tencent.com/npm/csstype/-/csstype-3.1.3.tgz", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], 214 | 215 | "daisyui": ["daisyui@5.1.10", "https://mirrors.cloud.tencent.com/npm/daisyui/-/daisyui-5.1.10.tgz", {}, "sha512-p1J/HME2WmaSiy6u2alIbeP3gd5PNVft3+6Bdll0BRSm/UdI4084+pD01LxFug/5wGexNewWqbcEL6nB2n2o+Q=="], 216 | 217 | "detect-libc": ["detect-libc@2.0.4", "https://mirrors.cloud.tencent.com/npm/detect-libc/-/detect-libc-2.0.4.tgz", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="], 218 | 219 | "dom-serializer": ["dom-serializer@2.0.0", "https://mirrors.cloud.tencent.com/npm/dom-serializer/-/dom-serializer-2.0.0.tgz", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], 220 | 221 | "domelementtype": ["domelementtype@2.3.0", "https://mirrors.cloud.tencent.com/npm/domelementtype/-/domelementtype-2.3.0.tgz", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], 222 | 223 | "domhandler": ["domhandler@5.0.3", "https://mirrors.cloud.tencent.com/npm/domhandler/-/domhandler-5.0.3.tgz", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], 224 | 225 | "domutils": ["domutils@3.2.2", "https://mirrors.cloud.tencent.com/npm/domutils/-/domutils-3.2.2.tgz", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], 226 | 227 | "dts-bundle-generator": ["dts-bundle-generator@9.5.1", "https://mirrors.cloud.tencent.com/npm/dts-bundle-generator/-/dts-bundle-generator-9.5.1.tgz", { "dependencies": { "typescript": ">=5.0.2", "yargs": "^17.6.0" }, "bin": { "dts-bundle-generator": "dist/bin/dts-bundle-generator.js" } }, "sha512-DxpJOb2FNnEyOzMkG11sxO2dmxPjthoVWxfKqWYJ/bI/rT1rvTMktF5EKjAYrRZu6Z6t3NhOUZ0sZ5ZXevOfbA=="], 228 | 229 | "electron-to-chromium": ["electron-to-chromium@1.5.215", "https://mirrors.cloud.tencent.com/npm/electron-to-chromium/-/electron-to-chromium-1.5.215.tgz", {}, "sha512-TIvGp57UpeNetj/wV/xpFNpWGb0b/ROw372lHPx5Aafx02gjTBtWnEEcaSX3W2dLM3OSdGGyHX/cHl01JQsLaQ=="], 230 | 231 | "emoji-regex": ["emoji-regex@8.0.0", "https://mirrors.cloud.tencent.com/npm/emoji-regex/-/emoji-regex-8.0.0.tgz", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], 232 | 233 | "enhanced-resolve": ["enhanced-resolve@5.18.3", "https://mirrors.cloud.tencent.com/npm/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="], 234 | 235 | "entities": ["entities@4.5.0", "https://mirrors.cloud.tencent.com/npm/entities/-/entities-4.5.0.tgz", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], 236 | 237 | "escalade": ["escalade@3.2.0", "https://mirrors.cloud.tencent.com/npm/escalade/-/escalade-3.2.0.tgz", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], 238 | 239 | "get-caller-file": ["get-caller-file@2.0.5", "https://mirrors.cloud.tencent.com/npm/get-caller-file/-/get-caller-file-2.0.5.tgz", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], 240 | 241 | "get-tsconfig": ["get-tsconfig@4.10.1", "https://mirrors.cloud.tencent.com/npm/get-tsconfig/-/get-tsconfig-4.10.1.tgz", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ=="], 242 | 243 | "graceful-fs": ["graceful-fs@4.2.11", "https://mirrors.cloud.tencent.com/npm/graceful-fs/-/graceful-fs-4.2.11.tgz", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], 244 | 245 | "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "https://mirrors.cloud.tencent.com/npm/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], 246 | 247 | "jiti": ["jiti@2.5.1", "https://mirrors.cloud.tencent.com/npm/jiti/-/jiti-2.5.1.tgz", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w=="], 248 | 249 | "js-tokens": ["js-tokens@4.0.0", "https://mirrors.cloud.tencent.com/npm/js-tokens/-/js-tokens-4.0.0.tgz", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], 250 | 251 | "lightningcss": ["lightningcss@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss/-/lightningcss-1.30.1.tgz", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="], 252 | 253 | "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="], 254 | 255 | "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="], 256 | 257 | "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="], 258 | 259 | "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="], 260 | 261 | "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="], 262 | 263 | "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="], 264 | 265 | "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="], 266 | 267 | "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="], 268 | 269 | "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="], 270 | 271 | "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "https://mirrors.cloud.tencent.com/npm/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="], 272 | 273 | "lilconfig": ["lilconfig@3.1.3", "https://mirrors.cloud.tencent.com/npm/lilconfig/-/lilconfig-3.1.3.tgz", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], 274 | 275 | "lodash": ["lodash@4.17.21", "https://mirrors.cloud.tencent.com/npm/lodash/-/lodash-4.17.21.tgz", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], 276 | 277 | "lodash-es": ["lodash-es@4.17.21", "https://mirrors.cloud.tencent.com/npm/lodash-es/-/lodash-es-4.17.21.tgz", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], 278 | 279 | "lodash.memoize": ["lodash.memoize@4.1.2", "https://mirrors.cloud.tencent.com/npm/lodash.memoize/-/lodash.memoize-4.1.2.tgz", {}, "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="], 280 | 281 | "lodash.uniq": ["lodash.uniq@4.5.0", "https://mirrors.cloud.tencent.com/npm/lodash.uniq/-/lodash.uniq-4.5.0.tgz", {}, "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="], 282 | 283 | "loose-envify": ["loose-envify@1.4.0", "https://mirrors.cloud.tencent.com/npm/loose-envify/-/loose-envify-1.4.0.tgz", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], 284 | 285 | "magic-string": ["magic-string@0.30.19", "https://mirrors.cloud.tencent.com/npm/magic-string/-/magic-string-0.30.19.tgz", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="], 286 | 287 | "mdn-data": ["mdn-data@2.12.2", "https://mirrors.cloud.tencent.com/npm/mdn-data/-/mdn-data-2.12.2.tgz", {}, "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA=="], 288 | 289 | "minimist": ["minimist@1.2.8", "https://mirrors.cloud.tencent.com/npm/minimist/-/minimist-1.2.8.tgz", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], 290 | 291 | "minipass": ["minipass@7.1.2", "https://mirrors.cloud.tencent.com/npm/minipass/-/minipass-7.1.2.tgz", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], 292 | 293 | "minizlib": ["minizlib@3.0.2", "https://mirrors.cloud.tencent.com/npm/minizlib/-/minizlib-3.0.2.tgz", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="], 294 | 295 | "mkdirp": ["mkdirp@3.0.1", "https://mirrors.cloud.tencent.com/npm/mkdirp/-/mkdirp-3.0.1.tgz", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], 296 | 297 | "nanoid": ["nanoid@3.3.11", "https://mirrors.cloud.tencent.com/npm/nanoid/-/nanoid-3.3.11.tgz", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], 298 | 299 | "node-releases": ["node-releases@2.0.20", "https://mirrors.cloud.tencent.com/npm/node-releases/-/node-releases-2.0.20.tgz", {}, "sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA=="], 300 | 301 | "nth-check": ["nth-check@2.1.1", "https://mirrors.cloud.tencent.com/npm/nth-check/-/nth-check-2.1.1.tgz", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], 302 | 303 | "picocolors": ["picocolors@1.1.1", "https://mirrors.cloud.tencent.com/npm/picocolors/-/picocolors-1.1.1.tgz", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], 304 | 305 | "postcss": ["postcss@8.5.6", "https://mirrors.cloud.tencent.com/npm/postcss/-/postcss-8.5.6.tgz", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], 306 | 307 | "postcss-calc": ["postcss-calc@10.1.1", "https://mirrors.cloud.tencent.com/npm/postcss-calc/-/postcss-calc-10.1.1.tgz", { "dependencies": { "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.38" } }, "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw=="], 308 | 309 | "postcss-colormin": ["postcss-colormin@7.0.4", "https://mirrors.cloud.tencent.com/npm/postcss-colormin/-/postcss-colormin-7.0.4.tgz", { "dependencies": { "browserslist": "^4.25.1", "caniuse-api": "^3.0.0", "colord": "^2.9.3", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-ziQuVzQZBROpKpfeDwmrG+Vvlr0YWmY/ZAk99XD+mGEBuEojoFekL41NCsdhyNUtZI7DPOoIWIR7vQQK9xwluw=="], 310 | 311 | "postcss-convert-values": ["postcss-convert-values@7.0.7", "https://mirrors.cloud.tencent.com/npm/postcss-convert-values/-/postcss-convert-values-7.0.7.tgz", { "dependencies": { "browserslist": "^4.25.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-HR9DZLN04Xbe6xugRH6lS4ZQH2zm/bFh/ZyRkpedZozhvh+awAfbA0P36InO4fZfDhvYfNJeNvlTf1sjwGbw/A=="], 312 | 313 | "postcss-discard-comments": ["postcss-discard-comments@7.0.4", "https://mirrors.cloud.tencent.com/npm/postcss-discard-comments/-/postcss-discard-comments-7.0.4.tgz", { "dependencies": { "postcss-selector-parser": "^7.1.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-6tCUoql/ipWwKtVP/xYiFf1U9QgJ0PUvxN7pTcsQ8Ns3Fnwq1pU5D5s1MhT/XySeLq6GXNvn37U46Ded0TckWg=="], 314 | 315 | "postcss-discard-duplicates": ["postcss-discard-duplicates@7.0.2", "https://mirrors.cloud.tencent.com/npm/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.2.tgz", { "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w=="], 316 | 317 | "postcss-discard-empty": ["postcss-discard-empty@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-discard-empty/-/postcss-discard-empty-7.0.1.tgz", { "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg=="], 318 | 319 | "postcss-discard-overridden": ["postcss-discard-overridden@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-discard-overridden/-/postcss-discard-overridden-7.0.1.tgz", { "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg=="], 320 | 321 | "postcss-merge-longhand": ["postcss-merge-longhand@7.0.5", "https://mirrors.cloud.tencent.com/npm/postcss-merge-longhand/-/postcss-merge-longhand-7.0.5.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^7.0.5" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw=="], 322 | 323 | "postcss-merge-rules": ["postcss-merge-rules@7.0.6", "https://mirrors.cloud.tencent.com/npm/postcss-merge-rules/-/postcss-merge-rules-7.0.6.tgz", { "dependencies": { "browserslist": "^4.25.1", "caniuse-api": "^3.0.0", "cssnano-utils": "^5.0.1", "postcss-selector-parser": "^7.1.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-2jIPT4Tzs8K87tvgCpSukRQ2jjd+hH6Bb8rEEOUDmmhOeTcqDg5fEFK8uKIu+Pvc3//sm3Uu6FRqfyv7YF7+BQ=="], 324 | 325 | "postcss-minify-font-values": ["postcss-minify-font-values@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-minify-font-values/-/postcss-minify-font-values-7.0.1.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ=="], 326 | 327 | "postcss-minify-gradients": ["postcss-minify-gradients@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-minify-gradients/-/postcss-minify-gradients-7.0.1.tgz", { "dependencies": { "colord": "^2.9.3", "cssnano-utils": "^5.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A=="], 328 | 329 | "postcss-minify-params": ["postcss-minify-params@7.0.4", "https://mirrors.cloud.tencent.com/npm/postcss-minify-params/-/postcss-minify-params-7.0.4.tgz", { "dependencies": { "browserslist": "^4.25.1", "cssnano-utils": "^5.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-3OqqUddfH8c2e7M35W6zIwv7jssM/3miF9cbCSb1iJiWvtguQjlxZGIHK9JRmc8XAKmE2PFGtHSM7g/VcW97sw=="], 330 | 331 | "postcss-minify-selectors": ["postcss-minify-selectors@7.0.5", "https://mirrors.cloud.tencent.com/npm/postcss-minify-selectors/-/postcss-minify-selectors-7.0.5.tgz", { "dependencies": { "cssesc": "^3.0.0", "postcss-selector-parser": "^7.1.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-x2/IvofHcdIrAm9Q+p06ZD1h6FPcQ32WtCRVodJLDR+WMn8EVHI1kvLxZuGKz/9EY5nAmI6lIQIrpo4tBy5+ug=="], 332 | 333 | "postcss-normalize-charset": ["postcss-normalize-charset@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-normalize-charset/-/postcss-normalize-charset-7.0.1.tgz", { "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ=="], 334 | 335 | "postcss-normalize-display-values": ["postcss-normalize-display-values@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.1.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ=="], 336 | 337 | "postcss-normalize-positions": ["postcss-normalize-positions@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-normalize-positions/-/postcss-normalize-positions-7.0.1.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ=="], 338 | 339 | "postcss-normalize-repeat-style": ["postcss-normalize-repeat-style@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.1.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ=="], 340 | 341 | "postcss-normalize-string": ["postcss-normalize-string@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-normalize-string/-/postcss-normalize-string-7.0.1.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ=="], 342 | 343 | "postcss-normalize-timing-functions": ["postcss-normalize-timing-functions@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.1.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg=="], 344 | 345 | "postcss-normalize-unicode": ["postcss-normalize-unicode@7.0.4", "https://mirrors.cloud.tencent.com/npm/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.4.tgz", { "dependencies": { "browserslist": "^4.25.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-LvIURTi1sQoZqj8mEIE8R15yvM+OhbR1avynMtI9bUzj5gGKR/gfZFd8O7VMj0QgJaIFzxDwxGl/ASMYAkqO8g=="], 346 | 347 | "postcss-normalize-url": ["postcss-normalize-url@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-normalize-url/-/postcss-normalize-url-7.0.1.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ=="], 348 | 349 | "postcss-normalize-whitespace": ["postcss-normalize-whitespace@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.1.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA=="], 350 | 351 | "postcss-ordered-values": ["postcss-ordered-values@7.0.2", "https://mirrors.cloud.tencent.com/npm/postcss-ordered-values/-/postcss-ordered-values-7.0.2.tgz", { "dependencies": { "cssnano-utils": "^5.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw=="], 352 | 353 | "postcss-reduce-initial": ["postcss-reduce-initial@7.0.4", "https://mirrors.cloud.tencent.com/npm/postcss-reduce-initial/-/postcss-reduce-initial-7.0.4.tgz", { "dependencies": { "browserslist": "^4.25.1", "caniuse-api": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-rdIC9IlMBn7zJo6puim58Xd++0HdbvHeHaPgXsimMfG1ijC5A9ULvNLSE0rUKVJOvNMcwewW4Ga21ngyJjY/+Q=="], 354 | 355 | "postcss-reduce-transforms": ["postcss-reduce-transforms@7.0.1", "https://mirrors.cloud.tencent.com/npm/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.1.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g=="], 356 | 357 | "postcss-selector-parser": ["postcss-selector-parser@7.1.0", "https://mirrors.cloud.tencent.com/npm/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="], 358 | 359 | "postcss-svgo": ["postcss-svgo@7.1.0", "https://mirrors.cloud.tencent.com/npm/postcss-svgo/-/postcss-svgo-7.1.0.tgz", { "dependencies": { "postcss-value-parser": "^4.2.0", "svgo": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-KnAlfmhtoLz6IuU3Sij2ycusNs4jPW+QoFE5kuuUOK8awR6tMxZQrs5Ey3BUz7nFCzT3eqyFgqkyrHiaU2xx3w=="], 360 | 361 | "postcss-unique-selectors": ["postcss-unique-selectors@7.0.4", "https://mirrors.cloud.tencent.com/npm/postcss-unique-selectors/-/postcss-unique-selectors-7.0.4.tgz", { "dependencies": { "postcss-selector-parser": "^7.1.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-pmlZjsmEAG7cHd7uK3ZiNSW6otSZ13RHuZ/4cDN/bVglS5EpF2r2oxY99SuOHa8m7AWoBCelTS3JPpzsIs8skQ=="], 362 | 363 | "postcss-value-parser": ["postcss-value-parser@4.2.0", "https://mirrors.cloud.tencent.com/npm/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], 364 | 365 | "react": ["react@18.3.1", "https://mirrors.cloud.tencent.com/npm/react/-/react-18.3.1.tgz", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="], 366 | 367 | "react-dom": ["react-dom@18.3.1", "https://mirrors.cloud.tencent.com/npm/react-dom/-/react-dom-18.3.1.tgz", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="], 368 | 369 | "require-directory": ["require-directory@2.1.1", "https://mirrors.cloud.tencent.com/npm/require-directory/-/require-directory-2.1.1.tgz", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], 370 | 371 | "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "https://mirrors.cloud.tencent.com/npm/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], 372 | 373 | "sax": ["sax@1.4.1", "https://mirrors.cloud.tencent.com/npm/sax/-/sax-1.4.1.tgz", {}, "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="], 374 | 375 | "scheduler": ["scheduler@0.23.2", "https://mirrors.cloud.tencent.com/npm/scheduler/-/scheduler-0.23.2.tgz", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], 376 | 377 | "simple-git-hooks": ["simple-git-hooks@2.13.1", "https://mirrors.cloud.tencent.com/npm/simple-git-hooks/-/simple-git-hooks-2.13.1.tgz", { "bin": { "simple-git-hooks": "cli.js" } }, "sha512-WszCLXwT4h2k1ufIXAgsbiTOazqqevFCIncOuUBZJ91DdvWcC5+OFkluWRQPrcuSYd8fjq+o2y1QfWqYMoAToQ=="], 378 | 379 | "simplebar-core": ["simplebar-core@1.3.2", "https://mirrors.cloud.tencent.com/npm/simplebar-core/-/simplebar-core-1.3.2.tgz", { "dependencies": { "lodash": "^4.17.21", "lodash-es": "^4.17.21" } }, "sha512-qKgTTuTqapjsFGkNhCjyPhysnbZGpQqNmjk0nOYjFN5ordC/Wjvg+RbYCyMSnW60l/Z0ZS82GbNltly6PMUH1w=="], 380 | 381 | "simplebar-react": ["simplebar-react@3.3.2", "https://mirrors.cloud.tencent.com/npm/simplebar-react/-/simplebar-react-3.3.2.tgz", { "dependencies": { "simplebar-core": "^1.3.2" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-ZsgcQhKLtt5ra0BRIJeApfkTBQCa1vUPA/WXI4HcYReFt+oCEOvdVz6rR/XsGJcKxTlCRPmdGx1uJIUChupo+A=="], 382 | 383 | "source-map-js": ["source-map-js@1.2.1", "https://mirrors.cloud.tencent.com/npm/source-map-js/-/source-map-js-1.2.1.tgz", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], 384 | 385 | "string-width": ["string-width@4.2.3", "https://mirrors.cloud.tencent.com/npm/string-width/-/string-width-4.2.3.tgz", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], 386 | 387 | "strip-ansi": ["strip-ansi@6.0.1", "https://mirrors.cloud.tencent.com/npm/strip-ansi/-/strip-ansi-6.0.1.tgz", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], 388 | 389 | "stylehacks": ["stylehacks@7.0.6", "https://mirrors.cloud.tencent.com/npm/stylehacks/-/stylehacks-7.0.6.tgz", { "dependencies": { "browserslist": "^4.25.1", "postcss-selector-parser": "^7.1.0" }, "peerDependencies": { "postcss": "^8.4.32" } }, "sha512-iitguKivmsueOmTO0wmxURXBP8uqOO+zikLGZ7Mm9e/94R4w5T999Js2taS/KBOnQ/wdC3jN3vNSrkGDrlnqQg=="], 390 | 391 | "svgo": ["svgo@4.0.0", "https://mirrors.cloud.tencent.com/npm/svgo/-/svgo-4.0.0.tgz", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.4.1" }, "bin": "./bin/svgo.js" }, "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw=="], 392 | 393 | "tailwindcss": ["tailwindcss@4.1.13", "https://mirrors.cloud.tencent.com/npm/tailwindcss/-/tailwindcss-4.1.13.tgz", {}, "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w=="], 394 | 395 | "tapable": ["tapable@2.2.3", "https://mirrors.cloud.tencent.com/npm/tapable/-/tapable-2.2.3.tgz", {}, "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg=="], 396 | 397 | "tar": ["tar@7.4.3", "https://mirrors.cloud.tencent.com/npm/tar/-/tar-7.4.3.tgz", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], 398 | 399 | "typescript": ["typescript@5.9.2", "https://mirrors.cloud.tencent.com/npm/typescript/-/typescript-5.9.2.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="], 400 | 401 | "undici-types": ["undici-types@7.10.0", "https://mirrors.cloud.tencent.com/npm/undici-types/-/undici-types-7.10.0.tgz", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="], 402 | 403 | "update-browserslist-db": ["update-browserslist-db@1.1.3", "https://mirrors.cloud.tencent.com/npm/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="], 404 | 405 | "util-deprecate": ["util-deprecate@1.0.2", "https://mirrors.cloud.tencent.com/npm/util-deprecate/-/util-deprecate-1.0.2.tgz", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], 406 | 407 | "wrap-ansi": ["wrap-ansi@7.0.0", "https://mirrors.cloud.tencent.com/npm/wrap-ansi/-/wrap-ansi-7.0.0.tgz", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], 408 | 409 | "y18n": ["y18n@5.0.8", "https://mirrors.cloud.tencent.com/npm/y18n/-/y18n-5.0.8.tgz", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], 410 | 411 | "yallist": ["yallist@5.0.0", "https://mirrors.cloud.tencent.com/npm/yallist/-/yallist-5.0.0.tgz", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], 412 | 413 | "yargs": ["yargs@17.7.2", "https://mirrors.cloud.tencent.com/npm/yargs/-/yargs-17.7.2.tgz", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], 414 | 415 | "yargs-parser": ["yargs-parser@21.1.1", "https://mirrors.cloud.tencent.com/npm/yargs-parser/-/yargs-parser-21.1.1.tgz", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], 416 | 417 | "zustand": ["zustand@5.0.8", "https://mirrors.cloud.tencent.com/npm/zustand/-/zustand-5.0.8.tgz", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw=="], 418 | 419 | "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.5.0", "https://mirrors.cloud.tencent.com/npm/@emnapi/core/-/core-1.5.0.tgz", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg=="], 420 | 421 | "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.5.0", "https://mirrors.cloud.tencent.com/npm/@emnapi/runtime/-/runtime-1.5.0.tgz", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], 422 | 423 | "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "https://mirrors.cloud.tencent.com/npm/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], 424 | 425 | "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "https://mirrors.cloud.tencent.com/npm/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" }, "bundled": true }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="], 426 | 427 | "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "https://mirrors.cloud.tencent.com/npm/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="], 428 | 429 | "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "https://mirrors.cloud.tencent.com/npm/tslib/-/tslib-2.8.1.tgz", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], 430 | 431 | "csso/css-tree": ["css-tree@2.2.1", "https://mirrors.cloud.tencent.com/npm/css-tree/-/css-tree-2.2.1.tgz", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], 432 | 433 | "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "https://mirrors.cloud.tencent.com/npm/mdn-data/-/mdn-data-2.0.28.tgz", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], 434 | } 435 | } 436 | -------------------------------------------------------------------------------- /chrome-extension/biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "//", 3 | "root": false 4 | } 5 | -------------------------------------------------------------------------------- /chrome-extension/build.ts: -------------------------------------------------------------------------------- 1 | import { build } from '@libs/bundle-utils' 2 | import { name } from './package.json' with { type: 'json' } 3 | 4 | build({ 5 | define: { 6 | 'process.env.WS_PORT': process.env.WS_PORT || '3030', 7 | }, 8 | entrypoints: ['./src/background/index.ts'], 9 | naming: 'background.[ext]', 10 | packageName: name, 11 | watchDir: import.meta.dirname, 12 | }) 13 | -------------------------------------------------------------------------------- /chrome-extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ai-translator/chrome-extension", 3 | "type": "module", 4 | "scripts": { 5 | "dev": "NODE_ENV=development bun ./build.ts", 6 | "build": "NODE_ENV=production bun ./build.ts" 7 | }, 8 | "dependencies": { 9 | "@libs/constants": "workspace:*" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /chrome-extension/src/background/index.ts: -------------------------------------------------------------------------------- 1 | const IS_DEV = process.env.NODE_ENV === 'development' 2 | const PORT = process.env.WS_PORT 3 | 4 | if (IS_DEV) { 5 | // No to let extension go to inactive state 6 | const keepAlive = () => setInterval(chrome.runtime.getPlatformInfo, 20e3) 7 | chrome.runtime.onStartup.addListener(keepAlive) 8 | keepAlive() 9 | const ws = new WebSocket(`ws://localhost:${PORT}`) 10 | ws.onmessage = (event) => { 11 | if (event.data === 'reload') { 12 | chrome.runtime.reload() 13 | } 14 | } 15 | 16 | chrome.runtime.onInstalled.addListener((details) => { 17 | if (details.reason === chrome.runtime.OnInstalledReason.UPDATE) { 18 | chrome.tabs.reload() 19 | } 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /chrome-extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ai-translator", 3 | "author": "Plumbiu", 4 | "description": "Chrome AI Translator extension.", 5 | "type": "module", 6 | "license": "MIT", 7 | "scripts": { 8 | "build": "WORKSPACE_ROOT=$(pwd) bun --filter '@ai-translator/*' build && bun run build:zip", 9 | "build:bundle-utils": "bun --filter '@libs/bundle-utils' build", 10 | "build:libs": "bun --filter '@libs/*' build", 11 | "build:mainfest": "bun ./scripts/build-manifest.ts", 12 | "build:zip": "bun ./scripts/zip.ts", 13 | "clear:dist": "find . -type d -name \"dist\" -not -path \"*/node_modules/*\" -exec rm -rf {} + 2>/dev/null || true", 14 | "dev": "WORKSPACE_ROOT=$(pwd) bun --filter '!(./)' dev", 15 | "lint": "biome check . --write", 16 | "prebuild": "bun run build:bundle-utils && bun run build:libs && bun run build:mainfest", 17 | "predev": "bun run build:bundle-utils && bun run build:mainfest", 18 | "prepare": "bun run build:mainfest && simple-git-hooks" 19 | }, 20 | "workspaces": [ 21 | "chrome-extension", 22 | "packages/*", 23 | "pages/*" 24 | ], 25 | "devDependencies": { 26 | "@biomejs/biome": "2.2.3", 27 | "@libs/bundle-utils": "workspace:*", 28 | "@tailwindcss/postcss": "^4.1.13", 29 | "@types/adm-zip": "0.5.7", 30 | "@types/bun": "^1.2.21", 31 | "@types/chrome": "latest", 32 | "@types/dom-chromium-ai": "0.0.9", 33 | "@types/minimist": "^1.2.5", 34 | "@types/react": "^18.3.18", 35 | "@types/react-dom": "^18.3.5", 36 | "adm-zip": "0.5.16", 37 | "cssnano": "^7.1.1", 38 | "minimist": "^1.2.8", 39 | "picocolors": "^1.1.1", 40 | "postcss": "^8.5.6", 41 | "simple-git-hooks": "^2.13.1" 42 | }, 43 | "lint-staged": { 44 | "*": [ 45 | "bun lint" 46 | ] 47 | }, 48 | "simple-git-hooks": { 49 | "pre-commit": "bunx lint-staged" 50 | }, 51 | "dependencies": { 52 | "daisyui": "^5.1.10", 53 | "tailwindcss": "^4.1.13" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/bundle-utils/biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "//", 3 | "root": false 4 | } 5 | -------------------------------------------------------------------------------- /packages/bundle-utils/build.ts: -------------------------------------------------------------------------------- 1 | import { name } from './package.json' with { type: 'json' } 2 | import { build } from './src' 3 | 4 | build({ 5 | enforeNotWatch: true, 6 | entrypoints: ['./src/index.ts'], 7 | packageName: name, 8 | target: 'bun', 9 | watchDir: import.meta.dirname, 10 | minify: false, 11 | }) 12 | -------------------------------------------------------------------------------- /packages/bundle-utils/dev.ts: -------------------------------------------------------------------------------- 1 | import { watch } from 'node:fs' 2 | import path from 'node:path' 3 | import Bun from 'bun' 4 | 5 | const WORKSPACE_ROOT = process.env.WORKSPACE_ROOT || process.cwd() 6 | 7 | Bun.serve({ 8 | fetch(req, server) { 9 | if (server.upgrade(req)) { 10 | return 11 | } 12 | return new Response('WebSocket server', { status: 200 }) 13 | }, 14 | port: process.env.WS_PORT || 3030, 15 | websocket: { 16 | close() {}, 17 | message() {}, 18 | open(ws) { 19 | const distPath = path.resolve(WORKSPACE_ROOT, 'dist') 20 | const stylesPath = path.resolve(WORKSPACE_ROOT, 'styles') 21 | const manifestPath = path.resolve(WORKSPACE_ROOT, 'manifest.json') 22 | const reloadPlugin = () => ws.send('reload') 23 | 24 | watch(distPath, { recursive: true }, reloadPlugin) 25 | watch(stylesPath, { recursive: true }, reloadPlugin) 26 | watch(manifestPath, { recursive: true }, reloadPlugin) 27 | }, 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /packages/bundle-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@libs/bundle-utils", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "main": "./dist/index.js", 6 | "types": "./dist/index.d.ts", 7 | "files": [ 8 | "dist" 9 | ], 10 | "scripts": { 11 | "dev": "bun ./dev.ts", 12 | "build": "bun ./build.ts" 13 | }, 14 | "devDependencies": { 15 | "bun-plugin-dts": "^0.3.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/bundle-utils/src/index.ts: -------------------------------------------------------------------------------- 1 | import { watch } from 'node:fs' 2 | import path from 'node:path' 3 | import Bun from 'bun' 4 | import dtsPlugin from 'bun-plugin-dts' 5 | import { createColors } from 'picocolors' 6 | 7 | const color = createColors(true) 8 | 9 | function getEnv(key: string) { 10 | return process.env[key] || Bun.env[key] 11 | } 12 | 13 | interface CustomBuildConfig { 14 | packageName: string 15 | watchDir: string 16 | enforeNotWatch?: boolean 17 | } 18 | 19 | export function build(options: Bun.BuildConfig & CustomBuildConfig) { 20 | const { packageName } = options 21 | const IS_DEV = getEnv('NODE_ENV') === 'development' 22 | const WORKSPACE_ROOT = getEnv('WORKSPACE_ROOT') || process.cwd() 23 | 24 | const isLibs = packageName.startsWith('@libs/') 25 | const outdir = isLibs ? './dist' : path.resolve(WORKSPACE_ROOT, './dist') 26 | 27 | function _build() { 28 | const plugins = options.plugins || [] 29 | 30 | if (isLibs) { 31 | plugins.push(dtsPlugin()) 32 | } 33 | Bun.build({ 34 | minify: !IS_DEV, 35 | outdir, 36 | plugins, 37 | throw: false, 38 | ...options, 39 | }).then((result) => { 40 | if (packageName.startsWith('@ai-translator/')) { 41 | for (const item of result.outputs) { 42 | console.log( 43 | color.cyan(path.relative(WORKSPACE_ROOT, item.path)) + 44 | ': ' + 45 | color.green((item.size / 1024).toFixed(2) + 'kb'), 46 | ) 47 | } 48 | } 49 | }) 50 | } 51 | 52 | _build() 53 | 54 | if (IS_DEV && !options.enforeNotWatch) { 55 | const watcher = watch( 56 | path.resolve(options.watchDir, './src'), 57 | { recursive: true }, 58 | _build, 59 | ) 60 | 61 | process.on('SIGINT', () => { 62 | watcher.close() 63 | process.exit(0) 64 | }) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /packages/constants/biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "//", 3 | "root": false 4 | } 5 | -------------------------------------------------------------------------------- /packages/constants/build.ts: -------------------------------------------------------------------------------- 1 | import { build } from '@libs/bundle-utils' 2 | import { name } from '@libs/constants/package.json' with { type: 'json' } 3 | 4 | build({ 5 | entrypoints: ['./src/index.ts'], 6 | packageName: name, 7 | watchDir: import.meta.dirname, 8 | }) 9 | -------------------------------------------------------------------------------- /packages/constants/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@libs/constants", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "main": "./dist/index.js", 6 | "types": "./dist/index.d.ts", 7 | "files": [ 8 | "dist" 9 | ], 10 | "scripts": { 11 | "dev": "NODE_ENV=development bun ./build.ts", 12 | "build": "NODE_ENV=production bun ./build.ts" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/constants/src/index.ts: -------------------------------------------------------------------------------- 1 | export const SelectAutoDetectValue = 'auto' 2 | 3 | export const DelayTime = 100 4 | 5 | export const TranslateTypeEnum = { 6 | Detect: 'detect', 7 | Download: 'download', 8 | Translate: 'translate', 9 | } 10 | -------------------------------------------------------------------------------- /pages/content/biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "//", 3 | "root": false 4 | } 5 | -------------------------------------------------------------------------------- /pages/content/build.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs/promises' 2 | import { build } from '@libs/bundle-utils' 3 | import postcssTailwindcssPlugin from '@tailwindcss/postcss' 4 | import cssnano from 'cssnano' 5 | import postcss from 'postcss' 6 | import { name } from './package.json' with { type: 'json' } 7 | 8 | const IS_PRO = process.env.NODE_ENV === 'production' 9 | 10 | function escapeSpecialChars(str: string) { 11 | return str.replace(/[/[\]%:#!]/g, (char: string) => '\\' + char) 12 | } 13 | 14 | build({ 15 | define: { 16 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), 17 | }, 18 | entrypoints: ['./src/main.tsx'], 19 | naming: 'content.[ext]', 20 | packageName: name, 21 | watchDir: import.meta.dirname, 22 | plugins: [ 23 | { 24 | name: 'css:loader', 25 | setup(build) { 26 | build.onLoad({ filter: /.css$/ }, async ({ path }) => { 27 | const fileContent = await fs.readFile(path, 'utf-8') 28 | if (path.includes('node_modules')) { 29 | return { 30 | contents: `export default \`${escapeSpecialChars(fileContent)}\``, 31 | loader: 'js', 32 | } 33 | } 34 | if (path.endsWith('tailwind.css')) { 35 | const plugins: postcss.AcceptedPlugin[] = [ 36 | postcssTailwindcssPlugin({}), 37 | { 38 | postcssPlugin: 'postcss:transfrom-root', 39 | Rule(rule) { 40 | const selectors = rule.selectors 41 | const finalSelectors = new Set() 42 | for (const selector of selectors) { 43 | if (selector === ':root' || selector === 'html') { 44 | finalSelectors.add(':host') 45 | } else { 46 | finalSelectors.add(selector) 47 | } 48 | } 49 | rule.selectors = [...finalSelectors] 50 | }, 51 | }, 52 | ] 53 | if (IS_PRO) { 54 | plugins.push(cssnano()) 55 | } 56 | const content = (await postcss(plugins).process(fileContent)) 57 | .content 58 | return { 59 | contents: `export default \`${escapeSpecialChars(content)}\``, 60 | loader: 'js', 61 | } 62 | } 63 | return { 64 | contents: fileContent, 65 | loader: 'css', 66 | } 67 | }) 68 | }, 69 | }, 70 | ], 71 | throw: true, 72 | }) 73 | -------------------------------------------------------------------------------- /pages/content/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css' { 2 | const content: string 3 | export default content 4 | } 5 | -------------------------------------------------------------------------------- /pages/content/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ai-translator/content", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "scripts": { 6 | "dev": "NODE_ENV=development bun ./build.ts", 7 | "build": "NODE_ENV=production bun ./build.ts" 8 | }, 9 | "dependencies": { 10 | "@floating-ui/dom": "^1.7.4", 11 | "@libs/constants": "workspace:*", 12 | "clsx": "^2.1.1", 13 | "react": "^18.3.1", 14 | "react-dom": "^18.3.1", 15 | "simplebar-react": "^3.3.2", 16 | "zustand": "^5.0.8" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pages/content/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react' 2 | import barStyle from 'simplebar-react/dist/simplebar.min.css' 3 | import { TranslateIcon } from './components/icons' 4 | import { LeftPanleItem, RightPanleItem } from './components/PanelItem' 5 | import TooltipHeader from './components/TooltipHeader' 6 | import Button from './components/ui/Button' 7 | import useLatest from './hooks/useLatest' 8 | import useTheme from './hooks/useTheme' 9 | import useTransltor from './hooks/useTransltor' 10 | import useUpdateEffect from './hooks/useUpdateEffect' 11 | import { useTranslationStore } from './store' 12 | import tailwindcssStyle from './tailwind.css' 13 | import { isTargetInContainer } from './utils/dom' 14 | 15 | function App() { 16 | const { 17 | buttonVisible, 18 | setButtonVisible, 19 | slotVisible, 20 | setSlotVisible, 21 | sourceLanguage, 22 | targetLanguage, 23 | } = useTranslationStore() 24 | 25 | const latestButtonVisible = useLatest(buttonVisible) 26 | const latestSlotVisible = useLatest(slotVisible) 27 | 28 | const { 29 | showFloatButton, 30 | translateAndShowSlot, 31 | translate, 32 | selectionInfoCache, 33 | } = useTransltor() 34 | 35 | const { systemTheme } = useTheme() 36 | 37 | const wrapperDomRef = useRef(null) 38 | 39 | useEffect(() => { 40 | const handleMouseUp = async (e: Event) => { 41 | // button only show when both button and slot are not visible 42 | if (latestButtonVisible.current || latestSlotVisible.current) { 43 | return 44 | } 45 | if (isTargetInContainer(e)) { 46 | return 47 | } 48 | 49 | showFloatButton() 50 | } 51 | 52 | const handleMousedown = (e: Event) => { 53 | if (!(latestButtonVisible.current || latestSlotVisible.current)) { 54 | return 55 | } 56 | if (isTargetInContainer(e)) { 57 | return 58 | } 59 | if (latestSlotVisible.current) { 60 | setSlotVisible(false) 61 | } 62 | if (latestButtonVisible.current) { 63 | setButtonVisible(false) 64 | } 65 | } 66 | 67 | document.addEventListener('mouseup', handleMouseUp) 68 | document.addEventListener('mousedown', handleMousedown) 69 | 70 | return () => { 71 | document.removeEventListener('mouseup', handleMouseUp) 72 | document.removeEventListener('mousedown', handleMousedown) 73 | } 74 | }, []) 75 | 76 | useUpdateEffect(() => { 77 | translate(selectionInfoCache.current?.text) 78 | }, [sourceLanguage, targetLanguage]) 79 | 80 | useEffect(() => { 81 | const rootElement = wrapperDomRef.current 82 | if (rootElement) { 83 | rootElement.setAttribute('data-theme', systemTheme) 84 | } 85 | }, [systemTheme]) 86 | 87 | return ( 88 | <> 89 | 90 | 91 |
92 | {buttonVisible ? ( 93 | 96 | ) : null} 97 | {slotVisible ? ( 98 |
99 | 100 |
101 | 102 | 103 |
104 |
105 | ) : null} 106 |
107 | 108 | ) 109 | } 110 | 111 | export default App 112 | -------------------------------------------------------------------------------- /pages/content/src/components/CopyButton.tsx: -------------------------------------------------------------------------------- 1 | import { memo, useCallback, useState } from 'react' 2 | import { CheckIcon, CopyIcon } from './icons' 3 | import Button from './ui/Button' 4 | 5 | interface CopyButtonProps { 6 | text: string 7 | } 8 | const CopyButton = memo(({ text }: CopyButtonProps) => { 9 | const [isCopied, setIsCopied] = useState(false) 10 | 11 | const handleCopy = useCallback(async () => { 12 | await navigator.clipboard.writeText(text) 13 | setIsCopied(true) 14 | setTimeout(() => { 15 | setIsCopied(false) 16 | }, 1000) 17 | }, [text]) 18 | return ( 19 | 22 | ) 23 | }) 24 | 25 | export default CopyButton 26 | -------------------------------------------------------------------------------- /pages/content/src/components/LanguageSelect.tsx: -------------------------------------------------------------------------------- 1 | import { SelectAutoDetectValue } from '@libs/constants' 2 | import { useMemo } from 'react' 3 | import { useTranslationStore } from '../store' 4 | import { getLocalName, supportsLanguages } from '../utils/locale' 5 | 6 | // 生成目标语言选项 7 | const targetLanguageOptions = [navigator.language, ...supportsLanguages].map( 8 | (language) => ({ 9 | label: `${getLocalName(language)} (${language})`, 10 | value: language, 11 | }), 12 | ) 13 | 14 | const targetLanguageOptionDom = targetLanguageOptions.map((item) => ( 15 | 18 | )) 19 | 20 | export const SourceLanguageSelectId = '__ai_translator_source_language_select__' 21 | 22 | export function SourceLanguageSelect() { 23 | const sourceLanguage = useTranslationStore((state) => state.sourceLanguage) 24 | const setSourceLanguage = useTranslationStore( 25 | (state) => state.setSourceLanguage, 26 | ) 27 | const detecResult = useTranslationStore((state) => state.detectResult) 28 | 29 | const detectedLanguage = useMemo( 30 | () => detecResult[0].detectedLanguage, 31 | [detecResult], 32 | ) 33 | 34 | const sourceLanguageOptionDom = useMemo( 35 | () => 36 | [ 37 | { 38 | label: `Auto${detectedLanguage ? ` (${getLocalName(detectedLanguage)})` : ''}`, 39 | value: SelectAutoDetectValue, 40 | }, 41 | ...targetLanguageOptions, 42 | ].map((item) => ( 43 | 46 | )), 47 | [detectedLanguage], 48 | ) 49 | return ( 50 | 60 | ) 61 | } 62 | 63 | export const TargetLanguageSelectId = '__ai_translator_target_language_select__' 64 | 65 | export function TargetLanguageSelect() { 66 | const targetLanguage = useTranslationStore((state) => state.targetLanguage) 67 | const setTargetLanguage = useTranslationStore( 68 | (state) => state.setTargetLanguage, 69 | ) 70 | return ( 71 | 83 | ) 84 | } 85 | 86 | export function getLanguageSelectDom() { 87 | return { 88 | sourceLanguageSelectDom: document.querySelector( 89 | '.' + SourceLanguageSelectId, 90 | ), 91 | targetLanguageSelectDom: document.querySelector( 92 | '.' + TargetLanguageSelectId, 93 | ), 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /pages/content/src/components/PanelItem.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx' 2 | import type { CSSProperties } from 'react' 3 | import { memo } from 'react' 4 | import SimpleBar from 'simplebar-react' 5 | import { useTranslationStore } from '../store' 6 | import CopyButton from './CopyButton' 7 | import SpeechButton from './SpeechButton' 8 | 9 | const SimpleBarStyle: CSSProperties = { 10 | margin: 2, 11 | maxHeight: '50vh', 12 | minHeight: 64, 13 | minWidth: 36, 14 | userSelect: 'text', 15 | } 16 | 17 | const panelWrapperClassName = 18 | 'flex flex-col justify-between gap-2 w-1/2 shrink-1 grow-0' 19 | const panelBottomClassName = 20 | 'flex justify-end gap-2 px-[10px] pb-[12px] overflow-hidden' 21 | 22 | export const LeftPanleItem = memo(() => { 23 | const selectedText = useTranslationStore((state) => state.selectedText) 24 | const sourceLanguage = useTranslationStore((state) => state.sourceLanguage) 25 | return ( 26 |
27 |
28 | {selectedText} 29 |
30 |
31 | 32 | 33 |
34 |
35 | ) 36 | }) 37 | 38 | export const RightPanleItem = memo(() => { 39 | const slotStyle = useTranslationStore((state) => state.slotStyle) 40 | const translation = useTranslationStore((state) => state.translation) 41 | const targetLanguage = useTranslationStore((state) => state.targetLanguage) 42 | 43 | return ( 44 |
45 |
46 | {translation} 47 |
48 |
49 | 50 | 51 |
52 |
53 | ) 54 | }) 55 | -------------------------------------------------------------------------------- /pages/content/src/components/SpeechButton.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from 'react' 2 | import useSpeech from '../hooks/useSpeech' 3 | import { MutedIcon, SoundIcon } from './icons' 4 | import Button from './ui/Button' 5 | 6 | interface SpeechButtonProps { 7 | text: string 8 | lang: string 9 | } 10 | 11 | const SpeechButton = memo(({ text, lang }: SpeechButtonProps) => { 12 | const state = useSpeech(text, { lang }) 13 | 14 | function handleSpeech() { 15 | if (state.isPlaying) { 16 | state.stop() 17 | } else { 18 | state.speak() 19 | } 20 | } 21 | 22 | return ( 23 | 26 | ) 27 | }) 28 | 29 | export default SpeechButton 30 | -------------------------------------------------------------------------------- /pages/content/src/components/TooltipHeader.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from 'react' 2 | import { useTranslationStore } from '../store' 3 | import { ArrowRightOIcon, LoadingIcon } from './icons' 4 | import { SourceLanguageSelect, TargetLanguageSelect } from './LanguageSelect' 5 | 6 | const TooltipHeader = memo(() => { 7 | const loading = useTranslationStore((state) => state.loading) 8 | return ( 9 |
10 | 11 | 12 | 13 | 17 |
18 | ) 19 | }) 20 | 21 | export default TooltipHeader 22 | -------------------------------------------------------------------------------- /pages/content/src/components/icons/index.tsx: -------------------------------------------------------------------------------- 1 | import type { SVGProps } from 'react' 2 | 3 | export function CheckIcon(props: SVGProps) { 4 | return ( 5 | 12 | {/* Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE */} 13 | 17 | 18 | ) 19 | } 20 | 21 | export function CopyIcon(props: SVGProps) { 22 | return ( 23 | 30 | {/* Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE */} 31 | 35 | 36 | ) 37 | } 38 | 39 | export function ArrowRightOIcon(props: SVGProps) { 40 | return ( 41 | 48 | {/* Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE */} 49 | 53 | 54 | ) 55 | } 56 | 57 | export function LoadingIcon(props: SVGProps) { 58 | return ( 59 | 66 | {/* Icon from Material Line Icons by Vjacheslav Trushkin - https://github.com/cyberalien/line-md/blob/master/license.txt */} 67 | 74 | 79 | 85 | 92 | 93 | 99 | 105 | 106 | 107 | 108 | ) 109 | } 110 | 111 | export function MutedIcon(props: SVGProps) { 112 | return ( 113 | 120 | {/* Icon from Garden SVG Icons by Zendesk - https://github.com/zendeskgarden/svg-icons/blob/main/LICENSE.md */} 121 | 127 | 128 | ) 129 | } 130 | 131 | export function SoundIcon(props: SVGProps) { 132 | return ( 133 | 140 | {/* Icon from Garden SVG Icons by Zendesk - https://github.com/zendeskgarden/svg-icons/blob/main/LICENSE.md */} 141 | 147 | 148 | ) 149 | } 150 | 151 | export function TranslateIcon(props: SVGProps) { 152 | return ( 153 | 160 | {/* Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE */} 161 | 165 | 166 | ) 167 | } 168 | -------------------------------------------------------------------------------- /pages/content/src/components/ui/Button.tsx: -------------------------------------------------------------------------------- 1 | import { clsx } from 'clsx' 2 | 3 | export default function Button({ 4 | className, 5 | ...result 6 | }: React.DetailedHTMLProps< 7 | React.ButtonHTMLAttributes, 8 | HTMLButtonElement 9 | >) { 10 | return ( 11 |