From fa07b340e77de0b06f4db7229f8ee8821cb82962 Mon Sep 17 00:00:00 2001 From: Cccc_ Date: Mon, 4 May 2026 20:33:22 +0800 Subject: [PATCH] feat(webui): totally convert to new webui --- .env.example | 1 - .gitignore | 7 +- README.md | 9 +- apps/frontend/.env.development | 2 - apps/frontend/.env.production | 3 - apps/frontend/.prettierignore | 6 +- apps/frontend/.prettierrc | 9 - .../.prettierrc.json | 0 apps/frontend/README.md | 26 + .../components.json | 0 apps/frontend/eslint.config.js | 81 +- apps/frontend/index.html | 7 +- apps/frontend/package-lock.json | 4314 ----------------- apps/frontend/package.json | 41 +- .../{new-frontend => frontend}/pnpm-lock.yaml | 0 apps/frontend/postcss.config.js | 6 - apps/frontend/public/favicon.svg | 21 +- .../public/icons.svg | 0 apps/frontend/public/vite.svg | 1 - apps/frontend/src/App.vue | 147 +- apps/frontend/src/antd-theme.js | 248 - apps/frontend/src/api/client.js | 75 - .../src/api/client.ts | 0 apps/frontend/src/api/index.js | 258 - .../src/api/index.ts | 0 .../src/api/types.ts | 0 .../src/app/auth.ts | 0 .../src/app/router.ts | 0 .../src/app/theme.test.ts | 0 .../src/app/theme.ts | 0 .../src/assets/hero.png | Bin apps/frontend/src/assets/vue.svg | 1 - .../src/components/AppLayout.vue | 0 .../frontend/src/components/CrontabEditor.vue | 509 -- .../src/components/FieldConfigEditor.vue | 277 -- .../frontend/src/components/FieldTreeNode.vue | 630 --- apps/frontend/src/components/Layout.vue | 41 - apps/frontend/src/components/Navbar.vue | 473 -- apps/frontend/src/components/QRCodeModal.vue | 323 -- .../src/components/StateBlock.vue | 0 .../src/components/common/EmptyState.vue | 110 - .../src/components/common/LoadingState.vue | 87 - .../src/components/common/StatsCard.vue | 188 - .../templates/TemplateConfigEditor.vue | 0 .../templates/TemplateFieldNode.vue | 0 .../templates/template-config.test.ts | 0 .../components/templates/template-config.ts | 0 .../src/components/ui.ts | 0 .../src/components/ui/button/Button.vue | 0 .../src/components/ui/button/index.ts | 0 .../src/components/ui/dialog/Dialog.vue | 0 .../src/components/ui/dialog/DialogClose.vue | 0 .../components/ui/dialog/DialogContent.vue | 0 .../ui/dialog/DialogDescription.vue | 0 .../src/components/ui/dialog/DialogFooter.vue | 0 .../src/components/ui/dialog/DialogHeader.vue | 0 .../components/ui/dialog/DialogOverlay.vue | 0 .../ui/dialog/DialogScrollContent.vue | 0 .../src/components/ui/dialog/DialogTitle.vue | 0 .../components/ui/dialog/DialogTrigger.vue | 0 .../src/components/ui/dialog/index.ts | 0 .../src/components/ui/tooltip/Tooltip.vue | 0 .../components/ui/tooltip/TooltipContent.vue | 0 .../components/ui/tooltip/TooltipProvider.vue | 0 .../components/ui/tooltip/TooltipTrigger.vue | 0 .../src/components/ui/tooltip/index.ts | 0 .../src/composables/useAsyncAction.js | 84 - .../frontend/src/composables/useBreakpoint.js | 65 - .../frontend/src/composables/usePollStatus.js | 124 - apps/frontend/src/composables/useTheme.js | 106 - .../src/composables/useTokenMonitor.js | 190 - .../src/lib/utils.ts | 0 apps/frontend/src/main.js | 53 - apps/{new-frontend => frontend}/src/main.ts | 0 apps/frontend/src/router/index.js | 162 - apps/frontend/src/stores/admin.js | 62 - apps/frontend/src/stores/auth.js | 133 - apps/frontend/src/stores/checkIn.js | 96 - apps/frontend/src/stores/task.js | 164 - apps/frontend/src/stores/template.js | 169 - apps/frontend/src/stores/user.js | 94 - apps/frontend/src/style.css | 1341 +---- .../src/utils/format.ts | 0 apps/frontend/src/utils/helpers.js | 145 - apps/frontend/src/views/DashboardView.vue | 943 ++-- apps/frontend/src/views/LoginView.vue | 732 +-- apps/frontend/src/views/NotFoundView.vue | 40 +- .../src/views/PendingApprovalView.vue | 409 +- apps/frontend/src/views/RecordsView.vue | 344 +- apps/frontend/src/views/SettingsView.vue | 423 +- apps/frontend/src/views/TaskRecordsView.vue | 514 +- apps/frontend/src/views/TasksView.vue | 1207 ++--- .../src/views/admin/AdminLogsView.vue | 0 .../src/views/admin/AdminRecordsView.vue | 0 .../src/views/admin/AdminStatsView.vue | 0 .../src/views/admin/AdminTemplatesView.vue | 0 .../src/views/admin/AdminUsersView.vue | 0 apps/frontend/src/views/admin/LogsView.vue | 134 - apps/frontend/src/views/admin/RecordsView.vue | 190 - apps/frontend/src/views/admin/StatsView.vue | 181 - .../src/views/admin/TemplatesView.vue | 796 --- apps/frontend/src/views/admin/UsersView.vue | 607 --- apps/frontend/tailwind.config.js | 98 - .../tsconfig.app.json | 0 apps/{new-frontend => frontend}/tsconfig.json | 0 .../tsconfig.node.json | 0 apps/frontend/vite.config.js | 45 - .../{new-frontend => frontend}/vite.config.ts | 1 + apps/new-frontend/.gitignore | 24 - apps/new-frontend/.prettierignore | 4 - apps/new-frontend/README.md | 5 - apps/new-frontend/eslint.config.js | 65 - apps/new-frontend/index.html | 13 - apps/new-frontend/package.json | 44 - apps/new-frontend/public/favicon.svg | 1 - apps/new-frontend/src/App.vue | 72 - apps/new-frontend/src/style.css | 197 - apps/new-frontend/src/views/DashboardView.vue | 432 -- apps/new-frontend/src/views/LoginView.vue | 256 - apps/new-frontend/src/views/NotFoundView.vue | 16 - .../src/views/PendingApprovalView.vue | 65 - apps/new-frontend/src/views/RecordsView.vue | 127 - apps/new-frontend/src/views/SettingsView.vue | 168 - .../src/views/TaskRecordsView.vue | 109 - apps/new-frontend/src/views/TasksView.vue | 427 -- docs/architecture.md | 15 +- docs/deployment.md | 9 +- docs/development.md | 148 +- main.py | 12 +- 129 files changed, 1938 insertions(+), 17824 deletions(-) delete mode 100644 apps/frontend/.env.development delete mode 100644 apps/frontend/.env.production delete mode 100644 apps/frontend/.prettierrc rename apps/{new-frontend => frontend}/.prettierrc.json (100%) create mode 100644 apps/frontend/README.md rename apps/{new-frontend => frontend}/components.json (100%) delete mode 100644 apps/frontend/package-lock.json rename apps/{new-frontend => frontend}/pnpm-lock.yaml (100%) delete mode 100644 apps/frontend/postcss.config.js rename apps/{new-frontend => frontend}/public/icons.svg (100%) delete mode 100644 apps/frontend/public/vite.svg delete mode 100644 apps/frontend/src/antd-theme.js delete mode 100644 apps/frontend/src/api/client.js rename apps/{new-frontend => frontend}/src/api/client.ts (100%) delete mode 100644 apps/frontend/src/api/index.js rename apps/{new-frontend => frontend}/src/api/index.ts (100%) rename apps/{new-frontend => frontend}/src/api/types.ts (100%) rename apps/{new-frontend => frontend}/src/app/auth.ts (100%) rename apps/{new-frontend => frontend}/src/app/router.ts (100%) rename apps/{new-frontend => frontend}/src/app/theme.test.ts (100%) rename apps/{new-frontend => frontend}/src/app/theme.ts (100%) rename apps/{new-frontend => frontend}/src/assets/hero.png (100%) delete mode 100644 apps/frontend/src/assets/vue.svg rename apps/{new-frontend => frontend}/src/components/AppLayout.vue (100%) delete mode 100644 apps/frontend/src/components/CrontabEditor.vue delete mode 100644 apps/frontend/src/components/FieldConfigEditor.vue delete mode 100644 apps/frontend/src/components/FieldTreeNode.vue delete mode 100644 apps/frontend/src/components/Layout.vue delete mode 100644 apps/frontend/src/components/Navbar.vue delete mode 100644 apps/frontend/src/components/QRCodeModal.vue rename apps/{new-frontend => frontend}/src/components/StateBlock.vue (100%) delete mode 100644 apps/frontend/src/components/common/EmptyState.vue delete mode 100644 apps/frontend/src/components/common/LoadingState.vue delete mode 100644 apps/frontend/src/components/common/StatsCard.vue rename apps/{new-frontend => frontend}/src/components/templates/TemplateConfigEditor.vue (100%) rename apps/{new-frontend => frontend}/src/components/templates/TemplateFieldNode.vue (100%) rename apps/{new-frontend => frontend}/src/components/templates/template-config.test.ts (100%) rename apps/{new-frontend => frontend}/src/components/templates/template-config.ts (100%) rename apps/{new-frontend => frontend}/src/components/ui.ts (100%) rename apps/{new-frontend => frontend}/src/components/ui/button/Button.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/button/index.ts (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/Dialog.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/DialogClose.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/DialogContent.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/DialogDescription.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/DialogFooter.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/DialogHeader.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/DialogOverlay.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/DialogScrollContent.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/DialogTitle.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/DialogTrigger.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/dialog/index.ts (100%) rename apps/{new-frontend => frontend}/src/components/ui/tooltip/Tooltip.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/tooltip/TooltipContent.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/tooltip/TooltipProvider.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/tooltip/TooltipTrigger.vue (100%) rename apps/{new-frontend => frontend}/src/components/ui/tooltip/index.ts (100%) delete mode 100644 apps/frontend/src/composables/useAsyncAction.js delete mode 100644 apps/frontend/src/composables/useBreakpoint.js delete mode 100644 apps/frontend/src/composables/usePollStatus.js delete mode 100644 apps/frontend/src/composables/useTheme.js delete mode 100644 apps/frontend/src/composables/useTokenMonitor.js rename apps/{new-frontend => frontend}/src/lib/utils.ts (100%) delete mode 100644 apps/frontend/src/main.js rename apps/{new-frontend => frontend}/src/main.ts (100%) delete mode 100644 apps/frontend/src/router/index.js delete mode 100644 apps/frontend/src/stores/admin.js delete mode 100644 apps/frontend/src/stores/auth.js delete mode 100644 apps/frontend/src/stores/checkIn.js delete mode 100644 apps/frontend/src/stores/task.js delete mode 100644 apps/frontend/src/stores/template.js delete mode 100644 apps/frontend/src/stores/user.js rename apps/{new-frontend => frontend}/src/utils/format.ts (100%) delete mode 100644 apps/frontend/src/utils/helpers.js rename apps/{new-frontend => frontend}/src/views/admin/AdminLogsView.vue (100%) rename apps/{new-frontend => frontend}/src/views/admin/AdminRecordsView.vue (100%) rename apps/{new-frontend => frontend}/src/views/admin/AdminStatsView.vue (100%) rename apps/{new-frontend => frontend}/src/views/admin/AdminTemplatesView.vue (100%) rename apps/{new-frontend => frontend}/src/views/admin/AdminUsersView.vue (100%) delete mode 100644 apps/frontend/src/views/admin/LogsView.vue delete mode 100644 apps/frontend/src/views/admin/RecordsView.vue delete mode 100644 apps/frontend/src/views/admin/StatsView.vue delete mode 100644 apps/frontend/src/views/admin/TemplatesView.vue delete mode 100644 apps/frontend/src/views/admin/UsersView.vue delete mode 100644 apps/frontend/tailwind.config.js rename apps/{new-frontend => frontend}/tsconfig.app.json (100%) rename apps/{new-frontend => frontend}/tsconfig.json (100%) rename apps/{new-frontend => frontend}/tsconfig.node.json (100%) delete mode 100644 apps/frontend/vite.config.js rename apps/{new-frontend => frontend}/vite.config.ts (96%) delete mode 100644 apps/new-frontend/.gitignore delete mode 100644 apps/new-frontend/.prettierignore delete mode 100644 apps/new-frontend/README.md delete mode 100644 apps/new-frontend/eslint.config.js delete mode 100644 apps/new-frontend/index.html delete mode 100644 apps/new-frontend/package.json delete mode 100644 apps/new-frontend/public/favicon.svg delete mode 100644 apps/new-frontend/src/App.vue delete mode 100644 apps/new-frontend/src/style.css delete mode 100644 apps/new-frontend/src/views/DashboardView.vue delete mode 100644 apps/new-frontend/src/views/LoginView.vue delete mode 100644 apps/new-frontend/src/views/NotFoundView.vue delete mode 100644 apps/new-frontend/src/views/PendingApprovalView.vue delete mode 100644 apps/new-frontend/src/views/RecordsView.vue delete mode 100644 apps/new-frontend/src/views/SettingsView.vue delete mode 100644 apps/new-frontend/src/views/TaskRecordsView.vue delete mode 100644 apps/new-frontend/src/views/TasksView.vue diff --git a/.env.example b/.env.example index 9da157c..5b921d7 100644 --- a/.env.example +++ b/.env.example @@ -60,4 +60,3 @@ TOKEN_CHECK_INTERVAL_MINUTES=30 # 会话数据清理间隔(小时) SESSION_CLEANUP_INTERVAL_HOURS=24 - diff --git a/.gitignore b/.gitignore index f827d11..6a76f8c 100644 --- a/.gitignore +++ b/.gitignore @@ -53,9 +53,10 @@ Thumbs.db apps/frontend/node_modules/ apps/frontend/dist/ apps/frontend/.vite/ -apps/new-frontend/node_modules/ -apps/new-frontend/dist/ -apps/new-frontend/.vite/ + +# 本地验证产物 +.playwright-cli/ +output/ .claude .codex diff --git a/README.md b/README.md index 318fd22..23613e2 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ## 技术栈 **后端**: FastAPI + SQLAlchemy + APScheduler + Selenium -**前端**: Vue 3 + Ant Design Vue + Pinia +**前端**: Vue 3 + TypeScript + shadcn-vue + Tailwind **数据库**: SQLite ## 快速开始 @@ -28,7 +28,8 @@ - Python 3.9+ - uv -- Node.js 16+ +- Node.js 20+ +- pnpm - Chrome 浏览器 ### 安装运行 @@ -40,8 +41,8 @@ uv run python main.py backend # 前端 cd apps/frontend -npm install -npm run dev +pnpm install +pnpm dev # 创建管理员 uv run python apps/backend/scripts/create_admin.py diff --git a/apps/frontend/.env.development b/apps/frontend/.env.development deleted file mode 100644 index 6d45ba0..0000000 --- a/apps/frontend/.env.development +++ /dev/null @@ -1,2 +0,0 @@ -# API Base URL (Development) -VITE_API_BASE_URL=http://localhost:8000 diff --git a/apps/frontend/.env.production b/apps/frontend/.env.production deleted file mode 100644 index 7d536cd..0000000 --- a/apps/frontend/.env.production +++ /dev/null @@ -1,3 +0,0 @@ -# API Base URL (Production) -# 留空,让 API 请求使用相对路径(由 Nginx 转发) -VITE_API_BASE_URL= diff --git a/apps/frontend/.prettierignore b/apps/frontend/.prettierignore index d70bb9c..661aec8 100644 --- a/apps/frontend/.prettierignore +++ b/apps/frontend/.prettierignore @@ -1,4 +1,4 @@ -node_modules dist -.DS_Store -*.local +node_modules +pnpm-lock.yaml +components.json diff --git a/apps/frontend/.prettierrc b/apps/frontend/.prettierrc deleted file mode 100644 index 4fe916c..0000000 --- a/apps/frontend/.prettierrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "semi": true, - "singleQuote": true, - "tabWidth": 2, - "trailingComma": "es5", - "printWidth": 100, - "arrowParens": "avoid", - "endOfLine": "auto" -} diff --git a/apps/new-frontend/.prettierrc.json b/apps/frontend/.prettierrc.json similarity index 100% rename from apps/new-frontend/.prettierrc.json rename to apps/frontend/.prettierrc.json diff --git a/apps/frontend/README.md b/apps/frontend/README.md new file mode 100644 index 0000000..06bb320 --- /dev/null +++ b/apps/frontend/README.md @@ -0,0 +1,26 @@ +# CheckIn App Frontend + +Vue 3 + TypeScript frontend for CheckIn App. This is the supported frontend source tree. + +## Commands + +```bash +pnpm install +pnpm dev +pnpm lint:check +pnpm test +pnpm build +``` + +The development server runs on port `3000` and proxies `/api` to `http://127.0.0.1:8000`. + +## Structure + +- `src/app/`: auth state, router, theme state +- `src/api/`: typed API helpers and fetch client +- `src/components/ui/`: shadcn-vue primitives +- `src/components/templates/`: structured template field editor +- `src/views/`: route-owned pages +- `src/style.css`: Tailwind v4 and shadcn token setup + +Prefer shadcn-vue primitives, lucide icons, semantic tokens, and the local helpers in `src/components/ui.ts` for repeated surfaces. Keep route-local Tailwind where it expresses one-off layout or dense operational structure. diff --git a/apps/new-frontend/components.json b/apps/frontend/components.json similarity index 100% rename from apps/new-frontend/components.json rename to apps/frontend/components.json diff --git a/apps/frontend/eslint.config.js b/apps/frontend/eslint.config.js index 2dc6d8a..58078c1 100644 --- a/apps/frontend/eslint.config.js +++ b/apps/frontend/eslint.config.js @@ -1,38 +1,65 @@ -import js from '@eslint/js'; -import pluginVue from 'eslint-plugin-vue'; -import prettierConfig from '@vue/eslint-config-prettier'; +import js from '@eslint/js' +import prettierConfig from '@vue/eslint-config-prettier' +import tsParser from '@typescript-eslint/parser' +import pluginVue from 'eslint-plugin-vue' +import vueParser from 'vue-eslint-parser' + +const browserGlobals = { + AbortController: 'readonly', + DOMException: 'readonly', + Headers: 'readonly', + URL: 'readonly', + URLSearchParams: 'readonly', + console: 'readonly', + document: 'readonly', + fetch: 'readonly', + localStorage: 'readonly', + window: 'readonly', +} export default [ { - ignores: ['node_modules', 'dist', '*.local'], + ignores: ['dist/**', 'node_modules/**', 'coverage/**', '*.local', 'pnpm-lock.yaml'], }, js.configs.recommended, - ...pluginVue.configs['flat/recommended'], - prettierConfig, { + files: ['**/*.ts'], languageOptions: { - globals: { - // 浏览器环境 - window: 'readonly', - document: 'readonly', - localStorage: 'readonly', - console: 'readonly', - setTimeout: 'readonly', - clearTimeout: 'readonly', - setInterval: 'readonly', - clearInterval: 'readonly', - navigator: 'readonly', - // Node.js 环境(用于配置文件) - process: 'readonly', - __dirname: 'readonly', - }, + ecmaVersion: 'latest', + sourceType: 'module', + parser: tsParser, + globals: browserGlobals, }, rules: { - 'vue/multi-word-component-names': 'off', - 'vue/no-v-html': 'warn', - 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - 'no-unused-vars': 'warn', + 'no-undef': 'off', }, }, -]; + ...pluginVue.configs['flat/recommended'], + { + files: ['**/*.vue'], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + parser: vueParser, + parserOptions: { + parser: tsParser, + ecmaVersion: 'latest', + sourceType: 'module', + }, + globals: browserGlobals, + }, + rules: { + 'no-undef': 'off', + }, + }, + prettierConfig, + { + files: ['**/*.{js,ts,vue}'], + rules: { + 'no-console': 'warn', + 'no-unused-vars': 'off', + 'vue/multi-word-component-names': 'off', + 'vue/no-v-html': 'warn', + }, + }, +] diff --git a/apps/frontend/index.html b/apps/frontend/index.html index f60ac5a..33bd005 100644 --- a/apps/frontend/index.html +++ b/apps/frontend/index.html @@ -1,14 +1,13 @@ - + - 接龙自动打卡 - + CheckIn App
- + diff --git a/apps/frontend/package-lock.json b/apps/frontend/package-lock.json deleted file mode 100644 index 5e1f539..0000000 --- a/apps/frontend/package-lock.json +++ /dev/null @@ -1,4314 +0,0 @@ -{ - "name": "frontend", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "frontend", - "version": "0.0.0", - "dependencies": { - "@ant-design/icons-vue": "^7.0.1", - "ant-design-vue": "^4.2.6", - "axios": "^1.13.4", - "pinia": "^3.0.4", - "vue": "^3.5.27", - "vue-router": "^4.6.4" - }, - "devDependencies": { - "@eslint/js": "^9.39.2", - "@vitejs/plugin-vue": "^6.0.3", - "@vue/eslint-config-prettier": "^10.2.0", - "autoprefixer": "^10.4.23", - "eslint": "^9.39.2", - "eslint-plugin-vue": "^10.7.0", - "postcss": "^8.5.6", - "prettier": "^3.8.1", - "tailwindcss": "^3.4.19", - "vite": "^7.3.1" - } - }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@ant-design/colors": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz", - "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==", - "license": "MIT", - "dependencies": { - "@ctrl/tinycolor": "^3.4.0" - } - }, - "node_modules/@ant-design/icons-svg": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", - "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==", - "license": "MIT" - }, - "node_modules/@ant-design/icons-vue": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-7.0.1.tgz", - "integrity": "sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==", - "license": "MIT", - "dependencies": { - "@ant-design/colors": "^6.0.0", - "@ant-design/icons-svg": "^4.2.1" - }, - "peerDependencies": { - "vue": ">=3.0.3" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", - "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.6" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", - "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@ctrl/tinycolor": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", - "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", - "license": "MIT" - }, - "node_modules/@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", - "license": "MIT" - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", - "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", - "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", - "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", - "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", - "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", - "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", - "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", - "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", - "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", - "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", - "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", - "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", - "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", - "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", - "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", - "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", - "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", - "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", - "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", - "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", - "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", - "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", - "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", - "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", - "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", - "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.53", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz", - "integrity": "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz", - "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz", - "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz", - "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz", - "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz", - "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz", - "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz", - "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz", - "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz", - "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz", - "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz", - "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz", - "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz", - "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz", - "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz", - "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz", - "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz", - "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz", - "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz", - "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz", - "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz", - "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz", - "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@simonwep/pickr": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.8.2.tgz", - "integrity": "sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==", - "license": "MIT", - "dependencies": { - "core-js": "^3.15.1", - "nanopop": "^2.1.0" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@vitejs/plugin-vue": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.3.tgz", - "integrity": "sha512-TlGPkLFLVOY3T7fZrwdvKpjprR3s4fxRln0ORDo1VQ7HHyxJwTlrjKU3kpVWTlaAjIEuCTokmjkZnr8Tpc925w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rolldown/pluginutils": "1.0.0-beta.53" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", - "vue": "^3.2.25" - } - }, - "node_modules/@vue/compiler-core": { - "version": "3.5.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.27.tgz", - "integrity": "sha512-gnSBQjZA+//qDZen+6a2EdHqJ68Z7uybrMf3SPjEGgG4dicklwDVmMC1AeIHxtLVPT7sn6sH1KOO+tS6gwOUeQ==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@vue/shared": "3.5.27", - "entities": "^7.0.0", - "estree-walker": "^2.0.2", - "source-map-js": "^1.2.1" - } - }, - "node_modules/@vue/compiler-dom": { - "version": "3.5.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.27.tgz", - "integrity": "sha512-oAFea8dZgCtVVVTEC7fv3T5CbZW9BxpFzGGxC79xakTr6ooeEqmRuvQydIiDAkglZEAd09LgVf1RoDnL54fu5w==", - "license": "MIT", - "dependencies": { - "@vue/compiler-core": "3.5.27", - "@vue/shared": "3.5.27" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.5.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.27.tgz", - "integrity": "sha512-sHZu9QyDPeDmN/MRoshhggVOWE5WlGFStKFwu8G52swATgSny27hJRWteKDSUUzUH+wp+bmeNbhJnEAel/auUQ==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@vue/compiler-core": "3.5.27", - "@vue/compiler-dom": "3.5.27", - "@vue/compiler-ssr": "3.5.27", - "@vue/shared": "3.5.27", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.21", - "postcss": "^8.5.6", - "source-map-js": "^1.2.1" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.5.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.27.tgz", - "integrity": "sha512-Sj7h+JHt512fV1cTxKlYhg7qxBvack+BGncSpH+8vnN+KN95iPIcqB5rsbblX40XorP+ilO7VIKlkuu3Xq2vjw==", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.27", - "@vue/shared": "3.5.27" - } - }, - "node_modules/@vue/devtools-api": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz", - "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==", - "license": "MIT", - "dependencies": { - "@vue/devtools-kit": "^7.7.9" - } - }, - "node_modules/@vue/devtools-kit": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", - "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", - "license": "MIT", - "dependencies": { - "@vue/devtools-shared": "^7.7.9", - "birpc": "^2.3.0", - "hookable": "^5.5.3", - "mitt": "^3.0.1", - "perfect-debounce": "^1.0.0", - "speakingurl": "^14.0.1", - "superjson": "^2.2.2" - } - }, - "node_modules/@vue/devtools-shared": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz", - "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", - "license": "MIT", - "dependencies": { - "rfdc": "^1.4.1" - } - }, - "node_modules/@vue/eslint-config-prettier": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-10.2.0.tgz", - "integrity": "sha512-GL3YBLwv/+b86yHcNNfPJxOTtVFJ4Mbc9UU3zR+KVoG7SwGTjPT+32fXamscNumElhcpXW3mT0DgzS9w32S7Bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-config-prettier": "^10.0.1", - "eslint-plugin-prettier": "^5.2.2" - }, - "peerDependencies": { - "eslint": ">= 8.21.0", - "prettier": ">= 3.0.0" - } - }, - "node_modules/@vue/reactivity": { - "version": "3.5.27", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.27.tgz", - "integrity": "sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==", - "license": "MIT", - "dependencies": { - "@vue/shared": "3.5.27" - } - }, - "node_modules/@vue/runtime-core": { - "version": "3.5.27", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.27.tgz", - "integrity": "sha512-fxVuX/fzgzeMPn/CLQecWeDIFNt3gQVhxM0rW02Tvp/YmZfXQgcTXlakq7IMutuZ/+Ogbn+K0oct9J3JZfyk3A==", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.27", - "@vue/shared": "3.5.27" - } - }, - "node_modules/@vue/runtime-dom": { - "version": "3.5.27", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.27.tgz", - "integrity": "sha512-/QnLslQgYqSJ5aUmb5F0z0caZPGHRB8LEAQ1s81vHFM5CBfnun63rxhvE/scVb/j3TbBuoZwkJyiLCkBluMpeg==", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.27", - "@vue/runtime-core": "3.5.27", - "@vue/shared": "3.5.27", - "csstype": "^3.2.3" - } - }, - "node_modules/@vue/server-renderer": { - "version": "3.5.27", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.27.tgz", - "integrity": "sha512-qOz/5thjeP1vAFc4+BY3Nr6wxyLhpeQgAE/8dDtKo6a6xdk+L4W46HDZgNmLOBUDEkFXV3G7pRiUqxjX0/2zWA==", - "license": "MIT", - "dependencies": { - "@vue/compiler-ssr": "3.5.27", - "@vue/shared": "3.5.27" - }, - "peerDependencies": { - "vue": "3.5.27" - } - }, - "node_modules/@vue/shared": { - "version": "3.5.27", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.27.tgz", - "integrity": "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==", - "license": "MIT" - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ant-design-vue": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-4.2.6.tgz", - "integrity": "sha512-t7eX13Yj3i9+i5g9lqFyYneoIb3OzTvQjq9Tts1i+eiOd3Eva/6GagxBSXM1fOCjqemIu0FYVE1ByZ/38epR3Q==", - "license": "MIT", - "dependencies": { - "@ant-design/colors": "^6.0.0", - "@ant-design/icons-vue": "^7.0.0", - "@babel/runtime": "^7.10.5", - "@ctrl/tinycolor": "^3.5.0", - "@emotion/hash": "^0.9.0", - "@emotion/unitless": "^0.8.0", - "@simonwep/pickr": "~1.8.0", - "array-tree-filter": "^2.1.0", - "async-validator": "^4.0.0", - "csstype": "^3.1.1", - "dayjs": "^1.10.5", - "dom-align": "^1.12.1", - "dom-scroll-into-view": "^2.0.0", - "lodash": "^4.17.21", - "lodash-es": "^4.17.15", - "resize-observer-polyfill": "^1.5.1", - "scroll-into-view-if-needed": "^2.2.25", - "shallow-equal": "^1.0.0", - "stylis": "^4.1.3", - "throttle-debounce": "^5.0.0", - "vue-types": "^3.0.0", - "warning": "^4.0.0" - }, - "engines": { - "node": ">=12.22.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ant-design-vue" - }, - "peerDependencies": { - "vue": ">=3.2.0" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/array-tree-filter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", - "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==", - "license": "MIT" - }, - "node_modules/async-validator": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", - "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==", - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/autoprefixer": { - "version": "10.4.23", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz", - "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.28.1", - "caniuse-lite": "^1.0.30001760", - "fraction.js": "^5.3.4", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/axios": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz", - "integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/baseline-browser-mapping": { - "version": "2.9.11", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", - "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/birpc": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", - "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true, - "license": "ISC" - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001762", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", - "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/compute-scroll-into-view": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", - "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/copy-anything": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", - "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", - "license": "MIT", - "dependencies": { - "is-what": "^5.2.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/core-js": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", - "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "license": "MIT" - }, - "node_modules/dayjs": { - "version": "1.11.19", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", - "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, - "license": "MIT" - }, - "node_modules/dom-align": { - "version": "1.12.4", - "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz", - "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==", - "license": "MIT" - }, - "node_modules/dom-scroll-into-view": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz", - "integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==", - "license": "MIT" - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", - "dev": true, - "license": "ISC" - }, - "node_modules/entities": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", - "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", - "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.2", - "@esbuild/android-arm": "0.27.2", - "@esbuild/android-arm64": "0.27.2", - "@esbuild/android-x64": "0.27.2", - "@esbuild/darwin-arm64": "0.27.2", - "@esbuild/darwin-x64": "0.27.2", - "@esbuild/freebsd-arm64": "0.27.2", - "@esbuild/freebsd-x64": "0.27.2", - "@esbuild/linux-arm": "0.27.2", - "@esbuild/linux-arm64": "0.27.2", - "@esbuild/linux-ia32": "0.27.2", - "@esbuild/linux-loong64": "0.27.2", - "@esbuild/linux-mips64el": "0.27.2", - "@esbuild/linux-ppc64": "0.27.2", - "@esbuild/linux-riscv64": "0.27.2", - "@esbuild/linux-s390x": "0.27.2", - "@esbuild/linux-x64": "0.27.2", - "@esbuild/netbsd-arm64": "0.27.2", - "@esbuild/netbsd-x64": "0.27.2", - "@esbuild/openbsd-arm64": "0.27.2", - "@esbuild/openbsd-x64": "0.27.2", - "@esbuild/openharmony-arm64": "0.27.2", - "@esbuild/sunos-x64": "0.27.2", - "@esbuild/win32-arm64": "0.27.2", - "@esbuild/win32-ia32": "0.27.2", - "@esbuild/win32-x64": "0.27.2" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", - "@eslint/plugin-kit": "^0.4.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-config-prettier": { - "version": "10.1.8", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", - "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "funding": { - "url": "https://opencollective.com/eslint-config-prettier" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz", - "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.11.7" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-vue": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.7.0.tgz", - "integrity": "sha512-r2XFCK4qlo1sxEoAMIoTTX0PZAdla0JJDt1fmYiworZUX67WeEGqm+JbyAg3M+pGiJ5U6Mp5WQbontXWtIW7TA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.1.1", - "postcss-selector-parser": "^7.1.0", - "semver": "^7.6.3", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "@stylistic/eslint-plugin": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", - "@typescript-eslint/parser": "^7.0.0 || ^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", - "vue-eslint-parser": "^10.0.0" - }, - "peerDependenciesMeta": { - "@stylistic/eslint-plugin": { - "optional": true - }, - "@typescript-eslint/parser": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "license": "MIT" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" - }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fraction.js": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", - "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hookable": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", - "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", - "license": "MIT" - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", - "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-what": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz", - "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", - "license": "MIT" - }, - "node_modules/lodash-es": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz", - "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==", - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/nanopop": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/nanopop/-/nanopop-2.4.2.tgz", - "integrity": "sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw==", - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/perfect-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", - "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinia": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.4.tgz", - "integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==", - "license": "MIT", - "dependencies": { - "@vue/devtools-api": "^7.7.7" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "typescript": ">=4.5.0", - "vue": "^3.5.11" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", - "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-load-config": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", - "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.1.1" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "jiti": ">=1.21.0", - "postcss": ">=8.0.9", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - }, - "postcss": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-nested/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-selector-parser": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", - "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", - "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "license": "MIT" - }, - "node_modules/rollup": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz", - "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.54.0", - "@rollup/rollup-android-arm64": "4.54.0", - "@rollup/rollup-darwin-arm64": "4.54.0", - "@rollup/rollup-darwin-x64": "4.54.0", - "@rollup/rollup-freebsd-arm64": "4.54.0", - "@rollup/rollup-freebsd-x64": "4.54.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", - "@rollup/rollup-linux-arm-musleabihf": "4.54.0", - "@rollup/rollup-linux-arm64-gnu": "4.54.0", - "@rollup/rollup-linux-arm64-musl": "4.54.0", - "@rollup/rollup-linux-loong64-gnu": "4.54.0", - "@rollup/rollup-linux-ppc64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-musl": "4.54.0", - "@rollup/rollup-linux-s390x-gnu": "4.54.0", - "@rollup/rollup-linux-x64-gnu": "4.54.0", - "@rollup/rollup-linux-x64-musl": "4.54.0", - "@rollup/rollup-openharmony-arm64": "4.54.0", - "@rollup/rollup-win32-arm64-msvc": "4.54.0", - "@rollup/rollup-win32-ia32-msvc": "4.54.0", - "@rollup/rollup-win32-x64-gnu": "4.54.0", - "@rollup/rollup-win32-x64-msvc": "4.54.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/scroll-into-view-if-needed": { - "version": "2.2.31", - "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz", - "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==", - "license": "MIT", - "dependencies": { - "compute-scroll-into-view": "^1.0.20" - } - }, - "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shallow-equal": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", - "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==", - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/speakingurl": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", - "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stylis": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", - "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", - "license": "MIT" - }, - "node_modules/sucrase": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", - "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "tinyglobby": "^0.2.11", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/superjson": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", - "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", - "license": "MIT", - "dependencies": { - "copy-anything": "^4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/synckit": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", - "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.2.9" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, - "node_modules/tailwindcss": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", - "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.6.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.7", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tailwindcss/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/throttle-debounce": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", - "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==", - "license": "MIT", - "engines": { - "node": ">=12.22" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/vite": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", - "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/vue": { - "version": "3.5.27", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.27.tgz", - "integrity": "sha512-aJ/UtoEyFySPBGarREmN4z6qNKpbEguYHMmXSiOGk69czc+zhs0NF6tEFrY8TZKAl8N/LYAkd4JHVd5E/AsSmw==", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.27", - "@vue/compiler-sfc": "3.5.27", - "@vue/runtime-dom": "3.5.27", - "@vue/server-renderer": "3.5.27", - "@vue/shared": "3.5.27" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/vue-eslint-parser": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz", - "integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "debug": "^4.4.0", - "eslint-scope": "^8.2.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.6.0", - "semver": "^7.6.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - } - }, - "node_modules/vue-router": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz", - "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==", - "license": "MIT", - "dependencies": { - "@vue/devtools-api": "^6.6.4" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "vue": "^3.5.0" - } - }, - "node_modules/vue-router/node_modules/@vue/devtools-api": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", - "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", - "license": "MIT" - }, - "node_modules/vue-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/vue-types/-/vue-types-3.0.2.tgz", - "integrity": "sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==", - "license": "MIT", - "dependencies": { - "is-plain-object": "3.0.1" - }, - "engines": { - "node": ">=10.15.0" - }, - "peerDependencies": { - "vue": "^3.0.0" - } - }, - "node_modules/warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 378371f..c17a7a6 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -1,33 +1,44 @@ { - "name": "frontend", + "name": "checkin-app-frontend", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", - "build": "vite build", + "build": "vue-tsc -b && vite build", "preview": "vite preview", - "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix", - "format": "prettier --write ." + "test": "node --test --experimental-strip-types src/app/theme.test.ts src/components/templates/template-config.test.ts", + "typecheck": "vue-tsc -b", + "lint": "eslint . --fix", + "lint:check": "eslint .", + "format": "prettier --write .", + "format:check": "prettier --check ." }, "dependencies": { - "@ant-design/icons-vue": "^7.0.1", - "ant-design-vue": "^4.2.6", - "axios": "^1.13.4", - "pinia": "^3.0.4", - "vue": "^3.5.27", - "vue-router": "^4.6.4" + "@tailwindcss/vite": "^4.2.4", + "@vueuse/core": "^14.3.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-vue-next": "^1.0.0", + "reka-ui": "^2.9.6", + "tailwind-merge": "^3.5.0", + "tailwindcss": "^4.2.4", + "vue": "^3.5.33" }, "devDependencies": { "@eslint/js": "^9.39.2", - "@vitejs/plugin-vue": "^6.0.3", + "@types/node": "^25.6.0", + "@typescript-eslint/parser": "^8.59.1", + "@vitejs/plugin-vue": "^6.0.6", "@vue/eslint-config-prettier": "^10.2.0", - "autoprefixer": "^10.4.23", + "@vue/tsconfig": "^0.9.1", "eslint": "^9.39.2", "eslint-plugin-vue": "^10.7.0", - "postcss": "^8.5.6", "prettier": "^3.8.1", - "tailwindcss": "^3.4.19", - "vite": "^7.3.1" + "tw-animate-css": "^1.4.0", + "typescript": "~6.0.3", + "vite": "^8.0.10", + "vue-eslint-parser": "^10.4.0", + "vue-tsc": "^3.2.7" } } diff --git a/apps/new-frontend/pnpm-lock.yaml b/apps/frontend/pnpm-lock.yaml similarity index 100% rename from apps/new-frontend/pnpm-lock.yaml rename to apps/frontend/pnpm-lock.yaml diff --git a/apps/frontend/postcss.config.js b/apps/frontend/postcss.config.js deleted file mode 100644 index 2aa7205..0000000 --- a/apps/frontend/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; diff --git a/apps/frontend/public/favicon.svg b/apps/frontend/public/favicon.svg index 180ccba..6893eb1 100644 --- a/apps/frontend/public/favicon.svg +++ b/apps/frontend/public/favicon.svg @@ -1,20 +1 @@ - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/apps/new-frontend/public/icons.svg b/apps/frontend/public/icons.svg similarity index 100% rename from apps/new-frontend/public/icons.svg rename to apps/frontend/public/icons.svg diff --git a/apps/frontend/public/vite.svg b/apps/frontend/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/apps/frontend/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/frontend/src/App.vue b/apps/frontend/src/App.vue index 6723982..c6952eb 100644 --- a/apps/frontend/src/App.vue +++ b/apps/frontend/src/App.vue @@ -1,85 +1,72 @@ - + - + diff --git a/apps/frontend/src/antd-theme.js b/apps/frontend/src/antd-theme.js deleted file mode 100644 index d47c9f5..0000000 --- a/apps/frontend/src/antd-theme.js +++ /dev/null @@ -1,248 +0,0 @@ -import { theme } from 'ant-design-vue'; - -/** - * Ant Design Vue 主题配置 - * 严格遵循 Material Design 3 规范 - * @param {boolean} isDark - 是否为暗色模式 - */ -export default function getAntdTheme(isDark = false) { - return { - token: { - // === Material Design 3 Color System === - - // Primary - 主色调(绿色) - colorPrimary: isDark ? '#81c784' : '#4caf50', - - // Secondary colors - colorSuccess: isDark ? '#81c784' : '#4caf50', - colorWarning: '#ff9800', - colorError: '#f44336', // MD3 标准错误色 - colorInfo: isDark ? '#64b5f6' : '#2196f3', - - // === Surface & Background (MD3 规范) === - colorBgBase: isDark ? '#1c1b1f' : '#ffffff', - colorBgContainer: isDark ? '#1c1b1f' : '#ffffff', - colorBgElevated: isDark ? '#26252a' : '#ffffff', - colorBgLayout: isDark ? '#1c1b1f' : '#fefbff', // MD3 标准背景色 - colorBgSpotlight: isDark ? '#26252a' : '#ffffff', - - // === Typography (MD3 规范) === - colorText: isDark ? '#e6e1e5' : '#1c1b1f', // On-surface - colorTextSecondary: isDark ? '#cac4d0' : '#49454f', // On-surface-variant - colorTextTertiary: isDark ? '#938f99' : '#79747e', - colorTextQuaternary: isDark ? '#79747e' : '#938f99', - - // === Borders === - colorBorder: isDark ? '#49454f' : '#d1cdd6', - colorBorderSecondary: isDark ? '#3a3740' : '#e3e1e6', - colorSplit: isDark ? '#49454f' : '#e3e1e6', - - // === Shape System === - borderRadius: 12, // Medium shape - borderRadiusLG: 16, // Large shape - borderRadiusSM: 8, // Small shape - borderRadiusXS: 4, // Extra small shape - - // === Typography === - fontFamily: "'Roboto', 'Inter', system-ui, -apple-system, sans-serif", - fontSize: 14, // Body Medium - fontSizeLG: 16, // Body Large - fontSizeSM: 12, // Body Small - lineHeight: 1.428, // 20/14 = 1.428 - lineHeightLG: 1.5, // 24/16 = 1.5 - - // === Links === - colorLink: isDark ? '#64b5f6' : '#2196f3', - colorLinkHover: isDark ? '#90caf9' : '#1976d2', - colorLinkActive: isDark ? '#42a5f5' : '#1565c0', - - // === Components === - controlHeight: 40, - controlHeightLG: 48, - controlHeightSM: 32, - - // === Motion (MD3 规范) === - motionDurationSlow: '0.3s', - motionDurationMid: '0.2s', - motionDurationFast: '0.1s', - }, - - components: { - // === Card 组件 (MD3 Elevated Card) === - Card: { - borderRadiusLG: 16, - paddingLG: 24, - colorBgContainer: isDark ? '#1c1b1f' : '#ffffff', - colorBorderSecondary: isDark ? '#49454f' : '#e3e1e6', - colorTextHeading: isDark ? '#e6e1e5' : '#1c1b1f', - }, - - // === Button 组件 (MD3 规范) === - Button: { - borderRadius: 20, // MD3 Filled Button 圆角 - borderRadiusLG: 24, - borderRadiusSM: 16, - controlHeight: 40, - controlHeightLG: 48, - controlHeightSM: 32, - fontSize: 14, - fontSizeLG: 16, - fontSizeSM: 12, - paddingContentHorizontal: 24, - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - colorBgContainer: isDark ? '#26252a' : '#ffffff', - }, - - // === Input 组件 (MD3 Text Field) === - Input: { - borderRadius: 12, - controlHeight: 40, - colorBgContainer: isDark ? '#26252a' : '#ffffff', - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - colorTextPlaceholder: isDark ? '#938f99' : '#79747e', - colorBorder: isDark ? '#49454f' : '#d1cdd6', - }, - - // === Select 组件 === - Select: { - borderRadius: 12, - controlHeight: 40, - colorBgContainer: isDark ? '#26252a' : '#ffffff', - colorBgElevated: isDark ? '#26252a' : '#ffffff', - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - colorTextPlaceholder: isDark ? '#938f99' : '#79747e', - colorBorder: isDark ? '#49454f' : '#d1cdd6', - }, - - // === Modal 组件 (MD3 Dialog) === - Modal: { - borderRadiusLG: 28, // MD3 Dialog 使用 Extra Large 圆角 - colorBgElevated: isDark ? '#1c1b1f' : '#ffffff', - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - colorTextHeading: isDark ? '#e6e1e5' : '#1c1b1f', - }, - - // === Table 组件 === - Table: { - borderRadius: 12, - colorBgContainer: isDark ? '#1c1b1f' : '#ffffff', - colorFillAlter: isDark ? '#26252a' : '#f5f5f5', - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - colorTextHeading: isDark ? '#e6e1e5' : '#1c1b1f', - colorBorderSecondary: isDark ? '#49454f' : '#e3e1e6', - }, - - // === Tabs 组件 === - Tabs: { - borderRadius: 12, - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - colorBgContainer: isDark ? '#1c1b1f' : '#ffffff', - }, - - // === Menu 组件 === - Menu: { - colorItemBg: isDark ? '#1c1b1f' : '#ffffff', - colorItemBgHover: isDark ? '#26252a' : '#f5f5f5', - colorItemBgSelected: isDark ? '#3a4a3f' : '#e8f5e9', - colorItemText: isDark ? '#e6e1e5' : '#1c1b1f', - colorItemTextSelected: isDark ? '#81c784' : '#4caf50', - borderRadius: 12, - }, - - // === Dropdown 组件 === - Dropdown: { - colorBgElevated: isDark ? '#26252a' : '#ffffff', - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - borderRadiusLG: 12, - }, - - // === Descriptions 组件 === - Descriptions: { - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - colorTextSecondary: isDark ? '#cac4d0' : '#49454f', - colorBgContainer: isDark ? '#1c1b1f' : '#ffffff', - colorFillAlter: isDark ? '#201f24' : '#f3f4f6', // Label 背景色 = surface-container - colorSplit: isDark ? '#49454f' : '#e3e1e6', - borderRadiusLG: 8, // 设置 Descriptions 容器圆角 - }, - - // === Alert 组件 === - Alert: { - borderRadiusLG: 12, - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - }, - - // === Drawer 组件 === - Drawer: { - colorBgElevated: isDark ? '#1c1b1f' : '#ffffff', - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - borderRadiusLG: 16, - }, - - // === Form 组件 === - Form: { - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - colorTextHeading: isDark ? '#e6e1e5' : '#1c1b1f', - }, - - // === Empty 组件 === - Empty: { - colorTextDescription: isDark ? '#938f99' : '#79747e', - }, - - // === Tag 组件 === - Tag: { - borderRadiusSM: 16, // 药丸形 - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - }, - - // === Switch 组件 === - Switch: { - colorPrimary: isDark ? '#81c784' : '#4caf50', - colorText: isDark ? '#e6e1e5' : '#1c1b1f', - }, - - // === Segmented 组件 === - Segmented: { - borderRadius: 12, - borderRadiusSM: 8, - // 根据源码,Segmented 使用这些 token 映射: - // labelColor <- colorTextLabel - // labelColorHover <- colorText - // bgColor <- colorBgLayout - // bgColorHover <- colorFillSecondary - // bgColorSelected <- colorBgElevated - - // 未选中项文字颜色 - colorTextLabel: isDark ? '#938f99' : '#79747e', - labelColor: isDark ? '#938f99' : '#79747e', - - // 选中项和 hover 时的文字颜色 - colorText: isDark ? '#ffffff' : '#1c1b1f', - labelColorHover: isDark ? '#ffffff' : '#1c1b1f', - - // 整体背景色 - colorBgLayout: isDark ? '#26252a' : '#f5f5f5', - bgColor: isDark ? '#26252a' : '#f5f5f5', - - // hover 背景色(降低透明度,保持文字可见) - colorFillSecondary: isDark ? 'rgba(129, 199, 132, 0.12)' : 'rgba(76, 175, 80, 0.08)', - bgColorHover: isDark ? 'rgba(129, 199, 132, 0.12)' : 'rgba(76, 175, 80, 0.08)', - - // 选中项背景色(主题色) - colorBgElevated: isDark ? '#81c784' : '#4caf50', - bgColorSelected: isDark ? '#81c784' : '#4caf50', - }, - - // === Tooltip 组件 === - Tooltip: { - colorBgSpotlight: isDark ? '#313033' : '#f5f5f5', // Tooltip 背景色(跟随主题) - colorTextLightSolid: isDark ? '#ffffff' : '#1c1b1f', // Tooltip 文本颜色(跟随主题) - borderRadius: 8, - }, - }, - - // 算法配置 - 使用 Ant Design 内置的暗黑算法 - algorithm: isDark ? [theme.darkAlgorithm] : [], - }; -} diff --git a/apps/frontend/src/api/client.js b/apps/frontend/src/api/client.js deleted file mode 100644 index 8dc25d5..0000000 --- a/apps/frontend/src/api/client.js +++ /dev/null @@ -1,75 +0,0 @@ -import axios from 'axios'; - -// 创建 axios 实例 -const client = axios.create({ - baseURL: import.meta.env.VITE_API_BASE_URL || '', - timeout: 30000, - headers: { - 'Content-Type': 'application/json', - }, -}); - -// 请求拦截器 - 添加 Token -client.interceptors.request.use( - config => { - const token = localStorage.getItem('token'); - if (token) { - config.headers.Authorization = `Bearer ${token}`; - } - return config; - }, - error => { - return Promise.reject(error); - } -); - -// 响应拦截器 - 统一错误处理 -client.interceptors.response.use( - response => { - return response.data; - }, - error => { - if (error.response) { - // 服务器返回错误状态码 - const { status, data } = error.response; - - if (status === 401) { - // JWT token 过期或无效:需要重新登录 - // 注意:打卡业务的 authorization token 过期不会影响网站登录状态 - localStorage.removeItem('token'); - localStorage.removeItem('user'); - - // 延迟跳转到登录页 - setTimeout(() => { - if (window.location.pathname !== '/login') { - window.location.href = '/login'; - } - }, 100); - } - - // 返回统一的错误对象 - return Promise.reject({ - status, - message: data.detail || data.message || '请求失败', - data, - }); - } else if (error.request) { - // 请求已发出但没有收到响应(超时或网络错误) - return Promise.reject({ - status: 0, - message: - error.code === 'ECONNABORTED' ? '请求超时,请稍后重试' : '网络错误,请检查您的网络连接', - data: null, - }); - } else { - // 发生了触发请求错误的问题 - return Promise.reject({ - status: 0, - message: error.message || '请求配置错误', - data: null, - }); - } - } -); - -export default client; diff --git a/apps/new-frontend/src/api/client.ts b/apps/frontend/src/api/client.ts similarity index 100% rename from apps/new-frontend/src/api/client.ts rename to apps/frontend/src/api/client.ts diff --git a/apps/frontend/src/api/index.js b/apps/frontend/src/api/index.js deleted file mode 100644 index 5d09624..0000000 --- a/apps/frontend/src/api/index.js +++ /dev/null @@ -1,258 +0,0 @@ -import client from './client'; - -/** - * 认证 API - */ -export const authAPI = { - // 请求 QR 码 - requestQRCode: alias => { - return client.post('/api/auth/request_qrcode', { alias }); - }, - - // 查询扫码状态 - getQRCodeStatus: sessionId => { - return client.get(`/api/auth/qrcode_status/${sessionId}`); - }, - - // 取消 QR 码登录会话 - cancelQRCodeSession: sessionId => { - return client.delete(`/api/auth/qrcode_session/${sessionId}`); - }, - - // 别名+密码登录 - aliasLogin: (alias, password) => { - return client.post('/api/auth/alias_login', { alias, password }); - }, - - // 验证 Token - verifyToken: token => { - return client.post('/api/auth/verify_token', { token }); - }, -}; - -/** - * 用户 API - */ -export const userAPI = { - // 获取当前用户信息 - getCurrentUser: () => { - return client.get('/api/users/me'); - }, - - // 获取当前用户审批状态 - getUserStatus: () => { - return client.get('/api/users/me/status'); - }, - - // 获取当前用户 Token 状态 - getTokenStatus: () => { - return client.get('/api/users/me/token_status'); - }, - - // 更新当前用户个人信息 - updateProfile: profileData => { - return client.put('/api/users/me/profile', profileData); - }, - - // 创建用户(管理员) - createUser: userData => { - return client.post('/api/users', userData); - }, - - // 获取所有用户(管理员) - getUsers: (params = {}) => { - return client.get('/api/users', { params }); - }, - - // 获取指定用户 - getUser: userId => { - return client.get(`/api/users/${userId}`); - }, - - // 更新用户 - updateUser: (userId, userData) => { - return client.put(`/api/users/${userId}`, userData); - }, - - // 删除用户 - deleteUser: userId => { - return client.delete(`/api/users/${userId}`); - }, -}; - -/** - * 任务 API (V2 新增) - */ -export const taskAPI = { - // 获取当前用户的任务列表 - getMyTasks: (params = {}) => { - return client.get('/api/tasks', { params }); - }, - - // 获取任务详情 - getTask: taskId => { - return client.get(`/api/tasks/${taskId}`); - }, - - // 更新任务 - updateTask: (taskId, taskData) => { - return client.put(`/api/tasks/${taskId}`, taskData); - }, - - // 删除任务 - deleteTask: taskId => { - return client.delete(`/api/tasks/${taskId}`); - }, - - // 切换任务启用状态 - toggleTask: taskId => { - return client.post(`/api/tasks/${taskId}/toggle`); - }, - - // 手动触发任务打卡(异步,立即返回) - checkInTask: taskId => { - return client.post(`/api/check_in/manual/${taskId}`); - }, - - // 查询打卡记录状态 - getCheckInRecordStatus: recordId => { - return client.get(`/api/check_in/record/${recordId}/status`); - }, - - // 获取任务的打卡记录 - getTaskRecords: (taskId, params = {}) => { - return client.get(`/api/check_in/task/${taskId}/records`, { params }); - }, -}; - -/** - * 打卡 API - */ -export const checkInAPI = { - // 手动打卡(兼容旧版,推荐使用 taskAPI.checkInTask) - manualCheckIn: taskId => { - // 打卡操作耗时较长,设置 120 秒超时 - return client.post( - `/api/check_in/manual/${taskId}`, - {}, - { - timeout: 120000, // 120 秒 - } - ); - }, - - // 获取任务打卡记录(兼容旧版,推荐使用 taskAPI.getTaskRecords) - getMyRecords: (params = {}) => { - return client.get('/api/check_in/my-records', { params }); - }, - - // 获取所有打卡记录(管理员) - getAllRecords: (params = {}) => { - return client.get('/api/check_in/records', { params }); - }, - - // 统计打卡记录数 - getRecordsCount: (params = {}) => { - return client.get('/api/check_in/records/count', { params }); - }, -}; - -/** - * 管理员 API - */ -export const adminAPI = { - // 获取待审批用户 - getPendingUsers: () => { - return client.get('/api/admin/users/pending'); - }, - - // 审批通过用户 - approveUser: userId => { - return client.post(`/api/admin/users/${userId}/approve`); - }, - - // 拒绝用户 - rejectUser: userId => { - return client.delete(`/api/admin/users/${userId}/reject`); - }, - - // 批量启用/禁用任务(V2 更新) - batchToggleTasks: (taskIds, isActive) => { - return client.post('/api/admin/batch_toggle_tasks', { - task_ids: taskIds, - is_active: isActive, - }); - }, - - // 批量触发打卡(V2 更新) - batchCheckIn: taskIds => { - return client.post('/api/admin/batch_check_in', { - task_ids: taskIds, - }); - }, - - // 查看系统日志 - getLogs: (params = {}) => { - return client.get('/api/admin/logs', { params }); - }, - - // 系统统计信息 - getStats: () => { - return client.get('/api/admin/stats'); - }, -}; - -/** - * 模板 API - */ -export const templateAPI = { - // 获取所有模板列表 - getTemplates: (params = {}) => { - return client.get('/api/templates', { params }); - }, - - // 获取启用的模板列表 - getActiveTemplates: (params = {}) => { - return client.get('/api/templates/active', { params }); - }, - - // 获取单个模板详情 - getTemplate: templateId => { - return client.get(`/api/templates/${templateId}`); - }, - - // 预览模板生成的 payload - previewTemplate: templateId => { - return client.get(`/api/templates/${templateId}/preview`); - }, - - // 创建模板(管理员) - createTemplate: templateData => { - return client.post('/api/templates', templateData); - }, - - // 更新模板(管理员) - updateTemplate: (templateId, templateData) => { - return client.put(`/api/templates/${templateId}`, templateData); - }, - - // 删除模板(管理员) - deleteTemplate: templateId => { - return client.delete(`/api/templates/${templateId}`); - }, - - // 从模板创建任务 - createTaskFromTemplate: requestData => { - return client.post('/api/templates/create-task', requestData); - }, -}; - -// 导出所有 API -export default { - auth: authAPI, - user: userAPI, - task: taskAPI, // V2 新增 - checkIn: checkInAPI, - admin: adminAPI, - template: templateAPI, // V2.2 新增 -}; diff --git a/apps/new-frontend/src/api/index.ts b/apps/frontend/src/api/index.ts similarity index 100% rename from apps/new-frontend/src/api/index.ts rename to apps/frontend/src/api/index.ts diff --git a/apps/new-frontend/src/api/types.ts b/apps/frontend/src/api/types.ts similarity index 100% rename from apps/new-frontend/src/api/types.ts rename to apps/frontend/src/api/types.ts diff --git a/apps/new-frontend/src/app/auth.ts b/apps/frontend/src/app/auth.ts similarity index 100% rename from apps/new-frontend/src/app/auth.ts rename to apps/frontend/src/app/auth.ts diff --git a/apps/new-frontend/src/app/router.ts b/apps/frontend/src/app/router.ts similarity index 100% rename from apps/new-frontend/src/app/router.ts rename to apps/frontend/src/app/router.ts diff --git a/apps/new-frontend/src/app/theme.test.ts b/apps/frontend/src/app/theme.test.ts similarity index 100% rename from apps/new-frontend/src/app/theme.test.ts rename to apps/frontend/src/app/theme.test.ts diff --git a/apps/new-frontend/src/app/theme.ts b/apps/frontend/src/app/theme.ts similarity index 100% rename from apps/new-frontend/src/app/theme.ts rename to apps/frontend/src/app/theme.ts diff --git a/apps/new-frontend/src/assets/hero.png b/apps/frontend/src/assets/hero.png similarity index 100% rename from apps/new-frontend/src/assets/hero.png rename to apps/frontend/src/assets/hero.png diff --git a/apps/frontend/src/assets/vue.svg b/apps/frontend/src/assets/vue.svg deleted file mode 100644 index 770e9d3..0000000 --- a/apps/frontend/src/assets/vue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/new-frontend/src/components/AppLayout.vue b/apps/frontend/src/components/AppLayout.vue similarity index 100% rename from apps/new-frontend/src/components/AppLayout.vue rename to apps/frontend/src/components/AppLayout.vue diff --git a/apps/frontend/src/components/CrontabEditor.vue b/apps/frontend/src/components/CrontabEditor.vue deleted file mode 100644 index 117b7c0..0000000 --- a/apps/frontend/src/components/CrontabEditor.vue +++ /dev/null @@ -1,509 +0,0 @@ - - - - - diff --git a/apps/frontend/src/components/FieldConfigEditor.vue b/apps/frontend/src/components/FieldConfigEditor.vue deleted file mode 100644 index 248202d..0000000 --- a/apps/frontend/src/components/FieldConfigEditor.vue +++ /dev/null @@ -1,277 +0,0 @@ - - - - - diff --git a/apps/frontend/src/components/FieldTreeNode.vue b/apps/frontend/src/components/FieldTreeNode.vue deleted file mode 100644 index e74407b..0000000 --- a/apps/frontend/src/components/FieldTreeNode.vue +++ /dev/null @@ -1,630 +0,0 @@ - - - - - diff --git a/apps/frontend/src/components/Layout.vue b/apps/frontend/src/components/Layout.vue deleted file mode 100644 index e5347ce..0000000 --- a/apps/frontend/src/components/Layout.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - - - diff --git a/apps/frontend/src/components/Navbar.vue b/apps/frontend/src/components/Navbar.vue deleted file mode 100644 index c2e17b8..0000000 --- a/apps/frontend/src/components/Navbar.vue +++ /dev/null @@ -1,473 +0,0 @@ - - - diff --git a/apps/frontend/src/components/QRCodeModal.vue b/apps/frontend/src/components/QRCodeModal.vue deleted file mode 100644 index 4c42983..0000000 --- a/apps/frontend/src/components/QRCodeModal.vue +++ /dev/null @@ -1,323 +0,0 @@ - - - - - diff --git a/apps/new-frontend/src/components/StateBlock.vue b/apps/frontend/src/components/StateBlock.vue similarity index 100% rename from apps/new-frontend/src/components/StateBlock.vue rename to apps/frontend/src/components/StateBlock.vue diff --git a/apps/frontend/src/components/common/EmptyState.vue b/apps/frontend/src/components/common/EmptyState.vue deleted file mode 100644 index 44bd028..0000000 --- a/apps/frontend/src/components/common/EmptyState.vue +++ /dev/null @@ -1,110 +0,0 @@ - - - diff --git a/apps/frontend/src/components/common/LoadingState.vue b/apps/frontend/src/components/common/LoadingState.vue deleted file mode 100644 index d46bfdf..0000000 --- a/apps/frontend/src/components/common/LoadingState.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - - - diff --git a/apps/frontend/src/components/common/StatsCard.vue b/apps/frontend/src/components/common/StatsCard.vue deleted file mode 100644 index a7edbc2..0000000 --- a/apps/frontend/src/components/common/StatsCard.vue +++ /dev/null @@ -1,188 +0,0 @@ - - - - - diff --git a/apps/new-frontend/src/components/templates/TemplateConfigEditor.vue b/apps/frontend/src/components/templates/TemplateConfigEditor.vue similarity index 100% rename from apps/new-frontend/src/components/templates/TemplateConfigEditor.vue rename to apps/frontend/src/components/templates/TemplateConfigEditor.vue diff --git a/apps/new-frontend/src/components/templates/TemplateFieldNode.vue b/apps/frontend/src/components/templates/TemplateFieldNode.vue similarity index 100% rename from apps/new-frontend/src/components/templates/TemplateFieldNode.vue rename to apps/frontend/src/components/templates/TemplateFieldNode.vue diff --git a/apps/new-frontend/src/components/templates/template-config.test.ts b/apps/frontend/src/components/templates/template-config.test.ts similarity index 100% rename from apps/new-frontend/src/components/templates/template-config.test.ts rename to apps/frontend/src/components/templates/template-config.test.ts diff --git a/apps/new-frontend/src/components/templates/template-config.ts b/apps/frontend/src/components/templates/template-config.ts similarity index 100% rename from apps/new-frontend/src/components/templates/template-config.ts rename to apps/frontend/src/components/templates/template-config.ts diff --git a/apps/new-frontend/src/components/ui.ts b/apps/frontend/src/components/ui.ts similarity index 100% rename from apps/new-frontend/src/components/ui.ts rename to apps/frontend/src/components/ui.ts diff --git a/apps/new-frontend/src/components/ui/button/Button.vue b/apps/frontend/src/components/ui/button/Button.vue similarity index 100% rename from apps/new-frontend/src/components/ui/button/Button.vue rename to apps/frontend/src/components/ui/button/Button.vue diff --git a/apps/new-frontend/src/components/ui/button/index.ts b/apps/frontend/src/components/ui/button/index.ts similarity index 100% rename from apps/new-frontend/src/components/ui/button/index.ts rename to apps/frontend/src/components/ui/button/index.ts diff --git a/apps/new-frontend/src/components/ui/dialog/Dialog.vue b/apps/frontend/src/components/ui/dialog/Dialog.vue similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/Dialog.vue rename to apps/frontend/src/components/ui/dialog/Dialog.vue diff --git a/apps/new-frontend/src/components/ui/dialog/DialogClose.vue b/apps/frontend/src/components/ui/dialog/DialogClose.vue similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/DialogClose.vue rename to apps/frontend/src/components/ui/dialog/DialogClose.vue diff --git a/apps/new-frontend/src/components/ui/dialog/DialogContent.vue b/apps/frontend/src/components/ui/dialog/DialogContent.vue similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/DialogContent.vue rename to apps/frontend/src/components/ui/dialog/DialogContent.vue diff --git a/apps/new-frontend/src/components/ui/dialog/DialogDescription.vue b/apps/frontend/src/components/ui/dialog/DialogDescription.vue similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/DialogDescription.vue rename to apps/frontend/src/components/ui/dialog/DialogDescription.vue diff --git a/apps/new-frontend/src/components/ui/dialog/DialogFooter.vue b/apps/frontend/src/components/ui/dialog/DialogFooter.vue similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/DialogFooter.vue rename to apps/frontend/src/components/ui/dialog/DialogFooter.vue diff --git a/apps/new-frontend/src/components/ui/dialog/DialogHeader.vue b/apps/frontend/src/components/ui/dialog/DialogHeader.vue similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/DialogHeader.vue rename to apps/frontend/src/components/ui/dialog/DialogHeader.vue diff --git a/apps/new-frontend/src/components/ui/dialog/DialogOverlay.vue b/apps/frontend/src/components/ui/dialog/DialogOverlay.vue similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/DialogOverlay.vue rename to apps/frontend/src/components/ui/dialog/DialogOverlay.vue diff --git a/apps/new-frontend/src/components/ui/dialog/DialogScrollContent.vue b/apps/frontend/src/components/ui/dialog/DialogScrollContent.vue similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/DialogScrollContent.vue rename to apps/frontend/src/components/ui/dialog/DialogScrollContent.vue diff --git a/apps/new-frontend/src/components/ui/dialog/DialogTitle.vue b/apps/frontend/src/components/ui/dialog/DialogTitle.vue similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/DialogTitle.vue rename to apps/frontend/src/components/ui/dialog/DialogTitle.vue diff --git a/apps/new-frontend/src/components/ui/dialog/DialogTrigger.vue b/apps/frontend/src/components/ui/dialog/DialogTrigger.vue similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/DialogTrigger.vue rename to apps/frontend/src/components/ui/dialog/DialogTrigger.vue diff --git a/apps/new-frontend/src/components/ui/dialog/index.ts b/apps/frontend/src/components/ui/dialog/index.ts similarity index 100% rename from apps/new-frontend/src/components/ui/dialog/index.ts rename to apps/frontend/src/components/ui/dialog/index.ts diff --git a/apps/new-frontend/src/components/ui/tooltip/Tooltip.vue b/apps/frontend/src/components/ui/tooltip/Tooltip.vue similarity index 100% rename from apps/new-frontend/src/components/ui/tooltip/Tooltip.vue rename to apps/frontend/src/components/ui/tooltip/Tooltip.vue diff --git a/apps/new-frontend/src/components/ui/tooltip/TooltipContent.vue b/apps/frontend/src/components/ui/tooltip/TooltipContent.vue similarity index 100% rename from apps/new-frontend/src/components/ui/tooltip/TooltipContent.vue rename to apps/frontend/src/components/ui/tooltip/TooltipContent.vue diff --git a/apps/new-frontend/src/components/ui/tooltip/TooltipProvider.vue b/apps/frontend/src/components/ui/tooltip/TooltipProvider.vue similarity index 100% rename from apps/new-frontend/src/components/ui/tooltip/TooltipProvider.vue rename to apps/frontend/src/components/ui/tooltip/TooltipProvider.vue diff --git a/apps/new-frontend/src/components/ui/tooltip/TooltipTrigger.vue b/apps/frontend/src/components/ui/tooltip/TooltipTrigger.vue similarity index 100% rename from apps/new-frontend/src/components/ui/tooltip/TooltipTrigger.vue rename to apps/frontend/src/components/ui/tooltip/TooltipTrigger.vue diff --git a/apps/new-frontend/src/components/ui/tooltip/index.ts b/apps/frontend/src/components/ui/tooltip/index.ts similarity index 100% rename from apps/new-frontend/src/components/ui/tooltip/index.ts rename to apps/frontend/src/components/ui/tooltip/index.ts diff --git a/apps/frontend/src/composables/useAsyncAction.js b/apps/frontend/src/composables/useAsyncAction.js deleted file mode 100644 index 8f4297b..0000000 --- a/apps/frontend/src/composables/useAsyncAction.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 通用异步操作 Composable - * 统一处理 loading、error 状态和消息提示 - * - * @example - * const { loading, error, execute } = useAsyncAction() - * - * const handleSubmit = async () => { - * await execute( - * () => api.createTask(formData), - * { successMsg: '创建成功', errorMsg: '创建失败' } - * ) - * } - */ - -import { ref } from 'vue'; -import { message } from 'ant-design-vue'; - -export function useAsyncAction(options = {}) { - const loading = ref(false); - const error = ref(null); - - /** - * 执行异步操作 - * @param {Function} asyncFn - 异步函数 - * @param {Object} config - 配置选项 - * @param {string} config.successMsg - 成功提示消息 - * @param {string} config.errorMsg - 错误提示消息 - * @param {boolean} config.throwOnError - 是否抛出错误 - * @param {boolean} config.silent - 是否静默模式(不显示消息) - * @returns {Promise} 异步函数的返回值 - */ - const execute = async (asyncFn, config = {}) => { - const { - successMsg = options.successMsg, - errorMsg = options.errorMsg, - throwOnError = false, - silent = false, - } = config; - - loading.value = true; - error.value = null; - - try { - const result = await asyncFn(); - - if (!silent && successMsg) { - message.success({ content: successMsg, duration: 3 }); - } - - return result; - } catch (err) { - error.value = err; - - if (!silent) { - const msg = err.message || err.detail || errorMsg || '操作失败'; - message.error({ content: msg, duration: 4 }); - } - - if (throwOnError) { - throw err; - } - - return null; - } finally { - loading.value = false; - } - }; - - /** - * 重置状态 - */ - const reset = () => { - loading.value = false; - error.value = null; - }; - - return { - loading, - error, - execute, - reset, - }; -} diff --git a/apps/frontend/src/composables/useBreakpoint.js b/apps/frontend/src/composables/useBreakpoint.js deleted file mode 100644 index 25c01d6..0000000 --- a/apps/frontend/src/composables/useBreakpoint.js +++ /dev/null @@ -1,65 +0,0 @@ -import { ref, onMounted, onUnmounted } from 'vue'; - -/** - * 响应式断点检测 Composable - * 基于 Ant Design 的断点系统 - * - xs: <576px (手机) - * - sm: ≥576px (平板竖屏) - * - md: ≥768px (平板横屏) - * - lg: ≥992px (桌面) - * - xl: ≥1200px (大屏) - * - xxl: ≥1600px (超大屏) - */ -export function useBreakpoint() { - const isMobile = ref(window.innerWidth < 768); - const isTablet = ref(window.innerWidth >= 768 && window.innerWidth < 992); - const isDesktop = ref(window.innerWidth >= 992); - - // Ant Design 断点 - const isXs = ref(window.innerWidth < 576); - const isSm = ref(window.innerWidth >= 576 && window.innerWidth < 768); - const isMd = ref(window.innerWidth >= 768 && window.innerWidth < 992); - const isLg = ref(window.innerWidth >= 992 && window.innerWidth < 1200); - const isXl = ref(window.innerWidth >= 1200 && window.innerWidth < 1600); - const isXxl = ref(window.innerWidth >= 1600); - - const updateBreakpoints = () => { - const width = window.innerWidth; - - // 简化断点 - isMobile.value = width < 768; - isTablet.value = width >= 768 && width < 992; - isDesktop.value = width >= 992; - - // Ant Design 断点 - isXs.value = width < 576; - isSm.value = width >= 576 && width < 768; - isMd.value = width >= 768 && width < 992; - isLg.value = width >= 992 && width < 1200; - isXl.value = width >= 1200 && width < 1600; - isXxl.value = width >= 1600; - }; - - onMounted(() => { - window.addEventListener('resize', updateBreakpoints); - }); - - onUnmounted(() => { - window.removeEventListener('resize', updateBreakpoints); - }); - - return { - // 简化断点(常用) - isMobile, - isTablet, - isDesktop, - - // Ant Design 断点(详细) - isXs, - isSm, - isMd, - isLg, - isXl, - isXxl, - }; -} diff --git a/apps/frontend/src/composables/usePollStatus.js b/apps/frontend/src/composables/usePollStatus.js deleted file mode 100644 index 4d827e3..0000000 --- a/apps/frontend/src/composables/usePollStatus.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * 状态轮询 Composable - * 支持指数退避、最大重试次数、自动清理 - * - * @example - * const { polling, startPolling, stopPolling } = usePollStatus({ - * interval: 2000, - * maxRetries: 15, - * backoff: true - * }) - * - * startPolling( - * async () => { - * const status = await api.getStatus(id) - * return { - * completed: status.status !== 'pending', - * success: status.status === 'success', - * data: status - * } - * }, - * { - * onSuccess: (result) => console.log('完成', result), - * onFailure: (error) => console.error('失败', error), - * onTimeout: () => console.warn('超时') - * } - * ) - */ - -import { ref, onUnmounted } from 'vue'; - -export function usePollStatus(options = {}) { - const { - interval = 2000, // 初始轮询间隔(毫秒) - maxRetries = 15, // 最大重试次数 - backoff = false, // 是否使用指数退避 - maxBackoffInterval = 10000, // 最大退避间隔(毫秒) - } = options; - - const polling = ref(false); - let pollTimer = null; - let retryCount = 0; - - /** - * 开始轮询 - * @param {Function} checkFn - 检查函数,应返回 { completed, success, data } - * @param {Object} callbacks - 回调函数 - * @param {Function} callbacks.onSuccess - 成功回调 - * @param {Function} callbacks.onFailure - 失败回调 - * @param {Function} callbacks.onTimeout - 超时回调 - */ - const startPolling = async (checkFn, callbacks = {}) => { - const { onSuccess, onFailure, onTimeout } = callbacks; - - // 重置状态 - stopPolling(); - polling.value = true; - retryCount = 0; - - const poll = async () => { - try { - const result = await checkFn(); - - // 检查是否完成 - if (result.completed) { - stopPolling(); - - if (result.success) { - onSuccess?.(result.data || result); - } else { - onFailure?.(result.data || result); - } - return; - } - - // 检查是否超时 - retryCount++; - if (retryCount >= maxRetries) { - stopPolling(); - onTimeout?.(); - return; - } - - // 计算下次轮询间隔(支持指数退避) - let nextInterval = interval; - if (backoff) { - // 指数退避:2s -> 4s -> 8s -> 最大10s - nextInterval = Math.min(interval * Math.pow(2, retryCount - 1), maxBackoffInterval); - } - - // 继续轮询 - pollTimer = setTimeout(poll, nextInterval); - } catch (error) { - stopPolling(); - onFailure?.(error); - } - }; - - // 立即执行第一次检查 - poll(); - }; - - /** - * 停止轮询 - */ - const stopPolling = () => { - if (pollTimer) { - clearTimeout(pollTimer); - pollTimer = null; - } - polling.value = false; - retryCount = 0; - }; - - // 组件卸载时自动清理 - onUnmounted(() => { - stopPolling(); - }); - - return { - polling, - startPolling, - stopPolling, - }; -} diff --git a/apps/frontend/src/composables/useTheme.js b/apps/frontend/src/composables/useTheme.js deleted file mode 100644 index db1e7cf..0000000 --- a/apps/frontend/src/composables/useTheme.js +++ /dev/null @@ -1,106 +0,0 @@ -import { ref, computed } from 'vue'; - -const THEME_STORAGE_KEY = 'checkin-app-theme'; - -// 全局主题状态(单例模式) -const theme = ref('light'); - -/** - * 应用主题到 DOM - */ -const applyTheme = newTheme => { - const html = document.documentElement; - - if (newTheme === 'dark') { - html.classList.add('dark'); - } else { - html.classList.remove('dark'); - } -}; - -/** - * 初始化主题 - * 优先级: localStorage > 系统偏好 > 默认亮色 - */ -export const initTheme = () => { - // 1. 尝试从 localStorage 读取 - const savedTheme = localStorage.getItem(THEME_STORAGE_KEY); - if (savedTheme === 'light' || savedTheme === 'dark') { - theme.value = savedTheme; - applyTheme(savedTheme); - return; - } - - // 2. 检测系统偏好 - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - theme.value = 'dark'; - applyTheme('dark'); - return; - } - - // 3. 默认亮色 - theme.value = 'light'; - applyTheme('light'); -}; - -/** - * 监听系统主题变化 - */ -export const watchSystemTheme = () => { - if (!window.matchMedia) return; - - const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); - - const handleChange = e => { - // 仅在用户未手动设置主题时才跟随系统 - const savedTheme = localStorage.getItem(THEME_STORAGE_KEY); - if (!savedTheme) { - const systemTheme = e.matches ? 'dark' : 'light'; - theme.value = systemTheme; - applyTheme(systemTheme); - } - }; - - mediaQuery.addEventListener('change', handleChange); - - // 返回清理函数 - return () => mediaQuery.removeEventListener('change', handleChange); -}; - -/** - * 主题管理 Composable - * 支持亮色/暗色模式切换,并持久化到 localStorage - */ -export function useTheme() { - /** - * 切换主题 - */ - const toggleTheme = () => { - const newTheme = theme.value === 'light' ? 'dark' : 'light'; - theme.value = newTheme; - applyTheme(newTheme); - localStorage.setItem(THEME_STORAGE_KEY, newTheme); - }; - - /** - * 设置指定主题 - */ - const setTheme = newTheme => { - if (newTheme !== 'light' && newTheme !== 'dark') { - console.warn(`Invalid theme: ${newTheme}. Using 'light' instead.`); - newTheme = 'light'; - } - - theme.value = newTheme; - applyTheme(newTheme); - localStorage.setItem(THEME_STORAGE_KEY, newTheme); - }; - - return { - theme, - toggleTheme, - setTheme, - isDark: computed(() => theme.value === 'dark'), - isLight: computed(() => theme.value === 'light'), - }; -} diff --git a/apps/frontend/src/composables/useTokenMonitor.js b/apps/frontend/src/composables/useTokenMonitor.js deleted file mode 100644 index d04c449..0000000 --- a/apps/frontend/src/composables/useTokenMonitor.js +++ /dev/null @@ -1,190 +0,0 @@ -import { computed, onMounted } from 'vue'; -import { message } from 'ant-design-vue'; -import { useAuthStore } from '@/stores/auth'; -import { useUserStore } from '@/stores/user'; -import { useRouter } from 'vue-router'; - -/** - * Token 过期监控 Composable - * - * 功能: - * 1. 定时检查 Token 状态 - * 2. Token 过期后 5 分钟内提醒用户 - * 3. 为有密码的用户提供友好的过期处理 - * - * 注意:使用单例模式,确保全局只有一个监控实例 - */ - -// 全局单例:确保整个应用只有一个监控实例 -let monitorTimer = null; -let warningShown = false; -let isMonitoring = false; // 新增:防止重复启动 - -// 检查间隔(毫秒) -const NORMAL_CHECK_INTERVAL = 15 * 60 * 1000; // 正常情况:15 分钟 -const URGENT_CHECK_INTERVAL = 5 * 60 * 1000; // Token 即将过期:5 分钟 - -export function useTokenMonitor() { - const authStore = useAuthStore(); - const userStore = useUserStore(); - const router = useRouter(); - - const tokenStatus = computed(() => userStore.tokenStatus); - const hasPassword = computed(() => authStore.user?.has_password || false); - - // 计算 Token 剩余分钟数 - const getRemainingMinutes = () => { - if (!tokenStatus.value?.expires_at) return null; - - const now = Math.floor(Date.now() / 1000); - const expiresAt = tokenStatus.value.expires_at; - const diffSeconds = expiresAt - now; - - return Math.floor(diffSeconds / 60); - }; - - // 检查 Token 状态并显示提醒 - const checkTokenStatus = async () => { - // 如果未登录,不检查 - if (!authStore.isAuthenticated) { - return; - } - - try { - // 获取最新的 Token 状态 - await userStore.fetchTokenStatus(); - - const remainingMinutes = getRemainingMinutes(); - - // Token 已过期(负数分钟) - if (remainingMinutes !== null && remainingMinutes < 0) { - const expiredMinutes = Math.abs(remainingMinutes); - - // Token 过期后 5 分钟内提醒 - if (expiredMinutes <= 5) { - if (hasPassword.value) { - // 有密码的用户:友好提示 - if (!warningShown) { - message.warning({ - content: `您的 Token 已过期 ${expiredMinutes} 分钟,部分功能可能受限。建议您扫码刷新凭证。`, - duration: 3, - key: 'token-expired-warning', - }); - warningShown = true; - } - } else { - // 没有密码的用户:必须重新登录 - message.error({ - content: '您的 Token 已过期,请重新扫码登录', - duration: 5, - key: 'token-expired-error', - }); - - // 清除登录状态并跳转 - authStore.logout(); - router.push('/login'); - } - } else if (expiredMinutes > 5) { - // 过期超过 5 分钟 - if (!hasPassword.value) { - // 没有密码的用户:强制退出 - authStore.logout(); - router.push('/login'); - } - } - } - // Token 即将过期(1小时内) - else if (remainingMinutes !== null && remainingMinutes > 0 && remainingMinutes <= 60) { - if (!warningShown) { - message.warning({ - content: `您的 Token 将在 ${remainingMinutes} 分钟后过期,建议您及时刷新`, - duration: 3, - key: 'token-expiring-warning', - }); - warningShown = true; - } - - // Token 即将过期时,切换到更频繁的检查(5 分钟) - adjustCheckInterval(URGENT_CHECK_INTERVAL); - } - // Token 状态正常 - else if (remainingMinutes !== null && remainingMinutes > 60) { - // 重置警告标志 - warningShown = false; - - // 恢复正常检查频率(15 分钟) - adjustCheckInterval(NORMAL_CHECK_INTERVAL); - } - } catch (error) { - console.error('检查 Token 状态失败:', error); - } - }; - - // 调整检查间隔 - const adjustCheckInterval = newInterval => { - if (monitorTimer) { - const currentInterval = monitorTimer._idleTimeout || 0; - - // 只有当新间隔与当前间隔不同时才重启定时器 - if (currentInterval !== newInterval) { - clearInterval(monitorTimer); - monitorTimer = setInterval(() => { - checkTokenStatus(); - }, newInterval); - } - } - }; - - // 启动监控 - const startMonitoring = () => { - // 避免重复启动(单例模式) - if (isMonitoring || monitorTimer) { - return; - } - - isMonitoring = true; - - // 立即检查一次 - checkTokenStatus(); - - // 默认使用正常检查频率(15 分钟) - monitorTimer = setInterval(() => { - checkTokenStatus(); - }, NORMAL_CHECK_INTERVAL); - }; - - // 停止监控 - const stopMonitoring = () => { - if (monitorTimer) { - clearInterval(monitorTimer); - monitorTimer = null; - } - isMonitoring = false; - warningShown = false; - }; - - // 手动触发检查 - const checkNow = () => { - warningShown = false; // 重置警告标志,允许再次显示 - checkTokenStatus(); - }; - - // 组件挂载时启动监控 - onMounted(() => { - if (authStore.isAuthenticated) { - startMonitoring(); - } - }); - - // 组件卸载时不停止监控(因为是全局单例) - // onUnmounted 中不调用 stopMonitoring(),让监控持续运行 - - return { - tokenStatus, - hasPassword, - startMonitoring, - stopMonitoring, - checkNow, - getRemainingMinutes, - }; -} diff --git a/apps/new-frontend/src/lib/utils.ts b/apps/frontend/src/lib/utils.ts similarity index 100% rename from apps/new-frontend/src/lib/utils.ts rename to apps/frontend/src/lib/utils.ts diff --git a/apps/frontend/src/main.js b/apps/frontend/src/main.js deleted file mode 100644 index b99efc6..0000000 --- a/apps/frontend/src/main.js +++ /dev/null @@ -1,53 +0,0 @@ -import { createApp } from 'vue'; -import { createPinia } from 'pinia'; - -// Ant Design Vue -import Antd, { message } from 'ant-design-vue'; -import 'ant-design-vue/dist/reset.css'; - -import App from './App.vue'; -import router from './router'; -import './style.css'; - -const app = createApp(App); -const pinia = createPinia(); - -app.use(pinia); -app.use(router); - -// Ant Design Vue -app.use(Antd); - -// 全局未捕获的 Promise 错误处理 -window.addEventListener('unhandledrejection', event => { - console.error('未捕获的 Promise 错误:', event.reason); - - // 显示用户友好的错误提示 - const errorMessage = event.reason?.message || event.reason || '操作失败'; - - // 只对非网络错误显示提示(网络错误已在 axios 拦截器中处理) - if (!errorMessage.includes('网络错误') && !errorMessage.includes('请求超时')) { - message.error({ - content: `操作失败: ${errorMessage}`, - duration: 3, - }); - } - - // 阻止默认的控制台错误输出(已经用 console.error 输出了) - event.preventDefault(); -}); - -// 全局错误处理(捕获 Vue 组件内的错误) -app.config.errorHandler = (err, instance, info) => { - console.error('Vue 错误:', err); - console.error('错误信息:', info); - console.error('组件实例:', instance); - - // 显示用户友好的错误提示 - message.error({ - content: '应用发生错误,请刷新页面重试', - duration: 3, - }); -}; - -app.mount('#app'); diff --git a/apps/new-frontend/src/main.ts b/apps/frontend/src/main.ts similarity index 100% rename from apps/new-frontend/src/main.ts rename to apps/frontend/src/main.ts diff --git a/apps/frontend/src/router/index.js b/apps/frontend/src/router/index.js deleted file mode 100644 index 2b376ad..0000000 --- a/apps/frontend/src/router/index.js +++ /dev/null @@ -1,162 +0,0 @@ -import { createRouter, createWebHistory } from 'vue-router'; -import { useAuthStore } from '@/stores/auth'; -import { userAPI } from '@/api'; - -const routes = [ - { - path: '/login', - name: 'Login', - component: () => import('@/views/LoginView.vue'), - meta: { requiresAuth: false, title: '登录' }, - }, - { - path: '/', - redirect: '/dashboard', - }, - { - path: '/pending-approval', - name: 'PendingApproval', - component: () => import('@/views/PendingApprovalView.vue'), - meta: { requiresAuth: true, title: '等待审批' }, - }, - { - path: '/dashboard', - name: 'Dashboard', - component: () => import('@/views/DashboardView.vue'), - meta: { requiresAuth: true, title: '我的仪表盘' }, - }, - { - path: '/tasks', - name: 'Tasks', - component: () => import('@/views/TasksView.vue'), - meta: { requiresAuth: true, title: '任务管理' }, - }, - { - path: '/tasks/:taskId/records', - name: 'TaskRecords', - component: () => import('@/views/TaskRecordsView.vue'), - meta: { requiresAuth: true, title: '任务打卡记录' }, - }, - { - path: '/records', - name: 'Records', - component: () => import('@/views/RecordsView.vue'), - meta: { requiresAuth: true, title: '打卡记录' }, - }, - { - path: '/settings', - name: 'Settings', - component: () => import('@/views/SettingsView.vue'), - meta: { requiresAuth: true, title: '个人设置' }, - }, - { - path: '/admin', - meta: { requiresAuth: true, requiresAdmin: true }, - children: [ - { - path: 'users', - name: 'AdminUsers', - component: () => import('@/views/admin/UsersView.vue'), - meta: { requiresAuth: true, requiresAdmin: true, title: '用户管理' }, - }, - { - path: 'records', - name: 'AdminRecords', - component: () => import('@/views/admin/RecordsView.vue'), - meta: { requiresAuth: true, requiresAdmin: true, title: '打卡记录' }, - }, - { - path: 'logs', - name: 'AdminLogs', - component: () => import('@/views/admin/LogsView.vue'), - meta: { requiresAuth: true, requiresAdmin: true, title: '系统日志' }, - }, - { - path: 'stats', - name: 'AdminStats', - component: () => import('@/views/admin/StatsView.vue'), - meta: { requiresAuth: true, requiresAdmin: true, title: '统计信息' }, - }, - { - path: 'templates', - name: 'AdminTemplates', - component: () => import('@/views/admin/TemplatesView.vue'), - meta: { requiresAuth: true, requiresAdmin: true, title: '模板管理' }, - }, - ], - }, - { - path: '/:pathMatch(.*)*', - name: 'NotFound', - component: () => import('@/views/NotFoundView.vue'), - meta: { requiresAuth: false, title: '页面未找到' }, - }, -]; - -const router = createRouter({ - history: createWebHistory(), - routes, -}); - -// 全局前置守卫 -router.beforeEach(async (to, from, next) => { - const authStore = useAuthStore(); - - // 设置页面标题 - document.title = to.meta.title ? `${to.meta.title} - 接龙自动打卡系统` : '接龙自动打卡系统'; - - // 检查是否需要认证 - if (to.meta.requiresAuth) { - if (!authStore.isAuthenticated) { - // 未登录,重定向到登录页 - next({ name: 'Login', query: { redirect: to.fullPath } }); - return; - } - - // 检查用户审批状态(除了待审批页面本身) - if (to.name !== 'PendingApproval') { - try { - const status = await userAPI.getUserStatus(); - - if (!status.is_approved) { - // 未审批用户只能访问待审批页面 - next({ name: 'PendingApproval' }); - return; - } - } catch (error) { - console.error('检查审批状态失败:', error); - // 如果检查失败,允许继续访问(避免阻塞正常用户) - } - } else { - // 访问待审批页面时,检查是否已审批 - try { - const status = await userAPI.getUserStatus(); - - if (status.is_approved) { - // 已审批用户不能访问待审批页面 - next({ name: 'Dashboard' }); - return; - } - } catch (error) { - console.error('检查审批状态失败:', error); - } - } - - // 检查是否需要管理员权限 - if (to.meta.requiresAdmin && !authStore.isAdmin) { - // 非管理员,重定向到仪表盘 - next({ name: 'Dashboard' }); - return; - } - } else { - // 不需要认证的页面,如果已登录则重定向到仪表盘 - if (to.name === 'Login' && authStore.isAuthenticated) { - next({ name: 'Dashboard' }); - return; - } - } - - next(); -}); - -export default router; diff --git a/apps/frontend/src/stores/admin.js b/apps/frontend/src/stores/admin.js deleted file mode 100644 index 6a1ccd2..0000000 --- a/apps/frontend/src/stores/admin.js +++ /dev/null @@ -1,62 +0,0 @@ -import { defineStore } from 'pinia'; -import { adminAPI } from '@/api'; - -export const useAdminStore = defineStore('admin', { - state: () => ({ - stats: null, // 系统统计信息 - logs: [], - logsTotal: 0, - loading: false, - }), - - getters: { - totalUsers: state => state.stats?.users?.total || 0, - activeUsers: state => { - // Active users = 已审批的用户(is_approved=true) - return state.stats?.users?.active || 0; - }, - totalRecords: state => state.stats?.check_in_records?.total || 0, - todayRecords: state => state.stats?.check_in_records?.today || 0, - }, - - actions: { - // 获取系统统计信息 - async fetchStats() { - this.loading = true; - try { - const stats = await adminAPI.getStats(); - this.stats = stats; - return stats; - } catch (error) { - throw new Error(error.message || '获取统计信息失败'); - } finally { - this.loading = false; - } - }, - - // 批量触发打卡 - async batchCheckIn(userIds) { - try { - const result = await adminAPI.batchCheckIn(userIds); - return result; - } catch (error) { - throw new Error(error.message || '批量打卡失败'); - } - }, - - // 获取系统日志 - async fetchLogs(params = {}) { - this.loading = true; - try { - const data = await adminAPI.getLogs(params); - this.logs = data.logs || data; - this.logsTotal = data.total || this.logs.length; - return data; - } catch (error) { - throw new Error(error.message || '获取日志失败'); - } finally { - this.loading = false; - } - }, - }, -}); diff --git a/apps/frontend/src/stores/auth.js b/apps/frontend/src/stores/auth.js deleted file mode 100644 index bb67f19..0000000 --- a/apps/frontend/src/stores/auth.js +++ /dev/null @@ -1,133 +0,0 @@ -import { defineStore } from 'pinia'; -import { authAPI, userAPI } from '@/api'; - -export const useAuthStore = defineStore('auth', { - state: () => { - // 安全地解析 localStorage 中的用户数据 - let user = null; - try { - const userStr = localStorage.getItem('user'); - if (userStr && userStr !== 'undefined' && userStr !== 'null') { - user = JSON.parse(userStr); - } - } catch (e) { - console.warn('Failed to parse user from localStorage:', e); - localStorage.removeItem('user'); - } - - return { - token: localStorage.getItem('token') || null, - user, - }; - }, - - getters: { - // 将 isAuthenticated 改为 getter,这样它会实时反应 state.token 的变化 - isAuthenticated: state => !!state.token, - isAdmin: state => state.user?.role === 'admin', - }, - - actions: { - // 设置认证信息 - setAuth(token, user) { - // 清理 token:移除 URL 编码的 Bearer 前缀 - let cleanToken = token; - if (cleanToken) { - // URL 解码 - cleanToken = decodeURIComponent(cleanToken); - // 移除 Bearer 前缀(如果存在) - if (cleanToken.toLowerCase().startsWith('bearer ')) { - cleanToken = cleanToken.substring(7); - } - } - - this.token = cleanToken; - this.user = user; - - localStorage.setItem('token', cleanToken); - localStorage.setItem('user', JSON.stringify(user)); - }, - - // 清除认证信息 - clearAuth() { - this.token = null; - this.user = null; - - localStorage.removeItem('token'); - localStorage.removeItem('user'); - }, - - // QR 码登录流程 - async loginWithQRCode(alias) { - try { - // 1. 请求 QR 码 - const qrData = await authAPI.requestQRCode(alias); - const { session_id, qrcode_base64 } = qrData; - - // 2. 返回 session_id 和 qrcode,由组件处理轮询 - return { session_id, qrcode_base64 }; - } catch (error) { - throw new Error(error.message || '请求二维码失败'); - } - }, - - // 检查扫码状态 - async checkQRCodeStatus(sessionId) { - try { - const result = await authAPI.getQRCodeStatus(sessionId); - - if (result.status === 'success') { - // 扫码成功,保存 Token 和用户信息 - this.setAuth(result.token, result.user); - return { success: true, user: result.user }; - } else if (result.status === 'failed') { - return { success: false, message: result.message }; - } else { - // pending 或 expired - return { success: false, status: result.status }; - } - } catch (error) { - throw new Error(error.message || '检查扫码状态失败'); - } - }, - - // 取消扫码会话 - async cancelQRCodeSession(sessionId) { - try { - await authAPI.cancelQRCodeSession(sessionId); - } catch (error) { - console.error('取消会话失败:', error); - } - }, - - // 验证 Token - async verifyToken(token) { - try { - const userData = await authAPI.verifyToken(token); - this.setAuth(token, userData); - return userData; - } catch (error) { - this.clearAuth(); - throw new Error(error.message || 'Token 验证失败'); - } - }, - - // 获取当前用户信息 - async fetchCurrentUser() { - try { - const userData = await userAPI.getCurrentUser(); - // 更新本地用户信息 - this.user = userData; - localStorage.setItem('user', JSON.stringify(userData)); - return userData; - } catch (error) { - throw new Error(error.message || '获取用户信息失败'); - } - }, - - // 登出 - logout() { - this.clearAuth(); - }, - }, -}); diff --git a/apps/frontend/src/stores/checkIn.js b/apps/frontend/src/stores/checkIn.js deleted file mode 100644 index b573220..0000000 --- a/apps/frontend/src/stores/checkIn.js +++ /dev/null @@ -1,96 +0,0 @@ -import { defineStore } from 'pinia'; -import { checkInAPI } from '@/api'; - -export const useCheckInStore = defineStore('checkIn', { - state: () => ({ - myRecords: [], - allRecords: [], // 管理员查看所有记录 - currentPage: 1, - pageSize: 20, - total: 0, - loading: false, - }), - - getters: { - todayRecords: state => { - const today = new Date().toISOString().split('T')[0]; - return state.myRecords.filter(record => { - const recordDate = new Date(record.check_in_time).toISOString().split('T')[0]; - return recordDate === today; - }); - }, - - successRate: state => { - if (state.myRecords.length === 0) return 0; - const successCount = state.myRecords.filter(r => r.status === 'success').length; - return ((successCount / state.myRecords.length) * 100).toFixed(2); - }, - }, - - actions: { - // 手动打卡 - async manualCheckIn() { - this.loading = true; - try { - const result = await checkInAPI.manualCheckIn(); - // 刷新打卡记录 - await this.fetchMyRecords(); - return result; - } catch (error) { - throw new Error(error.message || '打卡失败'); - } finally { - this.loading = false; - } - }, - - // 获取我的打卡记录 - async fetchMyRecords(params = {}) { - this.loading = true; - try { - const data = await checkInAPI.getMyRecords({ - skip: (this.currentPage - 1) * this.pageSize, - limit: this.pageSize, - ...params, - }); - // 后端现在返回 { records, total, skip, limit } - this.myRecords = data.records || data; - this.total = data.total || 0; - return data; - } catch (error) { - throw new Error(error.message || '获取打卡记录失败'); - } finally { - this.loading = false; - } - }, - - // 获取所有打卡记录(管理员) - async fetchAllRecords(params = {}) { - this.loading = true; - try { - const data = await checkInAPI.getAllRecords({ - skip: (this.currentPage - 1) * this.pageSize, - limit: this.pageSize, - ...params, - }); - // 后端现在返回 { records, total, skip, limit } - this.allRecords = data.records || data; - this.total = data.total || 0; - return data; - } catch (error) { - throw new Error(error.message || '获取打卡记录失败'); - } finally { - this.loading = false; - } - }, - - // 统计打卡记录 - async getRecordsCount(params = {}) { - try { - const count = await checkInAPI.getRecordsCount(params); - return count; - } catch (error) { - throw new Error(error.message || '获取统计信息失败'); - } - }, - }, -}); diff --git a/apps/frontend/src/stores/task.js b/apps/frontend/src/stores/task.js deleted file mode 100644 index ecbefef..0000000 --- a/apps/frontend/src/stores/task.js +++ /dev/null @@ -1,164 +0,0 @@ -import { defineStore } from 'pinia'; -import api from '@/api'; - -export const useTaskStore = defineStore('task', { - state: () => ({ - tasks: [], // 当前用户的任务列表 - currentTask: null, // 当前选中的任务 - loading: false, - error: null, - }), - - getters: { - // 启用的任务 - activeTasks: state => state.tasks.filter(t => t.is_active), - - // 禁用的任务 - inactiveTasks: state => state.tasks.filter(t => !t.is_active), - - // 任务数量统计 - taskStats: state => ({ - total: state.tasks.length, - active: state.tasks.filter(t => t.is_active).length, - inactive: state.tasks.filter(t => !t.is_active).length, - }), - - // 根据 ID 获取任务 - getTaskById: state => taskId => { - return state.tasks.find(t => t.id === taskId); - }, - }, - - actions: { - // 获取当前用户的所有任务 - async fetchMyTasks(includeInactive = true) { - this.loading = true; - this.error = null; - try { - const tasks = await api.task.getMyTasks({ include_inactive: includeInactive }); - this.tasks = tasks; - return tasks; - } catch (error) { - this.error = error.message || '获取任务列表失败'; - throw error; - } finally { - this.loading = false; - } - }, - - // 更新任务 - async updateTask(taskId, taskData) { - this.loading = true; - this.error = null; - try { - const updatedTask = await api.task.updateTask(taskId, taskData); - const index = this.tasks.findIndex(t => t.id === taskId); - if (index !== -1) { - this.tasks[index] = updatedTask; - } - return updatedTask; - } catch (error) { - this.error = error.message || '更新任务失败'; - throw error; - } finally { - this.loading = false; - } - }, - - // 删除任务 - async deleteTask(taskId) { - this.loading = true; - this.error = null; - try { - await api.task.deleteTask(taskId); - this.tasks = this.tasks.filter(t => t.id !== taskId); - } catch (error) { - this.error = error.message || '删除任务失败'; - throw error; - } finally { - this.loading = false; - } - }, - - // 切换任务启用状态 - async toggleTask(taskId) { - this.loading = true; - this.error = null; - try { - const updatedTask = await api.task.toggleTask(taskId); - const index = this.tasks.findIndex(t => t.id === taskId); - if (index !== -1) { - // 保留原任务的 last_check_in_time 和 last_check_in_status - const originalTask = this.tasks[index]; - this.tasks[index] = { - ...updatedTask, - last_check_in_time: updatedTask.last_check_in_time || originalTask.last_check_in_time, - last_check_in_status: - updatedTask.last_check_in_status || originalTask.last_check_in_status, - }; - } - return updatedTask; - } catch (error) { - this.error = error.message || '切换任务状态失败'; - throw error; - } finally { - this.loading = false; - } - }, - - // 获取任务详情 - async fetchTask(taskId) { - this.loading = true; - this.error = null; - try { - const task = await api.task.getTask(taskId); - this.currentTask = task; - return task; - } catch (error) { - this.error = error.message || '获取任务详情失败'; - throw error; - } finally { - this.loading = false; - } - }, - - // 手动触发任务打卡(异步方式,立即返回 record_id) - async checkInTask(taskId) { - // Don't set global loading state to avoid blocking UI during long check-in operations - this.error = null; - try { - const result = await api.task.checkInTask(taskId); - return result; - } catch (error) { - this.error = error.message || '打卡失败'; - throw error; - } - }, - - // 查询打卡记录状态 - async getCheckInRecordStatus(recordId) { - const result = await api.task.getCheckInRecordStatus(recordId); - return result; - }, - - // 获取任务的打卡记录 - async fetchTaskRecords(taskId, params = {}) { - this.loading = true; - this.error = null; - try { - const records = await api.task.getTaskRecords(taskId, params); - return records; - } catch (error) { - this.error = error.message || '获取打卡记录失败'; - throw error; - } finally { - this.loading = false; - } - }, - - // 清空当前任务 - clearCurrentTask() { - this.currentTask = null; - }, - }, -}); diff --git a/apps/frontend/src/stores/template.js b/apps/frontend/src/stores/template.js deleted file mode 100644 index 378abb3..0000000 --- a/apps/frontend/src/stores/template.js +++ /dev/null @@ -1,169 +0,0 @@ -import { defineStore } from 'pinia'; -import { templateAPI } from '@/api'; - -export const useTemplateStore = defineStore('template', { - state: () => ({ - templates: [], - currentTemplate: null, - loading: false, - error: null, - }), - - getters: { - activeTemplates: state => state.templates.filter(t => t.is_active), - - getTemplateById: state => id => { - return state.templates.find(t => t.id === id); - }, - }, - - actions: { - async fetchTemplates(isActive = null) { - this.loading = true; - this.error = null; - try { - const params = {}; - if (isActive !== null) { - params.is_active = isActive; - } - this.templates = await templateAPI.getTemplates(params); - return this.templates; - } catch (error) { - this.error = error.message || '获取模板列表失败'; - throw error; - } finally { - this.loading = false; - } - }, - - async fetchActiveTemplates() { - this.loading = true; - this.error = null; - try { - this.templates = await templateAPI.getActiveTemplates(); - return this.templates; - } catch (error) { - this.error = error.message || '获取启用模板失败'; - throw error; - } finally { - this.loading = false; - } - }, - - async fetchTemplate(id) { - this.loading = true; - this.error = null; - try { - this.currentTemplate = await templateAPI.getTemplate(id); - return this.currentTemplate; - } catch (error) { - this.error = error.message || '获取模板详情失败'; - throw error; - } finally { - this.loading = false; - } - }, - - async previewTemplate(id) { - this.loading = true; - this.error = null; - try { - const preview = await templateAPI.previewTemplate(id); - return preview; - } catch (error) { - this.error = error.message || '预览模板失败'; - throw error; - } finally { - this.loading = false; - } - }, - - async createTemplate(templateData) { - this.loading = true; - this.error = null; - try { - const newTemplate = await templateAPI.createTemplate(templateData); - this.templates.unshift(newTemplate); - return newTemplate; - } catch (error) { - this.error = error.message || '创建模板失败'; - throw error; - } finally { - this.loading = false; - } - }, - - async updateTemplate(id, templateData) { - this.loading = true; - this.error = null; - try { - const updatedTemplate = await templateAPI.updateTemplate(id, templateData); - const index = this.templates.findIndex(t => t.id === id); - if (index !== -1) { - this.templates[index] = updatedTemplate; - } - if (this.currentTemplate && this.currentTemplate.id === id) { - this.currentTemplate = updatedTemplate; - } - return updatedTemplate; - } catch (error) { - this.error = error.message || '更新模板失败'; - throw error; - } finally { - this.loading = false; - } - }, - - async deleteTemplate(id) { - this.loading = true; - this.error = null; - try { - await templateAPI.deleteTemplate(id); - this.templates = this.templates.filter(t => t.id !== id); - if (this.currentTemplate && this.currentTemplate.id === id) { - this.currentTemplate = null; - } - return true; - } catch (error) { - this.error = error.message || '删除模板失败'; - throw error; - } finally { - this.loading = false; - } - }, - - async createTaskFromTemplate( - templateId, - threadId, - fieldValues, - taskName = null, - cronExpression = '0 20 * * *' - ) { - this.loading = true; - this.error = null; - try { - const task = await templateAPI.createTaskFromTemplate({ - template_id: templateId, - thread_id: threadId, - field_values: fieldValues, - task_name: taskName, - cron_expression: cronExpression, - }); - return task; - } catch (error) { - this.error = error.message || '从模板创建任务失败'; - throw error; - } finally { - this.loading = false; - } - }, - - clearCurrentTemplate() { - this.currentTemplate = null; - }, - - clearError() { - this.error = null; - }, - }, -}); diff --git a/apps/frontend/src/stores/user.js b/apps/frontend/src/stores/user.js deleted file mode 100644 index 5a1ab5f..0000000 --- a/apps/frontend/src/stores/user.js +++ /dev/null @@ -1,94 +0,0 @@ -import { defineStore } from 'pinia'; -import { userAPI } from '@/api'; - -export const useUserStore = defineStore('user', { - state: () => ({ - tokenStatus: null, // Token 状态信息 - users: [], // 用户列表(管理员) - currentPage: 1, - pageSize: 20, - total: 0, - }), - - getters: { - isTokenExpiring: state => { - if (!state.tokenStatus) return false; - return state.tokenStatus.expiring_soon || false; - }, - - tokenExpireTime: state => { - if (!state.tokenStatus || !state.tokenStatus.expires_at) return null; - return new Date(state.tokenStatus.expires_at * 1000); - }, - }, - - actions: { - // 获取 Token 状态 - async fetchTokenStatus() { - try { - const status = await userAPI.getTokenStatus(); - this.tokenStatus = status; - return status; - } catch (error) { - throw new Error(error.message || '获取 Token 状态失败'); - } - }, - - // 获取用户列表(管理员) - async fetchUsers(params = {}) { - try { - const data = await userAPI.getUsers(params); - this.users = data.users || data; - this.total = data.total || this.users.length; - return data; - } catch (error) { - throw new Error(error.message || '获取用户列表失败'); - } - }, - - // 创建用户(管理员) - async createUser(userData) { - try { - const newUser = await userAPI.createUser(userData); - // 刷新用户列表 - await this.fetchUsers(); - return newUser; - } catch (error) { - throw new Error(error.message || '创建用户失败'); - } - }, - - // 更新用户 - async updateUser(userId, userData) { - try { - // 过滤空密码字段 - const cleanedData = { ...userData }; - if ( - cleanedData.password === '' || - cleanedData.password === null || - cleanedData.password === undefined - ) { - delete cleanedData.password; - } - - const updatedUser = await userAPI.updateUser(userId, cleanedData); - // 刷新用户列表 - await this.fetchUsers(); - return updatedUser; - } catch (error) { - throw new Error(error.message || '更新用户失败'); - } - }, - - // 删除用户 - async deleteUser(userId) { - try { - await userAPI.deleteUser(userId); - // 刷新用户列表 - await this.fetchUsers(); - } catch (error) { - throw new Error(error.message || '删除用户失败'); - } - }, - }, -}); diff --git a/apps/frontend/src/style.css b/apps/frontend/src/style.css index bc19c22..c22fcd0 100644 --- a/apps/frontend/src/style.css +++ b/apps/frontend/src/style.css @@ -1,1194 +1,197 @@ -/* ============================================ - Material Design 3 全局样式 - 严格遵循 Material Design 3 规范 - https://m3.material.io/ - ============================================ */ +@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;500;600;700&display=swap'); -/* TailwindCSS directives */ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import 'tailwindcss'; +@import 'tw-animate-css'; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --font-sans: var(--font-sans-app); + --font-heading: var(--font-sans); + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar: var(--sidebar); + --color-chart-5: var(--chart-5); + --color-chart-4: var(--chart-4); + --color-chart-3: var(--chart-3); + --color-chart-2: var(--chart-2); + --color-chart-1: var(--chart-1); + --color-ring: var(--ring); + --color-input: var(--input); + --color-border: var(--border); + --color-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-card-foreground: var(--card-foreground); + --color-card: var(--card); + --color-foreground: var(--foreground); + --color-background: var(--background); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); +} + +:root { + --font-sans-app: + 'Noto Sans', 'PingFang SC', 'Microsoft YaHei', system-ui, -apple-system, BlinkMacSystemFont, + 'Segoe UI', sans-serif; + --radius: 0.625rem; + --background: oklch(0.985 0.004 145); + --foreground: oklch(0.141 0.005 285.823); + --card: oklch(1 0 0); + --card-foreground: oklch(0.141 0.005 285.823); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.141 0.005 285.823); + --primary: oklch(0.49 0.14 150); + --primary-foreground: oklch(0.99 0.006 145); + --secondary: oklch(0.965 0.015 150); + --secondary-foreground: oklch(0.21 0.006 285.885); + --muted: oklch(0.967 0.001 286.375); + --muted-foreground: oklch(0.552 0.016 285.938); + --accent: oklch(0.94 0.045 150); + --accent-foreground: oklch(0.23 0.07 150); + --destructive: oklch(0.577 0.245 27.325); + --tone-success-bg: oklch(0.965 0.045 150); + --tone-success-fg: oklch(0.36 0.11 150); + --tone-success-border: oklch(0.84 0.09 150); + --tone-warning-bg: oklch(0.97 0.05 88); + --tone-warning-fg: oklch(0.42 0.1 70); + --tone-warning-border: oklch(0.85 0.11 82); + --tone-danger-bg: oklch(0.96 0.035 18); + --tone-danger-fg: oklch(0.48 0.16 24); + --tone-danger-border: oklch(0.84 0.09 20); + --tone-info-bg: oklch(0.96 0.035 225); + --tone-info-fg: oklch(0.39 0.1 230); + --tone-info-border: oklch(0.84 0.08 225); + --tone-info-strong: oklch(0.48 0.13 230); + --tone-info-strong-hover: oklch(0.42 0.13 230); + --border: oklch(0.92 0.004 286.32); + --input: oklch(0.92 0.004 286.32); + --ring: oklch(0.58 0.12 150); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.141 0.005 285.823); + --sidebar-primary: oklch(0.49 0.14 150); + --sidebar-primary-foreground: oklch(0.99 0.006 145); + --sidebar-accent: oklch(0.94 0.045 150); + --sidebar-accent-foreground: oklch(0.23 0.07 150); + --sidebar-border: oklch(0.92 0.004 286.32); + --sidebar-ring: oklch(0.705 0.015 286.067); +} + +.dark { + --background: oklch(0.141 0.005 285.823); + --foreground: oklch(0.985 0 0); + --card: oklch(0.21 0.006 285.885); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.21 0.006 285.885); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.92 0.004 286.32); + --primary-foreground: oklch(0.21 0.006 285.885); + --secondary: oklch(0.274 0.006 286.033); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.274 0.006 286.033); + --muted-foreground: oklch(0.705 0.015 286.067); + --accent: oklch(0.274 0.006 286.033); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --tone-success-bg: oklch(0.28 0.055 150 / 58%); + --tone-success-fg: oklch(0.82 0.12 150); + --tone-success-border: oklch(0.43 0.09 150 / 75%); + --tone-warning-bg: oklch(0.3 0.06 70 / 58%); + --tone-warning-fg: oklch(0.84 0.13 82); + --tone-warning-border: oklch(0.48 0.1 74 / 75%); + --tone-danger-bg: oklch(0.31 0.075 24 / 58%); + --tone-danger-fg: oklch(0.82 0.12 20); + --tone-danger-border: oklch(0.48 0.11 22 / 75%); + --tone-info-bg: oklch(0.31 0.06 230 / 58%); + --tone-info-fg: oklch(0.82 0.11 225); + --tone-info-border: oklch(0.48 0.1 230 / 75%); + --tone-info-strong: oklch(0.62 0.14 230); + --tone-info-strong-hover: oklch(0.68 0.14 230); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.552 0.016 285.938); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.21 0.006 285.885); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.274 0.006 286.033); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.552 0.016 285.938); +} -/* ============================================ - Base Layer - 基础样式 - ============================================ */ @layer base { - :root { - /* === MD3 Typography === */ - font-family: - 'Roboto', - 'Inter', - system-ui, - -apple-system, - sans-serif; - line-height: 1.5; - font-weight: 400; - color-scheme: light; - - /* === MD3 Color System - Light Mode === */ - /* Primary */ - --md-sys-color-primary: #4caf50; - --md-sys-color-on-primary: #ffffff; - --md-sys-color-primary-container: #c8e6c9; - --md-sys-color-on-primary-container: #1b5e20; - - /* Secondary */ - --md-sys-color-secondary: #2196f3; - --md-sys-color-on-secondary: #ffffff; - --md-sys-color-secondary-container: #bbdefb; - --md-sys-color-on-secondary-container: #0d47a1; - - /* Tertiary */ - --md-sys-color-tertiary: #ff9800; - --md-sys-color-on-tertiary: #ffffff; - --md-sys-color-tertiary-container: #ffe0b2; - --md-sys-color-on-tertiary-container: #e65100; - - /* Error */ - --md-sys-color-error: #f44336; - --md-sys-color-on-error: #ffffff; - --md-sys-color-error-container: #ffebee; - --md-sys-color-on-error-container: #b71c1c; - - /* Surface & Background */ - --md-sys-color-surface: #ffffff; - --md-sys-color-on-surface: #1c1b1f; - --md-sys-color-surface-variant: #f5f5f5; - --md-sys-color-on-surface-variant: #49454f; - --md-sys-color-background: #fefbff; - --md-sys-color-on-background: #1c1b1f; - - /* Outline */ - --md-sys-color-outline: #d1cdd6; - --md-sys-color-outline-variant: #e3e1e6; - - /* Surface Container Levels (Elevation Tint) */ - --md-sys-color-surface-container-lowest: #ffffff; - --md-sys-color-surface-container-low: #f7f9fb; - --md-sys-color-surface-container: #f3f4f6; - --md-sys-color-surface-container-high: #e8eaed; - --md-sys-color-surface-container-highest: #e0e3e6; - } - - /* === Dark Mode === */ - .dark { - color-scheme: dark; - - /* Primary */ - --md-sys-color-primary: #81c784; - --md-sys-color-on-primary: #1b5e20; - --md-sys-color-primary-container: #2e7d32; - --md-sys-color-on-primary-container: #c8e6c9; - - /* Secondary */ - --md-sys-color-secondary: #64b5f6; - --md-sys-color-on-secondary: #0d47a1; - --md-sys-color-secondary-container: #1565c0; - --md-sys-color-on-secondary-container: #bbdefb; - - /* Tertiary */ - --md-sys-color-tertiary: #ffb74d; - --md-sys-color-on-tertiary: #e65100; - --md-sys-color-tertiary-container: #ef6c00; - --md-sys-color-on-tertiary-container: #ffe0b2; - - /* Error */ - --md-sys-color-error: #ef5350; - --md-sys-color-on-error: #b71c1c; - --md-sys-color-error-container: #c62828; - --md-sys-color-on-error-container: #ffebee; - - /* Surface & Background */ - --md-sys-color-surface: #1c1b1f; - --md-sys-color-on-surface: #e6e1e5; - --md-sys-color-surface-variant: #26252a; - --md-sys-color-on-surface-variant: #cac4d0; - --md-sys-color-background: #1c1b1f; - --md-sys-color-on-background: #e6e1e5; - - /* Outline */ - --md-sys-color-outline: #605d66; - --md-sys-color-outline-variant: #49454f; - - /* Surface Container Levels */ - --md-sys-color-surface-container-lowest: #0f0e11; - --md-sys-color-surface-container-low: #1c1b1f; - --md-sys-color-surface-container: #201f24; - --md-sys-color-surface-container-high: #2b292f; - --md-sys-color-surface-container-highest: #36343a; - } - - /* === Reset & Base === */ * { - margin: 0; - padding: 0; - box-sizing: border-box; + @apply border-border outline-ring/50; + } + html { + @apply scroll-smooth; } - body { - margin: 0; - min-width: 320px; - min-height: 100vh; - background-color: var(--md-sys-color-background); - color: var(--md-sys-color-on-background); + @apply bg-background text-foreground antialiased; + font-family: var(--font-sans-app); font-synthesis: none; text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - transition: - background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), - color 0.3s cubic-bezier(0.4, 0, 0.2, 1); } - - #app { - width: 100%; - min-height: 100vh; - } - - /* === Typography Styles === */ - h1, - h2, - h3, - h4, - h5, - h6 { - font-weight: 400; - line-height: 1.2; - color: var(--md-sys-color-on-surface); - } - - /* Display Large */ - .md3-display-large { - font-size: 57px; - line-height: 64px; - font-weight: 400; - letter-spacing: -0.25px; - } - - /* Display Medium */ - .md3-display-medium { - font-size: 45px; - line-height: 52px; - font-weight: 400; - } - - /* Display Small */ - .md3-display-small { - font-size: 36px; - line-height: 44px; - font-weight: 400; - } - - /* Headline Large */ - .md3-headline-large { - font-size: 32px; - line-height: 40px; - font-weight: 400; - } - - /* Headline Medium */ - .md3-headline-medium { - font-size: 28px; - line-height: 36px; - font-weight: 400; - } - - /* Headline Small */ - .md3-headline-small { - font-size: 24px; - line-height: 32px; - font-weight: 400; - } - - /* Title Large */ - .md3-title-large { - font-size: 22px; - line-height: 28px; - font-weight: 400; - } - - /* Title Medium */ - .md3-title-medium { - font-size: 16px; - line-height: 24px; - font-weight: 500; - letter-spacing: 0.15px; - } - - /* Title Small */ - .md3-title-small { - font-size: 14px; - line-height: 20px; - font-weight: 500; - letter-spacing: 0.1px; - } - - /* Body Large */ - .md3-body-large { - font-size: 16px; - line-height: 24px; - font-weight: 400; - letter-spacing: 0.5px; - } - - /* Body Medium */ - .md3-body-medium { - font-size: 14px; - line-height: 20px; - font-weight: 400; - letter-spacing: 0.25px; - } - - /* Body Small */ - .md3-body-small { - font-size: 12px; - line-height: 16px; - font-weight: 400; - letter-spacing: 0.4px; - } - - /* Label Large */ - .md3-label-large { - font-size: 14px; - line-height: 20px; - font-weight: 500; - letter-spacing: 0.1px; - } - - /* Label Medium */ - .md3-label-medium { - font-size: 12px; - line-height: 16px; - font-weight: 500; - letter-spacing: 0.5px; - } - - /* Label Small */ - .md3-label-small { - font-size: 11px; - line-height: 16px; - font-weight: 500; - letter-spacing: 0.5px; + button, + input, + select, + textarea { + font: inherit; } } -/* ============================================ - Components Layer - MD3 组件样式 - ============================================ */ -@layer components { - /* === MD3 Card === */ - .md3-card { - background-color: var(--md-sys-color-surface-container-low); - color: var(--md-sys-color-on-surface); - border-radius: 12px; - box-shadow: - 0px 1px 2px 0px rgba(0, 0, 0, 0.1), - 0px 1px 3px 1px rgba(0, 0, 0, 0.05); - overflow: hidden; - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - } - - .md3-card:hover { - box-shadow: - 0px 1px 3px 0px rgba(0, 0, 0, 0.15), - 0px 4px 8px 3px rgba(0, 0, 0, 0.08); - transform: translateY(-1px); - } - - /* === MD3 Button === */ - .md3-button { - display: inline-flex; - align-items: center; - justify-content: center; - gap: 8px; - padding: 10px 24px; - border-radius: 20px; - font-size: 14px; - font-weight: 500; - line-height: 20px; - letter-spacing: 0.1px; - cursor: pointer; - border: none; - outline: none; - transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); - position: relative; - overflow: hidden; - } - - /* Filled Button (Primary) */ - .md3-button-filled { - @apply md3-button; - background-color: var(--md-sys-color-primary); - color: var(--md-sys-color-on-primary); - box-shadow: - 0px 1px 2px 0px rgba(0, 0, 0, 0.1), - 0px 1px 3px 1px rgba(0, 0, 0, 0.05); - } - - .md3-button-filled:hover { - box-shadow: - 0px 1px 3px 0px rgba(0, 0, 0, 0.15), - 0px 4px 8px 3px rgba(0, 0, 0, 0.08); - transform: translateY(-1px); - } - - .md3-button-filled:active { - box-shadow: - 0px 1px 2px 0px rgba(0, 0, 0, 0.1), - 0px 1px 3px 1px rgba(0, 0, 0, 0.05); - transform: translateY(0); - } - - /* Outlined Button */ - .md3-button-outlined { - @apply md3-button; - background-color: transparent; - color: var(--md-sys-color-primary); - border: 1px solid var(--md-sys-color-outline); - box-shadow: none; - } - - .md3-button-outlined:hover { - background-color: rgba(76, 175, 80, 0.08); - } - - .md3-button-outlined:active { - background-color: rgba(76, 175, 80, 0.12); - } - - /* Text Button */ - .md3-button-text { - @apply md3-button; - background-color: transparent; - color: var(--md-sys-color-primary); - box-shadow: none; - padding: 10px 12px; - } - - .md3-button-text:hover { - background-color: rgba(76, 175, 80, 0.08); - } - - .md3-button-text:active { - background-color: rgba(76, 175, 80, 0.12); - } - - /* === MD3 State Layers === */ - .md3-state-layer { - position: relative; - overflow: hidden; - } - - .md3-state-layer::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: currentColor; - opacity: 0; - transition: opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1); - pointer-events: none; - } - - .md3-state-layer:hover::before { - opacity: 0.08; - } - - .md3-state-layer:focus::before { - opacity: 0.12; - } - - .md3-state-layer:active::before { - opacity: 0.12; - } - - /* === MD3 Status Badges === */ - .md3-badge { - display: inline-flex; - align-items: center; - padding: 4px 12px; - border-radius: 16px; - font-size: 12px; - font-weight: 500; - line-height: 16px; - letter-spacing: 0.5px; - } - - .md3-badge-success { - @apply md3-badge; - background-color: #c8e6c9; - color: #1b5e20; - } - - .dark .md3-badge-success { - background-color: #2e7d32; - color: #c8e6c9; - } - - .md3-badge-warning { - @apply md3-badge; - background-color: #ffe0b2; - color: #e65100; - } - - .dark .md3-badge-warning { - background-color: #ef6c00; - color: #ffe0b2; - } - - .md3-badge-error { - @apply md3-badge; - background-color: #ffebee; - color: #b71c1c; - } - - .dark .md3-badge-error { - background-color: #c62828; - color: #ffebee; - } - - .md3-badge-info { - @apply md3-badge; - background-color: #bbdefb; - color: #0d47a1; - } - - .dark .md3-badge-info { - background-color: #1565c0; - color: #bbdefb; - } - - /* === MD3 Divider === */ - .md3-divider { - height: 1px; - background-color: var(--md-sys-color-outline-variant); - border: none; - margin: 20px 0; - } - - .ant-divider { - margin: 20px 0; - } - - /* === MD3 Surface === */ - .md3-surface { - background-color: var(--md-sys-color-surface); - color: var(--md-sys-color-on-surface); - } - - .md3-surface-variant { - background-color: var(--md-sys-color-surface-variant); - color: var(--md-sys-color-on-surface-variant); - } - - .md3-surface-container-lowest { - background-color: var(--md-sys-color-surface-container-lowest); - } - - .md3-surface-container-low { - background-color: var(--md-sys-color-surface-container-low); - } - - .md3-surface-container { - background-color: var(--md-sys-color-surface-container); - } - - .md3-surface-container-high { - background-color: var(--md-sys-color-surface-container-high); - } - - .md3-surface-container-highest { - background-color: var(--md-sys-color-surface-container-highest); - } +.dark .bg-white { + background-color: rgb(24 24 27); } -/* ============================================ - Ant Design Vue 组件覆盖样式 - ============================================ */ -@layer components { - /* === Card === */ - .ant-card { - border-radius: 12px; - box-shadow: - 0px 1px 2px 0px rgba(0, 0, 0, 0.1), - 0px 1px 3px 1px rgba(0, 0, 0, 0.05); - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - } - - .ant-card:hover { - box-shadow: - 0px 1px 3px 0px rgba(0, 0, 0, 0.15), - 0px 4px 8px 3px rgba(0, 0, 0, 0.08); - transform: translateY(-1px); - } - - .ant-card-head { - padding: 12px 16px; - } - - .ant-card-body { - padding: 16px; - } - - /* === Navbar === */ - .navbar-wrapper { - box-shadow: - 0px 1px 2px 0px rgba(0, 0, 0, 0.12), - 0px 2px 6px 2px rgba(0, 0, 0, 0.08) !important; - transition: box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1); - border-bottom: 1px solid rgba(0, 0, 0, 0.06); - } - - .navbar-wrapper .text-on-surface { - color: #1c1b1f; - } - - /* 导航按钮悬浮效果 */ - /* 普通导航按钮(绿色) */ - .navbar-wrapper .nav-button:not(.bg-primary-100):hover { - background-color: rgba(76, 175, 80, 0.08) !important; - } - - /* 管理后台按钮(蓝色) */ - .navbar-wrapper .admin-nav-button:not(.bg-secondary-100):hover { - background-color: rgba(33, 150, 243, 0.08) !important; - } - - /* 其他 navbar 组件的通用悬浮效果(绿色) */ - .navbar-wrapper .navbar-item:hover { - background-color: rgba(76, 175, 80, 0.08) !important; - } - - /* === Button === */ - .ant-btn { - border-radius: 20px; - font-weight: 500; - letter-spacing: 0.1px; - transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); - padding: 10px 24px; - height: auto; - min-height: 40px; - } - - .ant-btn-lg { - padding: 12px 28px; - min-height: 48px; - font-size: 16px; - } - - .ant-btn-sm { - padding: 6px 16px; - min-height: 32px; - } - - .ant-btn-primary { - box-shadow: - 0px 1px 2px 0px rgba(0, 0, 0, 0.1), - 0px 1px 3px 1px rgba(0, 0, 0, 0.05); - } - - .ant-btn-primary:hover { - box-shadow: - 0px 1px 3px 0px rgba(0, 0, 0, 0.15), - 0px 4px 8px 3px rgba(0, 0, 0, 0.08); - transform: translateY(-1px); - } - - .ant-btn-primary:active { - transform: translateY(0); - } - - .ant-btn:hover:not(:disabled) { - transform: translateY(-1px); - } - - .ant-btn:active:not(:disabled) { - transform: translateY(0); - } - - /* === Input & Select === */ - .ant-input, - .ant-input-password, - .ant-select-selector, - .ant-picker { - border-radius: 12px !important; - transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); - padding: 10px 16px !important; - min-height: 40px; - } - - .ant-select-selector { - padding: 6px 16px !important; - } - - .ant-input:focus, - .ant-input-password:focus, - .ant-select-focused .ant-select-selector, - .ant-picker-focused { - border-color: var(--md-sys-color-primary); - box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.12); - } - - /* === Table === */ - .ant-table { - border-radius: 12px; - } - - .ant-table-thead > tr > th { - background-color: var(--md-sys-color-surface-container); - color: var(--md-sys-color-on-surface); - font-weight: 500; - border-bottom: 1px solid var(--md-sys-color-outline-variant); - } - - .ant-table-tbody > tr:hover > td { - background-color: rgba(76, 175, 80, 0.04); - } - - /* === Modal === */ - .ant-modal-content { - border-radius: 28px; - } - - .ant-modal-header { - border-radius: 28px 28px 0 0; - background-color: var(--md-sys-color-surface); - border-bottom: none; - } - - /* === Tag === */ - .ant-tag { - border-radius: 16px; - font-weight: 500; - letter-spacing: 0.5px; - border: none; - padding: 4px 14px; - font-size: 13px; - line-height: 20px; - } - - /* === Tabs === */ - .ant-tabs-tab { - border-radius: 12px 12px 0 0; - transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); - } - - .ant-tabs-tab:hover { - background-color: rgba(76, 175, 80, 0.08); - } - - .ant-tabs-tab-active { - background-color: rgba(76, 175, 80, 0.12); - } - - /* === Menu === */ - .ant-menu-item { - border-radius: 12px; - margin: 4px 8px; - transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); - } - - .ant-menu-item:hover { - background-color: rgba(76, 175, 80, 0.08); - } - - .ant-menu-item-selected { - background-color: rgba(76, 175, 80, 0.12); - } - - /* === Drawer === */ - .ant-drawer-content { - border-radius: 16px 0 0 16px; - } - - /* === Alert === */ - .ant-alert { - border-radius: 12px; - padding: 16px 20px; - } - - .ant-alert-message { - margin-bottom: 4px; - font-weight: 500; - } - - .ant-alert-description { - line-height: 1.6; - } - - /* === Dropdown === */ - .ant-dropdown-menu { - border-radius: 12px; - box-shadow: - 0px 2px 3px 0px rgba(0, 0, 0, 0.15), - 0px 6px 10px 4px rgba(0, 0, 0, 0.1); - } - - .ant-dropdown-menu-item { - border-radius: 8px; - margin: 4px 8px; - } - - .ant-dropdown-menu-item:hover { - background-color: rgba(76, 175, 80, 0.08); - } - - /* === Descriptions === */ - .ant-descriptions-bordered .ant-descriptions-view { - border-color: var(--md-sys-color-outline-variant) !important; - border-radius: 8px !important; - overflow: hidden !important; - } - - /* table 元素也需要圆角 */ - .ant-descriptions.ant-descriptions-bordered .ant-descriptions-view table { - border-radius: 8px !important; - } - - /* 使用最高优先级覆盖 Ant Design CSS-in-JS */ - .ant-descriptions.ant-descriptions-bordered .ant-descriptions-view table tbody tr th, - .ant-descriptions.ant-descriptions-bordered .ant-descriptions-view table tbody tr td { - border-color: var(--md-sys-color-outline-variant) !important; - } - - /* Label 列 (th) 背景色 */ - .ant-descriptions.ant-descriptions-bordered .ant-descriptions-view table tbody tr th { - background-color: var(--md-sys-color-surface-container) !important; - padding: 12px 16px !important; - } - - /* Content 列 (td) 背景色 - 只对包含 content 的 td 应用 */ - .ant-descriptions.ant-descriptions-bordered .ant-descriptions-view table tbody tr td { - padding: 12px 16px !important; - } - - /* 只对包含 ant-descriptions-item-content 的 td 应用白色背景 */ - .ant-descriptions.ant-descriptions-bordered - .ant-descriptions-view - table - tbody - tr - td:has(.ant-descriptions-item-content) { - background-color: var(--md-sys-color-surface) !important; - } - - /* 对包含 ant-descriptions-item-label 的 td 应用灰色背景(跨列的 label) */ - .ant-descriptions.ant-descriptions-bordered - .ant-descriptions-view - table - tbody - tr - td:has(.ant-descriptions-item-label) { - background-color: var(--md-sys-color-surface-container) !important; - } - - /* Label 和 Content 内部元素样式 */ - .ant-descriptions.ant-descriptions-bordered .ant-descriptions-item-label { - font-weight: 500 !important; - color: var(--md-sys-color-on-surface-variant) !important; - } - - .ant-descriptions.ant-descriptions-bordered .ant-descriptions-item-content { - font-weight: 400 !important; - color: var(--md-sys-color-on-surface) !important; - } - - /* 圆角 - 第一行第一个 th(左上角)*/ - .ant-descriptions.ant-descriptions-bordered - .ant-descriptions-view - table - tbody - tr:first-child - th:first-child { - border-top-left-radius: 7px !important; - } - - /* 圆角 - 第一行最后一个 td(右上角)*/ - .ant-descriptions.ant-descriptions-bordered - .ant-descriptions-view - table - tbody - tr:first-child - td:last-child { - border-top-right-radius: 7px !important; - } - - /* 圆角 - 最后一行第一个 th(左下角)*/ - .ant-descriptions.ant-descriptions-bordered - .ant-descriptions-view - table - tbody - tr:last-child - th:first-child { - border-bottom-left-radius: 7px !important; - } - - /* 圆角 - 最后一行最后一个 td(右下角)*/ - .ant-descriptions.ant-descriptions-bordered - .ant-descriptions-view - table - tbody - tr:last-child - td:last-child { - border-bottom-right-radius: 7px !important; - } +.dark .bg-zinc-50 { + background-color: rgb(9 9 11 / 0.62); } -/* ============================================ - 暗色模式特定样式 - ============================================ */ -/* Navbar 暗色模式 */ -.dark .navbar-wrapper { - box-shadow: - 0px 2px 4px 0px rgba(0, 0, 0, 0.4), - 0px 4px 8px 4px rgba(0, 0, 0, 0.3) !important; - border-bottom: 1px solid rgba(255, 255, 255, 0.08); +.dark .bg-emerald-50 { + background-color: rgb(2 44 34 / 0.42); } -.dark .navbar-wrapper .text-on-surface { - color: #e6e1e5; +.dark .border-zinc-200 { + border-color: rgb(39 39 42); } -.dark .navbar-wrapper .nav-button:not(.bg-primary-100):hover { - background-color: rgba(129, 199, 132, 0.12) !important; +.dark .text-zinc-800, +.dark .text-zinc-600 { + color: rgb(212 212 216); } -.dark .navbar-wrapper .admin-nav-button:not(.bg-secondary-100):hover { - background-color: rgba(100, 181, 246, 0.12) !important; +.dark .text-zinc-500, +.dark .text-zinc-400 { + color: rgb(161 161 170); } -.dark .navbar-wrapper .navbar-item:hover { - background-color: rgba(129, 199, 132, 0.12) !important; -} - -/* Ant Design 组件暗色模式 */ -.dark .ant-card { - background-color: var(--md-sys-color-surface-container-low); - border-color: var(--md-sys-color-outline-variant); -} - -.dark .ant-input, -.dark .ant-input-password, -.dark .ant-select-selector, -.dark .ant-picker { - background-color: var(--md-sys-color-surface-container); - border-color: var(--md-sys-color-outline); - color: var(--md-sys-color-on-surface); -} - -.dark .ant-input::placeholder, -.dark .ant-input-password::placeholder { - color: var(--md-sys-color-on-surface-variant); -} - -.dark .ant-table { - background-color: var(--md-sys-color-surface); -} - -.dark .ant-table-thead > tr > th { - background-color: var(--md-sys-color-surface-container); - color: var(--md-sys-color-on-surface); - border-color: var(--md-sys-color-outline-variant); -} - -.dark .ant-table-tbody > tr > td { - border-color: var(--md-sys-color-outline-variant); - color: var(--md-sys-color-on-surface); -} - -/* Descriptions 暗色模式 */ -.dark .ant-descriptions.ant-descriptions-bordered th { - background-color: var(--md-sys-color-surface-container) !important; -} - -.dark .ant-descriptions.ant-descriptions-bordered td { - background-color: var(--md-sys-color-surface) !important; -} - -.dark .ant-descriptions.ant-descriptions-bordered .ant-descriptions-item-label { - color: var(--md-sys-color-on-surface-variant) !important; -} - -.dark .ant-descriptions.ant-descriptions-bordered .ant-descriptions-item-content { - color: var(--md-sys-color-on-surface) !important; -} - -.dark .ant-modal-content { - background-color: var(--md-sys-color-surface); -} - -.dark .ant-modal-header { - background-color: var(--md-sys-color-surface); - color: var(--md-sys-color-on-surface); -} - -.dark .ant-modal-body, -.dark .ant-modal-footer { - background-color: var(--md-sys-color-surface); - color: var(--md-sys-color-on-surface); -} - -.dark .ant-drawer-content { - background-color: var(--md-sys-color-surface); -} - -.dark .ant-dropdown-menu { - background-color: var(--md-sys-color-surface-container); -} - -/* ============================================ - 响应式设计 - ============================================ */ - -/* Extra Large Screens (≥1200px) */ -@media (min-width: 1200px) { - .ant-card { - padding: 24px; - } -} - -/* Large Screens (992px - 1199px) */ -@media (min-width: 992px) and (max-width: 1199px) { - .ant-card { - padding: 20px; - } -} - -/* Medium Screens (768px - 991px) */ -@media (min-width: 768px) and (max-width: 991px) { - .ant-card { - padding: 16px; - } - - .ant-table { - font-size: 13px; - } - - .ant-btn { - height: 36px; - padding: 8px 16px; - } -} - -/* Small Screens (576px - 767px) */ -@media (min-width: 576px) and (max-width: 767px) { - .ant-card-head { - padding: 12px 16px; - } - - .ant-card-body { - padding: 16px; - } - - .ant-table { - font-size: 12px; - } - - .ant-btn { - height: 32px; - padding: 6px 12px; - font-size: 13px; - } - - .md3-button { - padding: 8px 20px; - font-size: 13px; - } -} - -/* Extra Small Screens (<576px) */ -@media (max-width: 575px) { - body { - font-size: 14px; - } - - .ant-card-head { - padding: 10px 12px; - font-size: 16px; - } - - .ant-card-body { - padding: 12px; - } - - .ant-table { - font-size: 12px; - } - - .ant-btn { - height: 32px; - padding: 6px 12px; - font-size: 12px; - } - - .md3-button { - padding: 8px 16px; - font-size: 12px; - } - - .ant-modal-content { - margin: 16px; - border-radius: 24px; - } - - .md3-card, - .md3-card-elevated { - margin: 8px; - } -} - -/* ============================================ - 辅助类 - ============================================ */ -@layer utilities { - /* MD3 Elevation Classes */ - .elevation-0 { - box-shadow: none; - } - - .elevation-1 { - box-shadow: - 0px 1px 2px 0px rgba(0, 0, 0, 0.1), - 0px 1px 3px 1px rgba(0, 0, 0, 0.05); - } - - .elevation-2 { - box-shadow: - 0px 1px 2px 0px rgba(0, 0, 0, 0.12), - 0px 2px 6px 2px rgba(0, 0, 0, 0.08) !important; - } - - .dark .elevation-2 { - box-shadow: - 0px 1px 2px 0px rgba(0, 0, 0, 0.3), - 0px 2px 6px 2px rgba(0, 0, 0, 0.2) !important; - } - - .elevation-3 { - box-shadow: - 0px 1px 3px 0px rgba(0, 0, 0, 0.15), - 0px 4px 8px 3px rgba(0, 0, 0, 0.08); - } - - .elevation-4 { - box-shadow: - 0px 2px 3px 0px rgba(0, 0, 0, 0.15), - 0px 6px 10px 4px rgba(0, 0, 0, 0.1); - } - - .elevation-5 { - box-shadow: - 0px 4px 4px 0px rgba(0, 0, 0, 0.18), - 0px 8px 12px 6px rgba(0, 0, 0, 0.12); - } - - /* Text Colors */ - .text-on-surface { - color: var(--md-sys-color-on-surface); - } - - .text-on-surface-variant { - color: var(--md-sys-color-on-surface-variant); - } - - .text-primary { - color: var(--md-sys-color-primary); - } - - .text-secondary { - color: var(--md-sys-color-secondary); - } - - .text-error { - color: var(--md-sys-color-error); - } - - /* Background Colors */ - .bg-surface { - background-color: var(--md-sys-color-surface); - } - - .bg-surface-variant { - background-color: var(--md-sys-color-surface-variant); - } - - .bg-primary { - background-color: var(--md-sys-color-primary); - color: var(--md-sys-color-on-primary); - } - - .bg-secondary { - background-color: var(--md-sys-color-secondary); - color: var(--md-sys-color-on-secondary); - } - - .bg-error { - background-color: var(--md-sys-color-error); - color: var(--md-sys-color-on-error); - } - - /* MD3 Motion */ - .transition-standard { - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - } - - .transition-emphasized { - transition: all 0.5s cubic-bezier(0.2, 0, 0, 1); - } - - .transition-decelerated { - transition: all 0.4s cubic-bezier(0, 0, 0, 1); - } - - .transition-accelerated { - transition: all 0.2s cubic-bezier(0.3, 0, 1, 1); - } - - /* Ant Design Tooltip 文本居中 */ - - /* 针对 Ant Design Vue 4.x 的 tooltip */ - .ant-tooltip .ant-tooltip-inner { - display: flex !important; - align-items: center !important; - justify-content: center !important; - } - - /* 更高优先级的选择器 */ - div[class*='ant-tooltip'] .ant-tooltip-inner, - div[class^='ant-tooltip'] div[class*='tooltip-inner'] { - display: flex !important; - align-items: center !important; - justify-content: center !important; - } -} - -/* ============================================ - 滚动条样式(MD3 风格) - ============================================ */ -::-webkit-scrollbar { - width: 12px; - height: 12px; -} - -::-webkit-scrollbar-track { - background-color: var(--md-sys-color-surface-variant); - border-radius: 6px; -} - -::-webkit-scrollbar-thumb { - background-color: var(--md-sys-color-outline); - border-radius: 6px; - border: 2px solid var(--md-sys-color-surface-variant); -} - -::-webkit-scrollbar-thumb:hover { - background-color: var(--md-sys-color-outline-variant); -} - -/* Firefox */ -* { - scrollbar-width: thin; - scrollbar-color: var(--md-sys-color-outline) var(--md-sys-color-surface-variant); +.dark .hover\:text-zinc-950:hover { + color: rgb(250 250 250); } diff --git a/apps/new-frontend/src/utils/format.ts b/apps/frontend/src/utils/format.ts similarity index 100% rename from apps/new-frontend/src/utils/format.ts rename to apps/frontend/src/utils/format.ts diff --git a/apps/frontend/src/utils/helpers.js b/apps/frontend/src/utils/helpers.js deleted file mode 100644 index 467e142..0000000 --- a/apps/frontend/src/utils/helpers.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * 格式化日期时间 - * @param {string|Date} date - 日期 - * @param {boolean} includeTime - 是否包含时间 - * @returns {string} - */ -export function formatDateTime(date, includeTime = true) { - if (!date) return '-'; - - const d = new Date(date); - if (isNaN(d.getTime())) return '-'; - - const year = d.getFullYear(); - const month = String(d.getMonth() + 1).padStart(2, '0'); - const day = String(d.getDate()).padStart(2, '0'); - - if (!includeTime) { - return `${year}-${month}-${day}`; - } - - const hours = String(d.getHours()).padStart(2, '0'); - const minutes = String(d.getMinutes()).padStart(2, '0'); - const seconds = String(d.getSeconds()).padStart(2, '0'); - - return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; -} - -/** - * 格式化相对时间(多久之前) - * @param {string|Date} date - 日期 - * @returns {string} - */ -export function formatRelativeTime(date) { - if (!date) return '-'; - - const d = new Date(date); - if (isNaN(d.getTime())) return '-'; - - const now = new Date(); - const diff = now - d; // 毫秒差 - - const seconds = Math.floor(diff / 1000); - const minutes = Math.floor(seconds / 60); - const hours = Math.floor(minutes / 60); - const days = Math.floor(hours / 24); - - if (seconds < 60) return '刚刚'; - if (minutes < 60) return `${minutes} 分钟前`; - if (hours < 24) return `${hours} 小时前`; - if (days < 7) return `${days} 天前`; - - return formatDateTime(date, false); -} - -/** - * 格式化文件大小 - * @param {number} bytes - 字节数 - * @returns {string} - */ -export function formatFileSize(bytes) { - if (!bytes || bytes === 0) return '0 B'; - - const k = 1024; - const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - - return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`; -} - -/** - * 防抖函数 - * @param {Function} fn - 要防抖的函数 - * @param {number} delay - 延迟时间(毫秒) - * @returns {Function} - */ -export function debounce(fn, delay = 300) { - let timer = null; - return function (...args) { - if (timer) clearTimeout(timer); - timer = setTimeout(() => { - fn.apply(this, args); - }, delay); - }; -} - -/** - * 节流函数 - * @param {Function} fn - 要节流的函数 - * @param {number} delay - 延迟时间(毫秒) - * @returns {Function} - */ -export function throttle(fn, delay = 300) { - let timer = null; - let lastTime = 0; - - return function (...args) { - const now = Date.now(); - - if (now - lastTime < delay) { - if (timer) clearTimeout(timer); - timer = setTimeout(() => { - lastTime = now; - fn.apply(this, args); - }, delay); - } else { - lastTime = now; - fn.apply(this, args); - } - }; -} - -/** - * 复制文本到剪贴板 - * @param {string} text - 要复制的文本 - * @returns {Promise} - */ -export async function copyToClipboard(text) { - try { - if (navigator.clipboard && window.isSecureContext) { - await navigator.clipboard.writeText(text); - return true; - } else { - // 降级方案 - const textArea = document.createElement('textarea'); - textArea.value = text; - textArea.style.position = 'fixed'; - textArea.style.left = '-999999px'; - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - try { - document.execCommand('copy'); - textArea.remove(); - return true; - } catch (error) { - console.error('复制失败', error); - textArea.remove(); - return false; - } - } - } catch (error) { - console.error('复制失败', error); - return false; - } -} diff --git a/apps/frontend/src/views/DashboardView.vue b/apps/frontend/src/views/DashboardView.vue index 0baf8e3..13c85b0 100644 --- a/apps/frontend/src/views/DashboardView.vue +++ b/apps/frontend/src/views/DashboardView.vue @@ -1,547 +1,432 @@ - diff --git a/apps/frontend/src/views/LoginView.vue b/apps/frontend/src/views/LoginView.vue index a2477d8..c50d68e 100644 --- a/apps/frontend/src/views/LoginView.vue +++ b/apps/frontend/src/views/LoginView.vue @@ -1,524 +1,256 @@ - diff --git a/apps/frontend/src/views/NotFoundView.vue b/apps/frontend/src/views/NotFoundView.vue index 44852a0..0841337 100644 --- a/apps/frontend/src/views/NotFoundView.vue +++ b/apps/frontend/src/views/NotFoundView.vue @@ -1,30 +1,16 @@ - + - + diff --git a/apps/frontend/src/views/PendingApprovalView.vue b/apps/frontend/src/views/PendingApprovalView.vue index 1639c16..d4d1ac9 100644 --- a/apps/frontend/src/views/PendingApprovalView.vue +++ b/apps/frontend/src/views/PendingApprovalView.vue @@ -1,360 +1,65 @@ -