From 0fca7900c81450a01f515d99d193da9f73f2a5fd Mon Sep 17 00:00:00 2001 From: SunWuyuan Date: Mon, 6 Oct 2025 11:10:54 +0800 Subject: [PATCH] cskv --- DEPLOYMENT.md | 137 - classworks.js | 51 - docker-compose.yml | 1 - kv-admin/.claude/settings.local.json | 9 - kv-admin/.env.example | 8 - kv-admin/.gitignore | 24 - kv-admin/.npmrc | 1 - kv-admin/.vscode/extensions.json | 3 - kv-admin/README.md | 281 -- kv-admin/components.json | 20 - kv-admin/index.html | 13 - kv-admin/jsconfig.json | 9 - kv-admin/package.json | 43 - kv-admin/pnpm-lock.yaml | 3915 ----------------- kv-admin/public/vite.svg | 1 - kv-admin/src/App.vue | 10 - kv-admin/src/assets/vue.svg | 1 - kv-admin/src/components/AppCard.vue | 296 -- .../src/components/DeviceRegisterDialog.vue | 400 -- .../src/components/EditDeviceNameDialog.vue | 136 - kv-admin/src/components/HelloWorld.vue | 41 - kv-admin/src/components/LoginDialog.vue | 220 - kv-admin/src/components/PasswordInput.vue | 262 -- .../components/ResetDevicePasswordDialog.vue | 274 -- .../ui/alert-dialog/AlertDialog.vue | 17 - .../ui/alert-dialog/AlertDialogAction.vue | 23 - .../ui/alert-dialog/AlertDialogCancel.vue | 25 - .../ui/alert-dialog/AlertDialogContent.vue | 51 - .../alert-dialog/AlertDialogDescription.vue | 23 - .../ui/alert-dialog/AlertDialogFooter.vue | 18 - .../ui/alert-dialog/AlertDialogHeader.vue | 16 - .../ui/alert-dialog/AlertDialogTitle.vue | 23 - .../ui/alert-dialog/AlertDialogTrigger.vue | 14 - .../src/components/ui/alert-dialog/index.js | 9 - kv-admin/src/components/ui/badge/Badge.vue | 25 - kv-admin/src/components/ui/badge/index.js | 24 - kv-admin/src/components/ui/button/Button.vue | 24 - kv-admin/src/components/ui/button/index.js | 34 - kv-admin/src/components/ui/card/Card.vue | 21 - .../src/components/ui/card/CardAction.vue | 21 - .../src/components/ui/card/CardContent.vue | 13 - .../components/ui/card/CardDescription.vue | 16 - .../src/components/ui/card/CardFooter.vue | 16 - .../src/components/ui/card/CardHeader.vue | 21 - kv-admin/src/components/ui/card/CardTitle.vue | 16 - kv-admin/src/components/ui/card/index.js | 7 - .../src/components/ui/checkbox/Checkbox.vue | 46 - kv-admin/src/components/ui/checkbox/index.js | 1 - kv-admin/src/components/ui/dialog/Dialog.vue | 18 - .../src/components/ui/dialog/DialogClose.vue | 14 - .../components/ui/dialog/DialogContent.vue | 57 - .../ui/dialog/DialogDescription.vue | 25 - .../src/components/ui/dialog/DialogFooter.vue | 18 - .../src/components/ui/dialog/DialogHeader.vue | 16 - .../components/ui/dialog/DialogOverlay.vue | 29 - .../ui/dialog/DialogScrollContent.vue | 71 - .../src/components/ui/dialog/DialogTitle.vue | 25 - .../components/ui/dialog/DialogTrigger.vue | 14 - kv-admin/src/components/ui/dialog/index.js | 10 - .../ui/dropdown-menu/DropdownItem.vue | 22 - .../ui/dropdown-menu/DropdownMenu.vue | 62 - kv-admin/src/components/ui/input/Input.vue | 32 - kv-admin/src/components/ui/input/index.js | 1 - kv-admin/src/components/ui/label/Label.vue | 29 - kv-admin/src/components/ui/label/index.js | 1 - kv-admin/src/components/ui/select/Select.vue | 26 - .../components/ui/select/SelectContent.vue | 81 - .../src/components/ui/select/SelectGroup.vue | 14 - .../src/components/ui/select/SelectItem.vue | 47 - .../components/ui/select/SelectItemText.vue | 14 - .../src/components/ui/select/SelectLabel.vue | 20 - .../ui/select/SelectScrollDownButton.vue | 30 - .../ui/select/SelectScrollUpButton.vue | 30 - .../components/ui/select/SelectSeparator.vue | 21 - .../components/ui/select/SelectTrigger.vue | 37 - .../src/components/ui/select/SelectValue.vue | 15 - kv-admin/src/components/ui/select/index.js | 11 - .../src/components/ui/separator/Separator.vue | 28 - kv-admin/src/components/ui/separator/index.js | 1 - kv-admin/src/components/ui/sonner/Sonner.vue | 39 - kv-admin/src/components/ui/sonner/index.js | 1 - kv-admin/src/components/ui/table/Table.vue | 18 - .../src/components/ui/table/TableBody.vue | 16 - .../src/components/ui/table/TableCaption.vue | 16 - .../src/components/ui/table/TableCell.vue | 21 - .../src/components/ui/table/TableEmpty.vue | 31 - .../src/components/ui/table/TableFooter.vue | 18 - .../src/components/ui/table/TableHead.vue | 21 - .../src/components/ui/table/TableHeader.vue | 13 - kv-admin/src/components/ui/table/TableRow.vue | 21 - kv-admin/src/components/ui/table/index.js | 9 - kv-admin/src/components/ui/table/utils.js | 7 - kv-admin/src/components/ui/tabs/Tabs.vue | 31 - .../src/components/ui/tabs/TabsContent.vue | 25 - kv-admin/src/components/ui/tabs/TabsList.vue | 29 - .../src/components/ui/tabs/TabsTrigger.vue | 32 - kv-admin/src/components/ui/tabs/index.js | 4 - kv-admin/src/composables/useOAuthCallback.js | 126 - kv-admin/src/lib/api.js | 533 --- kv-admin/src/lib/axios.js | 37 - kv-admin/src/lib/deviceStore.js | 191 - kv-admin/src/lib/tokenStore.js | 66 - kv-admin/src/lib/utils.js | 6 - kv-admin/src/main.js | 45 - kv-admin/src/pages/authorize.vue | 493 --- kv-admin/src/pages/device-management.vue | 276 -- kv-admin/src/pages/index.vue | 861 ---- kv-admin/src/pages/kv-manager.vue | 615 --- kv-admin/src/pages/password-manager.vue | 615 --- kv-admin/src/stores/account.js | 116 - kv-admin/src/style.css | 124 - kv-admin/vite.config.js | 26 - package.json | 1 - .../20250524123413_2025_05_24/migration.sql | 24 - .../20250524123414_2025_05_25/migration.sql | 117 - .../20250930_remove_access_type/migration.sql | 8 - .../20251002032512_update/migration.sql | 2 - .../20251002074755_update/migration.sql | 21 - .../20251005011323_update/migration.sql | 17 - .../20251006025039_init/migration.sql | 68 + scripts/batchMigrate.js | 192 - 121 files changed, 68 insertions(+), 12343 deletions(-) delete mode 100644 DEPLOYMENT.md delete mode 100644 kv-admin/.claude/settings.local.json delete mode 100644 kv-admin/.env.example delete mode 100644 kv-admin/.gitignore delete mode 100644 kv-admin/.npmrc delete mode 100644 kv-admin/.vscode/extensions.json delete mode 100644 kv-admin/README.md delete mode 100644 kv-admin/components.json delete mode 100644 kv-admin/index.html delete mode 100644 kv-admin/jsconfig.json delete mode 100644 kv-admin/package.json delete mode 100644 kv-admin/pnpm-lock.yaml delete mode 100644 kv-admin/public/vite.svg delete mode 100644 kv-admin/src/App.vue delete mode 100644 kv-admin/src/assets/vue.svg delete mode 100644 kv-admin/src/components/AppCard.vue delete mode 100644 kv-admin/src/components/DeviceRegisterDialog.vue delete mode 100644 kv-admin/src/components/EditDeviceNameDialog.vue delete mode 100644 kv-admin/src/components/HelloWorld.vue delete mode 100644 kv-admin/src/components/LoginDialog.vue delete mode 100644 kv-admin/src/components/PasswordInput.vue delete mode 100644 kv-admin/src/components/ResetDevicePasswordDialog.vue delete mode 100644 kv-admin/src/components/ui/alert-dialog/AlertDialog.vue delete mode 100644 kv-admin/src/components/ui/alert-dialog/AlertDialogAction.vue delete mode 100644 kv-admin/src/components/ui/alert-dialog/AlertDialogCancel.vue delete mode 100644 kv-admin/src/components/ui/alert-dialog/AlertDialogContent.vue delete mode 100644 kv-admin/src/components/ui/alert-dialog/AlertDialogDescription.vue delete mode 100644 kv-admin/src/components/ui/alert-dialog/AlertDialogFooter.vue delete mode 100644 kv-admin/src/components/ui/alert-dialog/AlertDialogHeader.vue delete mode 100644 kv-admin/src/components/ui/alert-dialog/AlertDialogTitle.vue delete mode 100644 kv-admin/src/components/ui/alert-dialog/AlertDialogTrigger.vue delete mode 100644 kv-admin/src/components/ui/alert-dialog/index.js delete mode 100644 kv-admin/src/components/ui/badge/Badge.vue delete mode 100644 kv-admin/src/components/ui/badge/index.js delete mode 100644 kv-admin/src/components/ui/button/Button.vue delete mode 100644 kv-admin/src/components/ui/button/index.js delete mode 100644 kv-admin/src/components/ui/card/Card.vue delete mode 100644 kv-admin/src/components/ui/card/CardAction.vue delete mode 100644 kv-admin/src/components/ui/card/CardContent.vue delete mode 100644 kv-admin/src/components/ui/card/CardDescription.vue delete mode 100644 kv-admin/src/components/ui/card/CardFooter.vue delete mode 100644 kv-admin/src/components/ui/card/CardHeader.vue delete mode 100644 kv-admin/src/components/ui/card/CardTitle.vue delete mode 100644 kv-admin/src/components/ui/card/index.js delete mode 100644 kv-admin/src/components/ui/checkbox/Checkbox.vue delete mode 100644 kv-admin/src/components/ui/checkbox/index.js delete mode 100644 kv-admin/src/components/ui/dialog/Dialog.vue delete mode 100644 kv-admin/src/components/ui/dialog/DialogClose.vue delete mode 100644 kv-admin/src/components/ui/dialog/DialogContent.vue delete mode 100644 kv-admin/src/components/ui/dialog/DialogDescription.vue delete mode 100644 kv-admin/src/components/ui/dialog/DialogFooter.vue delete mode 100644 kv-admin/src/components/ui/dialog/DialogHeader.vue delete mode 100644 kv-admin/src/components/ui/dialog/DialogOverlay.vue delete mode 100644 kv-admin/src/components/ui/dialog/DialogScrollContent.vue delete mode 100644 kv-admin/src/components/ui/dialog/DialogTitle.vue delete mode 100644 kv-admin/src/components/ui/dialog/DialogTrigger.vue delete mode 100644 kv-admin/src/components/ui/dialog/index.js delete mode 100644 kv-admin/src/components/ui/dropdown-menu/DropdownItem.vue delete mode 100644 kv-admin/src/components/ui/dropdown-menu/DropdownMenu.vue delete mode 100644 kv-admin/src/components/ui/input/Input.vue delete mode 100644 kv-admin/src/components/ui/input/index.js delete mode 100644 kv-admin/src/components/ui/label/Label.vue delete mode 100644 kv-admin/src/components/ui/label/index.js delete mode 100644 kv-admin/src/components/ui/select/Select.vue delete mode 100644 kv-admin/src/components/ui/select/SelectContent.vue delete mode 100644 kv-admin/src/components/ui/select/SelectGroup.vue delete mode 100644 kv-admin/src/components/ui/select/SelectItem.vue delete mode 100644 kv-admin/src/components/ui/select/SelectItemText.vue delete mode 100644 kv-admin/src/components/ui/select/SelectLabel.vue delete mode 100644 kv-admin/src/components/ui/select/SelectScrollDownButton.vue delete mode 100644 kv-admin/src/components/ui/select/SelectScrollUpButton.vue delete mode 100644 kv-admin/src/components/ui/select/SelectSeparator.vue delete mode 100644 kv-admin/src/components/ui/select/SelectTrigger.vue delete mode 100644 kv-admin/src/components/ui/select/SelectValue.vue delete mode 100644 kv-admin/src/components/ui/select/index.js delete mode 100644 kv-admin/src/components/ui/separator/Separator.vue delete mode 100644 kv-admin/src/components/ui/separator/index.js delete mode 100644 kv-admin/src/components/ui/sonner/Sonner.vue delete mode 100644 kv-admin/src/components/ui/sonner/index.js delete mode 100644 kv-admin/src/components/ui/table/Table.vue delete mode 100644 kv-admin/src/components/ui/table/TableBody.vue delete mode 100644 kv-admin/src/components/ui/table/TableCaption.vue delete mode 100644 kv-admin/src/components/ui/table/TableCell.vue delete mode 100644 kv-admin/src/components/ui/table/TableEmpty.vue delete mode 100644 kv-admin/src/components/ui/table/TableFooter.vue delete mode 100644 kv-admin/src/components/ui/table/TableHead.vue delete mode 100644 kv-admin/src/components/ui/table/TableHeader.vue delete mode 100644 kv-admin/src/components/ui/table/TableRow.vue delete mode 100644 kv-admin/src/components/ui/table/index.js delete mode 100644 kv-admin/src/components/ui/table/utils.js delete mode 100644 kv-admin/src/components/ui/tabs/Tabs.vue delete mode 100644 kv-admin/src/components/ui/tabs/TabsContent.vue delete mode 100644 kv-admin/src/components/ui/tabs/TabsList.vue delete mode 100644 kv-admin/src/components/ui/tabs/TabsTrigger.vue delete mode 100644 kv-admin/src/components/ui/tabs/index.js delete mode 100644 kv-admin/src/composables/useOAuthCallback.js delete mode 100644 kv-admin/src/lib/api.js delete mode 100644 kv-admin/src/lib/axios.js delete mode 100644 kv-admin/src/lib/deviceStore.js delete mode 100644 kv-admin/src/lib/tokenStore.js delete mode 100644 kv-admin/src/lib/utils.js delete mode 100644 kv-admin/src/main.js delete mode 100644 kv-admin/src/pages/authorize.vue delete mode 100644 kv-admin/src/pages/device-management.vue delete mode 100644 kv-admin/src/pages/index.vue delete mode 100644 kv-admin/src/pages/kv-manager.vue delete mode 100644 kv-admin/src/pages/password-manager.vue delete mode 100644 kv-admin/src/stores/account.js delete mode 100644 kv-admin/src/style.css delete mode 100644 kv-admin/vite.config.js delete mode 100644 prisma/migrations/20250524123413_2025_05_24/migration.sql delete mode 100644 prisma/migrations/20250524123414_2025_05_25/migration.sql delete mode 100644 prisma/migrations/20250930_remove_access_type/migration.sql delete mode 100644 prisma/migrations/20251002032512_update/migration.sql delete mode 100644 prisma/migrations/20251002074755_update/migration.sql delete mode 100644 prisma/migrations/20251005011323_update/migration.sql create mode 100644 prisma/migrations/20251006025039_init/migration.sql delete mode 100644 scripts/batchMigrate.js diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md deleted file mode 100644 index 79063c0..0000000 --- a/DEPLOYMENT.md +++ /dev/null @@ -1,137 +0,0 @@ -## 快速开始 - -如果你想快速体验 Classworks,我们推荐使用 SQLite 版本。可以零配置运行。 - -## 部署方案 - -### MySQL 版本 - -```yaml -version: '3.8' - -services: - app: - build: - context: . - args: - DATABASE_TYPE: mysql - environment: - - NODE_ENV=production - - MYSQL_DATABASE_URL=mysql://user:password@mysql:3306/classworks - ports: - - 3000:3000 - depends_on: - mysql: - condition: service_healthy - - mysql: - image: mysql:8 - environment: - - MYSQL_DATABASE=classworks - - MYSQL_USER=user - - MYSQL_PASSWORD=password - - MYSQL_ROOT_PASSWORD=rootpassword - volumes: - - mysql_data:/var/lib/mysql - healthcheck: - test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] - interval: 10s - timeout: 5s - retries: 5 - -volumes: - mysql_data: -``` - -默认配置: -- 数据库版本:MySQL 8 -- 默认端口:3306 -- 数据持久化:自动配置 - -### PostgreSQL 版本 - - -```yaml -version: '3.8' - -services: - app: - build: - context: . - args: - DATABASE_TYPE: postgres - environment: - - NODE_ENV=production - - PG_DATABASE_URL=postgresql://user:password@postgres:5432/classworks - ports: - - 3000:3000 - depends_on: - postgres: - condition: service_healthy - - postgres: - image: postgres:15-alpine - environment: - - POSTGRES_DB=classworks - - POSTGRES_USER=user - - POSTGRES_PASSWORD=password - volumes: - - postgres_data:/var/lib/postgresql/data - healthcheck: - test: ["CMD-SHELL", "pg_isready -U user -d classworks"] - interval: 10s - timeout: 5s - retries: 5 - -volumes: - postgres_data: -``` - -默认配置: -- 数据库版本:PostgreSQL 15 Alpine -- 默认端口:5432 -- 数据持久化:自动配置 - -### SQLite 版本 - -将以下内容保存为 `docker-compose.yml`: - -```yaml -version: '3.8' - -services: - app: - build: - context: . - args: - DATABASE_TYPE: sqlite - ports: - - 3000:3000 - environment: - - NODE_ENV=production - volumes: - - sqlite_data:/data - -volumes: - sqlite_data: -``` - -## 使用说明 - -1. 选择你需要的版本,将对应的配置复制到 `docker-compose.yml` 文件中 -2. 根据需要修改环境变量(见下方环境变量配置) -3. 运行 `docker compose up -d` 启动服务 - - -## 环境变量配置 -``` -# Axiom.co 遥测配置 可选 -AXIOM_DATASET= -AXIOM_TOKEN= - -# 网站密钥 可选 -SITE_KEY= - -# 服务端口 可选 默认3000 -PORT= -``` \ No newline at end of file diff --git a/classworks.js b/classworks.js index 94906a5..23f6fb2 100644 --- a/classworks.js +++ b/classworks.js @@ -1,17 +1,9 @@ #!/usr/bin/env node import { execSync } from "child_process"; -import fs from "fs"; -import path from "path"; import dotenv from "dotenv"; dotenv.config(); -const PRISMA_DIR = path.join(process.cwd(), "prisma"); -const DATABASE_TYPE = process.env.DATABASE_TYPE || "sqlite"; -const DATABASE_URL = - DATABASE_TYPE === "sqlite" - ? "file:/data/db.sqlite" - : process.env.DATABASE_URL; // 🔄 执行数据库迁移函数 function runDatabaseMigration() { @@ -28,48 +20,6 @@ function runDatabaseMigration() { // 🧱 数据库初始化函数 function setupDatabase() { try { - // 如果是 SQLite,确保 /data 目录存在 - if (DATABASE_TYPE === "sqlite") { - if (!fs.existsSync("/data")) { - fs.mkdirSync("/data", { recursive: true }); - } - } else if (!DATABASE_URL) { - console.error("❌ 缺少 DATABASE_URL 环境变量"); - process.exit(1); - } - - // 从对应数据库类型的配置目录中复制配置文件 - const sourceDir = path.join(PRISMA_DIR, "database", DATABASE_TYPE); - if (!fs.existsSync(sourceDir)) { - console.error(`❌ 数据库配置未找到:${sourceDir}`); - process.exit(1); - } - - // 递归复制函数 - function copyRecursive(src, dest) { - const stats = fs.statSync(src); - if (stats.isDirectory()) { - if (!fs.existsSync(dest)) { - fs.mkdirSync(dest, { recursive: true }); - } - const entries = fs.readdirSync(src); - for (const entry of entries) { - copyRecursive(path.join(src, entry), path.join(dest, entry)); - } - } else { - fs.copyFileSync(src, dest); - } - } - - // 将所有配置文件和目录复制到 prisma 根目录下 - const entries = fs.readdirSync(sourceDir); - for (const entry of entries) { - const sourcePath = path.join(sourceDir, entry); - const targetPath = path.join(PRISMA_DIR, entry); - copyRecursive(sourcePath, targetPath); - } - console.log(`✅ 已复制 ${DATABASE_TYPE} 数据库配置文件和目录`); - // 执行数据库迁移 runDatabaseMigration(); } catch (error) { @@ -95,7 +45,6 @@ function buildLocal() { // 🚀 启动服务函数 function startServer() { try { - console.log(`🚀 使用 ${DATABASE_TYPE} 数据库启动服务中...`); execSync("npm run start", { stdio: "inherit" }); // 启动项目 } catch (error) { console.error("❌ 服务启动失败:", error.message); diff --git a/docker-compose.yml b/docker-compose.yml index ce2ba0d..c23578c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,6 @@ services: - "3000:3000" environment: - NODE_ENV=production - - DATABASE_TYPE=sqlite - DATABASE_URL= volumes: - .data:/app/data diff --git a/kv-admin/.claude/settings.local.json b/kv-admin/.claude/settings.local.json deleted file mode 100644 index 5b5f910..0000000 --- a/kv-admin/.claude/settings.local.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "permissions": { - "allow": [ - "Read(//d/Classworks/ClassworksServer/prisma/**)" - ], - "deny": [], - "ask": [] - } -} \ No newline at end of file diff --git a/kv-admin/.env.example b/kv-admin/.env.example deleted file mode 100644 index 4a7f32d..0000000 --- a/kv-admin/.env.example +++ /dev/null @@ -1,8 +0,0 @@ -# Backend API Base URL (后端服务地址) -VITE_API_BASE_URL=http://localhost:3000 - -# Site Key for authentication (站点密钥) -VITE_SITE_KEY=your-site-key-here - -# Assets URL for app icons (应用图标资源地址) -VITE_ASSETS_URL=http://localhost:3000/assets diff --git a/kv-admin/.gitignore b/kv-admin/.gitignore deleted file mode 100644 index a547bf3..0000000 --- a/kv-admin/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/kv-admin/.npmrc b/kv-admin/.npmrc deleted file mode 100644 index d67f374..0000000 --- a/kv-admin/.npmrc +++ /dev/null @@ -1 +0,0 @@ -node-linker=hoisted diff --git a/kv-admin/.vscode/extensions.json b/kv-admin/.vscode/extensions.json deleted file mode 100644 index a7cea0b..0000000 --- a/kv-admin/.vscode/extensions.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "recommendations": ["Vue.volar"] -} diff --git a/kv-admin/README.md b/kv-admin/README.md deleted file mode 100644 index 02da2af..0000000 --- a/kv-admin/README.md +++ /dev/null @@ -1,281 +0,0 @@ -# KV 服务管理应用 - -一个基于 Vue 3 + JavaScript + shadcn-vue 的 KV 存储服务管理界面,支持多应用 Token 管理和本地设备码生成。 - -## 功能特性 - -- 🔑 **多 Token 管理**:管理多个应用的访问 Token -- 🔐 **本地设备码生成**:自动生成设备授权码,无需服务器 -- 📊 **KV 空间信息**:实时显示当前 KV 空间的使用情况 -- 💾 **数据管理**:浏览、创建、编辑和删除 KV 键值对 -- 🔍 **搜索过滤**:支持键名搜索和多种排序方式 -- 📱 **响应式设计**:适配桌面和移动设备 -- 🎨 **现代 UI**:shadcn-vue 组件库,简洁清爽 -- ⚡ **快速开发**:Vite 驱动,HMR 即时更新 -- 🗂️ **约定式路由**:基于文件系统的自动路由 - -## 技术栈 - -- **框架**:Vue 3 + JavaScript -- **构建工具**:Vite -- **UI 组件**:shadcn-vue -- **样式**:Tailwind CSS v4 -- **路由**:Vue Router + unplugin-vue-router (约定式路由) -- **图标**:Lucide Icons -- **状态管理**:LocalStorage (轻量级) - -## 快速开始 - -### 1. 安装依赖 - -```bash -pnpm install -``` - -### 2. 配置环境变量 - -复制 `.env.example` 到 `.env` 并填写配置: - -```bash -cp .env.example .env -``` - -编辑 `.env` 文件: - -```env -VITE_API_BASE_URL=http://localhost:3000 -VITE_SITE_KEY=your-site-key-here -``` - -### 3. 启动开发服务器 - -```bash -pnpm dev -``` - -应用将在 http://localhost:5173 运行 - -### 4. 构建生产版本 - -```bash -pnpm build -``` - -构建产物将输出到 `dist` 目录。 - -## 项目结构 - -``` -kv-admin/ -├── src/ -│ ├── components/ -│ │ └── ui/ # shadcn-vue 组件 -│ ├── pages/ # 约定式路由页面 -│ │ ├── index.vue # Token 管理页面 (/) -│ │ └── dashboard.vue # KV 数据管理 (/dashboard) -│ ├── lib/ -│ │ ├── api.js # API 客户端 -│ │ ├── tokenStore.js # Token 存储管理 -│ │ └── utils.js # 工具函数 -│ ├── App.vue # 根组件 -│ ├── main.js # 入口文件 -│ └── style.css # 全局样式 -├── .env.example # 环境变量模板 -├── components.json # shadcn-vue 配置 -├── jsconfig.json # JavaScript 配置 -├── vite.config.js # Vite 配置 -└── package.json -``` - -## 核心功能说明 - -### 1. Token 管理(首页) - -- **添加应用 Token**:输入应用名称和 Token,系统自动生成设备码 -- **设备码生成**:本地随机生成格式如 `XXXX-XXXX-XXXX-XXXX` 的设备码 -- **多 Token 支持**:可以添加多个应用的 Token,方便切换 -- **活跃 Token**:选择当前要使用的 Token -- **KV 空间信息**:显示当前活跃应用的 KV 数据统计 -- **Token 可见性**:支持显示/隐藏 Token 值 -- **复制功能**:一键复制设备码和 Token - -### 2. 数据管理(Dashboard) - -- **浏览数据**:查看当前应用的所有 KV 键值对 -- **搜索**:通过键名快速查找 -- **排序**:按键名、创建时间或更新时间排序 -- **创建**:添加新的键值对(JSON 格式) -- **编辑**:修改现有键值对的内容 -- **查看详情**:查看完整的键值对信息和元数据 -- **删除**:删除不需要的键值对 -- **分页**:支持大量数据的分页浏览 - -### 设备码说明 - -**什么是设备码?** -- 设备码是应用授权的密钥,相当于一个唯一标识符 -- 格式:`XXXX-XXXX-XXXX-XXXX`(4段,每段4个字母/数字) -- **本地生成**:无需服务器接口,在浏览器端随机生成 -- **用途**:用于标识和授权特定的应用或设备访问 KV 服务 - -**工作流程:** -1. 用户添加应用 Token 时,系统自动生成设备码 -2. 设备码与 Token 绑定存储在本地 -3. 应用可以使用设备码作为标识符进行授权验证 - -## API 端点 - -应用与以下 API 端点交互: - -### KV 存储 -- `GET /kv` - 获取键值对列表 -- `GET /kv/_keys` - 获取键名列表 -- `GET /kv/:key` - 获取指定键的值 -- `GET /kv/:key/metadata` - 获取键的元数据 -- `POST /kv/:key` - 创建或更新键值对 -- `DELETE /kv/:key` - 删除键值对 -- `POST /kv/_batchimport` - 批量导入 - -## 数据存储 - -应用使用 LocalStorage 存储以下数据: - -- `kv_tokens` - Token 列表数据 - ```json - [ - { - "id": "1234567890", - "token": "your-token-here", - "appName": "我的应用", - "deviceCode": "ABCD-1234-EFGH-5678", - "createdAt": "2025-01-01T00:00:00.000Z", - "lastUsed": "2025-01-01T00:00:00.000Z" - } - ] - ``` -- `kv_active_token` - 当前活跃的 Token ID - -## 约定式路由 - -本项目使用 `unplugin-vue-router` 实现约定式路由,无需手动配置路由: - -- `src/pages/index.vue` → `/` (Token 管理页面) -- `src/pages/dashboard.vue` → `/dashboard` (数据管理页面) - -### 路由元信息 - -在页面组件中使用 `defineOptions` 设置路由元信息: - -```vue - -``` - -### 导航守卫 - -路由守卫在 `src/main.js` 中配置,自动处理授权检查: - -```javascript -router.beforeEach((to, _from, next) => { - const requiresAuth = to.meta?.requiresAuth - const activeToken = tokenStore.getActiveToken() - - if (requiresAuth && !activeToken) { - next({ path: '/' }) - } else { - next() - } -}) -``` - -## 开发 - -### 添加新页面 - -在 `src/pages/` 目录下创建新的 `.vue` 文件,路由会自动生成: - -``` -src/pages/ -├── index.vue → / -├── dashboard.vue → /dashboard -└── settings.vue → /settings (自动添加) -``` - -### 添加新组件 - -使用 shadcn-vue CLI 添加组件: - -```bash -pnpm dlx shadcn-vue@latest add [component-name] -``` - -## 部署 - -### Vercel / Netlify - -这些平台会自动检测 Vite 项目并进行构建。只需连接 Git 仓库即可。 - -### 传统服务器 - -构建后将 `dist` 目录部署到您的 Web 服务器,确保配置 SPA 回退规则: - -**Nginx 示例**: -```nginx -location / { - try_files $uri $uri/ /index.html; -} -``` - -## 使用流程 - -### 首次使用 - -1. 访问首页 -2. 点击"添加应用" -3. 输入应用名称(可选)和访问 Token -4. 系统自动生成设备码并保存 -5. 点击"管理数据"进入数据管理页面 - -### 切换应用 - -1. 在首页的应用列表中 -2. 点击要切换的应用行的"选择"按钮 -3. 该应用变为"活跃"状态 -4. KV 空间信息自动更新 -5. 点击"管理数据"查看该应用的数据 - -### 管理数据 - -1. 在数据管理页面可以进行 CRUD 操作 -2. 使用搜索框快速查找键名 -3. 使用排序和分页功能浏览大量数据 -4. 点击左上角的"主页"图标返回 Token 管理页面 - -## 安全建议 - -1. 始终使用 HTTPS 部署生产环境 -2. 定期更换访问 Token -3. 不要在前端代码中硬编码敏感信息 -4. 使用环境变量管理配置 -5. 实施适当的 CORS 策略 -6. LocalStorage 数据在浏览器端存储,注意隐私保护 - -## 技术亮点 - -- ✅ **纯 JavaScript**:无 TypeScript 依赖,更简单轻量 -- ✅ **约定式路由**:基于文件系统,自动生成路由 -- ✅ **本地设备码**:客户端生成,无需服务器接口 -- ✅ **多 Token 管理**:支持多应用切换 -- ✅ **现代化工具链**:Vite + Vue 3 组合式 API -- ✅ **完整的 UI 组件**:44 个 shadcn-vue 组件 -- ✅ **响应式设计**:Tailwind CSS v4 -- ✅ **轻量级状态**:LocalStorage 管理,无需额外状态库 - -## 许可证 - -MIT diff --git a/kv-admin/components.json b/kv-admin/components.json deleted file mode 100644 index 17158ce..0000000 --- a/kv-admin/components.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "https://shadcn-vue.com/schema.json", - "style": "new-york", - "typescript": false, - "tailwind": { - "config": "", - "css": "src/style.css", - "baseColor": "neutral", - "cssVariables": true, - "prefix": "" - }, - "aliases": { - "components": "@/components", - "composables": "@/composables", - "utils": "@/lib/utils", - "ui": "@/components/ui", - "lib": "@/lib" - }, - "iconLibrary": "lucide" -} \ No newline at end of file diff --git a/kv-admin/index.html b/kv-admin/index.html deleted file mode 100644 index 98d8148..0000000 --- a/kv-admin/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Classworks KV - - -
- - - diff --git a/kv-admin/jsconfig.json b/kv-admin/jsconfig.json deleted file mode 100644 index 0486e3b..0000000 --- a/kv-admin/jsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] - } - }, - "exclude": ["node_modules", "dist"] -} diff --git a/kv-admin/package.json b/kv-admin/package.json deleted file mode 100644 index e1863aa..0000000 --- a/kv-admin/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "kv-admin", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - }, - "dependencies": { - "@radix-ui/react-slot": "^1.2.3", - "@tailwindcss/vite": "^4.1.13", - "@tanstack/vue-table": "^8.21.3", - "@vee-validate/zod": "^4.15.1", - "@vueuse/core": "^13.9.0", - "axios": "^1.12.2", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "lucide-react": "^0.544.0", - "lucide-vue-next": "^0.544.0", - "marked": "^16.3.0", - "pinia": "^3.0.3", - "radix-vue": "^1.9.17", - "reka-ui": "^2.5.1", - "tailwind-merge": "^3.3.1", - "tailwindcss": "^4.1.13", - "vee-validate": "^4.15.1", - "vue": "^3.5.21", - "vue-router": "^4.5.1", - "vue-sonner": "^2.0.9", - "zod": "^3.25.76" - }, - "devDependencies": { - "@tailwindcss/typography": "^0.5.19", - "@vitejs/plugin-vue": "^6.0.1", - "@vue/devtools": "^8.0.2", - "tw-animate-css": "^1.4.0", - "unplugin-vue-router": "^0.15.0", - "vite": "^7.1.7", - "vite-plugin-vue-devtools": "^8.0.2" - } -} diff --git a/kv-admin/pnpm-lock.yaml b/kv-admin/pnpm-lock.yaml deleted file mode 100644 index b47b14d..0000000 --- a/kv-admin/pnpm-lock.yaml +++ /dev/null @@ -1,3915 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@radix-ui/react-slot': - specifier: ^1.2.3 - version: 1.2.3(react@19.2.0) - '@tailwindcss/vite': - specifier: ^4.1.13 - version: 4.1.14(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)) - '@tanstack/vue-table': - specifier: ^8.21.3 - version: 8.21.3(vue@3.5.22) - '@vee-validate/zod': - specifier: ^4.15.1 - version: 4.15.1(vue@3.5.22)(zod@3.25.76) - '@vueuse/core': - specifier: ^13.9.0 - version: 13.9.0(vue@3.5.22) - axios: - specifier: ^1.12.2 - version: 1.12.2 - class-variance-authority: - specifier: ^0.7.1 - version: 0.7.1 - clsx: - specifier: ^2.1.1 - version: 2.1.1 - lucide-react: - specifier: ^0.544.0 - version: 0.544.0(react@19.2.0) - lucide-vue-next: - specifier: ^0.544.0 - version: 0.544.0(vue@3.5.22) - marked: - specifier: ^16.3.0 - version: 16.3.0 - pinia: - specifier: ^3.0.3 - version: 3.0.3(vue@3.5.22) - radix-vue: - specifier: ^1.9.17 - version: 1.9.17(vue@3.5.22) - reka-ui: - specifier: ^2.5.1 - version: 2.5.1(vue@3.5.22) - tailwind-merge: - specifier: ^3.3.1 - version: 3.3.1 - tailwindcss: - specifier: ^4.1.13 - version: 4.1.14 - vee-validate: - specifier: ^4.15.1 - version: 4.15.1(vue@3.5.22) - vue: - specifier: ^3.5.21 - version: 3.5.22 - vue-router: - specifier: ^4.5.1 - version: 4.5.1(vue@3.5.22) - vue-sonner: - specifier: ^2.0.9 - version: 2.0.9 - zod: - specifier: ^3.25.76 - version: 3.25.76 - devDependencies: - '@tailwindcss/typography': - specifier: ^0.5.19 - version: 0.5.19(tailwindcss@4.1.14) - '@vitejs/plugin-vue': - specifier: ^6.0.1 - version: 6.0.1(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22) - '@vue/devtools': - specifier: ^8.0.2 - version: 8.0.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22) - tw-animate-css: - specifier: ^1.4.0 - version: 1.4.0 - unplugin-vue-router: - specifier: ^0.15.0 - version: 0.15.0(@vue/compiler-sfc@3.5.22)(vue-router@4.5.1(vue@3.5.22))(vue@3.5.22) - vite: - specifier: ^7.1.7 - version: 7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1) - vite-plugin-vue-devtools: - specifier: ^8.0.2 - version: 8.0.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22) - -packages: - - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.28.4': - resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.28.4': - resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.28.3': - resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-annotate-as-pure@7.27.3': - resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-create-class-features-plugin@7.28.3': - resolution: {integrity: sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-member-expression-to-functions@7.27.1': - resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-optimise-call-expression@7.27.1': - resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-replace-supers@7.27.1': - resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': - resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.28.4': - resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.28.4': - resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-proposal-decorators@7.28.0': - resolution: {integrity: sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-decorators@7.27.1': - resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.27.1': - resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-jsx@7.27.1': - resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.27.1': - resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-typescript@7.28.0': - resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.28.4': - resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.28.4': - resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} - engines: {node: '>=6.9.0'} - - '@electron/get@2.0.3': - resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==} - engines: {node: '>=12'} - - '@esbuild/aix-ppc64@0.25.10': - resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.25.10': - resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.25.10': - resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.25.10': - resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.25.10': - resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.10': - resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.25.10': - resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.10': - resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.25.10': - resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.25.10': - resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.25.10': - resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.25.10': - resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.25.10': - resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.25.10': - resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.10': - resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.25.10': - resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.25.10': - resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.25.10': - resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.10': - resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.25.10': - resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.10': - resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.25.10': - resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.25.10': - resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.25.10': - resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.25.10': - resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.25.10': - resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@floating-ui/core@1.7.3': - resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} - - '@floating-ui/dom@1.7.4': - resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} - - '@floating-ui/utils@0.2.10': - resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - - '@floating-ui/vue@1.1.9': - resolution: {integrity: sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ==} - - '@internationalized/date@3.9.0': - resolution: {integrity: sha512-yaN3brAnHRD+4KyyOsJyk49XUvj2wtbNACSqg0bz3u8t2VuzhC8Q5dfRnrSxjnnbDb+ienBnkn1TzQfE154vyg==} - - '@internationalized/number@3.6.5': - resolution: {integrity: sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==} - - '@isaacs/fs-minipass@4.0.1': - resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} - engines: {node: '>=18.0.0'} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@polka/url@1.0.0-next.29': - resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - - '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@rolldown/pluginutils@1.0.0-beta.29': - resolution: {integrity: sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==} - - '@rollup/rollup-android-arm-eabi@4.52.3': - resolution: {integrity: sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.52.3': - resolution: {integrity: sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.52.3': - resolution: {integrity: sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.52.3': - resolution: {integrity: sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.52.3': - resolution: {integrity: sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.52.3': - resolution: {integrity: sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.52.3': - resolution: {integrity: sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.52.3': - resolution: {integrity: sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.52.3': - resolution: {integrity: sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.52.3': - resolution: {integrity: sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loong64-gnu@4.52.3': - resolution: {integrity: sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.52.3': - resolution: {integrity: sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.52.3': - resolution: {integrity: sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.52.3': - resolution: {integrity: sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.52.3': - resolution: {integrity: sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.52.3': - resolution: {integrity: sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.52.3': - resolution: {integrity: sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-openharmony-arm64@4.52.3': - resolution: {integrity: sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.52.3': - resolution: {integrity: sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.52.3': - resolution: {integrity: sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.52.3': - resolution: {integrity: sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.52.3': - resolution: {integrity: sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA==} - cpu: [x64] - os: [win32] - - '@sec-ant/readable-stream@0.4.1': - resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - - '@sindresorhus/is@4.6.0': - resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} - engines: {node: '>=10'} - - '@sindresorhus/merge-streams@4.0.0': - resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} - engines: {node: '>=18'} - - '@socket.io/component-emitter@3.1.2': - resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - - '@swc/helpers@0.5.17': - resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - - '@szmarczak/http-timer@4.0.6': - resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} - engines: {node: '>=10'} - - '@tailwindcss/node@4.1.14': - resolution: {integrity: sha512-hpz+8vFk3Ic2xssIA3e01R6jkmsAhvkQdXlEbRTk6S10xDAtiQiM3FyvZVGsucefq764euO/b8WUW9ysLdThHw==} - - '@tailwindcss/oxide-android-arm64@4.1.14': - resolution: {integrity: sha512-a94ifZrGwMvbdeAxWoSuGcIl6/DOP5cdxagid7xJv6bwFp3oebp7y2ImYsnZBMTwjn5Ev5xESvS3FFYUGgPODQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [android] - - '@tailwindcss/oxide-darwin-arm64@4.1.14': - resolution: {integrity: sha512-HkFP/CqfSh09xCnrPJA7jud7hij5ahKyWomrC3oiO2U9i0UjP17o9pJbxUN0IJ471GTQQmzwhp0DEcpbp4MZTA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@tailwindcss/oxide-darwin-x64@4.1.14': - resolution: {integrity: sha512-eVNaWmCgdLf5iv6Qd3s7JI5SEFBFRtfm6W0mphJYXgvnDEAZ5sZzqmI06bK6xo0IErDHdTA5/t7d4eTfWbWOFw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@tailwindcss/oxide-freebsd-x64@4.1.14': - resolution: {integrity: sha512-QWLoRXNikEuqtNb0dhQN6wsSVVjX6dmUFzuuiL09ZeXju25dsei2uIPl71y2Ic6QbNBsB4scwBoFnlBfabHkEw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [freebsd] - - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.14': - resolution: {integrity: sha512-VB4gjQni9+F0VCASU+L8zSIyjrLLsy03sjcR3bM0V2g4SNamo0FakZFKyUQ96ZVwGK4CaJsc9zd/obQy74o0Fw==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - - '@tailwindcss/oxide-linux-arm64-gnu@4.1.14': - resolution: {integrity: sha512-qaEy0dIZ6d9vyLnmeg24yzA8XuEAD9WjpM5nIM1sUgQ/Zv7cVkharPDQcmm/t/TvXoKo/0knI3me3AGfdx6w1w==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@tailwindcss/oxide-linux-arm64-musl@4.1.14': - resolution: {integrity: sha512-ISZjT44s59O8xKsPEIesiIydMG/sCXoMBCqsphDm/WcbnuWLxxb+GcvSIIA5NjUw6F8Tex7s5/LM2yDy8RqYBQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@tailwindcss/oxide-linux-x64-gnu@4.1.14': - resolution: {integrity: sha512-02c6JhLPJj10L2caH4U0zF8Hji4dOeahmuMl23stk0MU1wfd1OraE7rOloidSF8W5JTHkFdVo/O7uRUJJnUAJg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@tailwindcss/oxide-linux-x64-musl@4.1.14': - resolution: {integrity: sha512-TNGeLiN1XS66kQhxHG/7wMeQDOoL0S33x9BgmydbrWAb9Qw0KYdd8o1ifx4HOGDWhVmJ+Ul+JQ7lyknQFilO3Q==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@tailwindcss/oxide-wasm32-wasi@4.1.14': - resolution: {integrity: sha512-uZYAsaW/jS/IYkd6EWPJKW/NlPNSkWkBlaeVBi/WsFQNP05/bzkebUL8FH1pdsqx4f2fH/bWFcUABOM9nfiJkQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - bundledDependencies: - - '@napi-rs/wasm-runtime' - - '@emnapi/core' - - '@emnapi/runtime' - - '@tybys/wasm-util' - - '@emnapi/wasi-threads' - - tslib - - '@tailwindcss/oxide-win32-arm64-msvc@4.1.14': - resolution: {integrity: sha512-Az0RnnkcvRqsuoLH2Z4n3JfAef0wElgzHD5Aky/e+0tBUxUhIeIqFBTMNQvmMRSP15fWwmvjBxZ3Q8RhsDnxAA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@tailwindcss/oxide-win32-x64-msvc@4.1.14': - resolution: {integrity: sha512-ttblVGHgf68kEE4om1n/n44I0yGPkCPbLsqzjvybhpwa6mKKtgFfAzy6btc3HRmuW7nHe0OOrSeNP9sQmmH9XA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@tailwindcss/oxide@4.1.14': - resolution: {integrity: sha512-23yx+VUbBwCg2x5XWdB8+1lkPajzLmALEfMb51zZUBYaYVPDQvBSD/WYDqiVyBIo2BZFa3yw1Rpy3G2Jp+K0dw==} - engines: {node: '>= 10'} - - '@tailwindcss/typography@0.5.19': - resolution: {integrity: sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==} - peerDependencies: - tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' - - '@tailwindcss/vite@4.1.14': - resolution: {integrity: sha512-BoFUoU0XqgCUS1UXWhmDJroKKhNXeDzD7/XwabjkDIAbMnc4ULn5e2FuEuBbhZ6ENZoSYzKlzvZ44Yr6EUDUSA==} - peerDependencies: - vite: ^5.2.0 || ^6 || ^7 - - '@tanstack/table-core@8.21.3': - resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} - engines: {node: '>=12'} - - '@tanstack/virtual-core@3.13.12': - resolution: {integrity: sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==} - - '@tanstack/vue-table@8.21.3': - resolution: {integrity: sha512-rusRyd77c5tDPloPskctMyPLFEQUeBzxdQ+2Eow4F7gDPlPOB1UnnhzfpdvqZ8ZyX2rRNGmqNnQWm87OI2OQPw==} - engines: {node: '>=12'} - peerDependencies: - vue: '>=3.2' - - '@tanstack/vue-virtual@3.13.12': - resolution: {integrity: sha512-vhF7kEU9EXWXh+HdAwKJ2m3xaOnTTmgcdXcF2pim8g4GvI7eRrk2YRuV5nUlZnd/NbCIX4/Ja2OZu5EjJL06Ww==} - peerDependencies: - vue: ^2.7.0 || ^3.0.0 - - '@types/cacheable-request@6.0.3': - resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} - - '@types/cors@2.8.19': - resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/http-cache-semantics@4.0.4': - resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} - - '@types/keyv@3.1.4': - resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} - - '@types/node@22.18.8': - resolution: {integrity: sha512-pAZSHMiagDR7cARo/cch1f3rXy0AEXwsVsVH09FcyeJVAzCnGgmYis7P3JidtTUjyadhTeSo8TgRPswstghDaw==} - - '@types/node@24.6.2': - resolution: {integrity: sha512-d2L25Y4j+W3ZlNAeMKcy7yDsK425ibcAOO2t7aPTz6gNMH0z2GThtwENCDc0d/Pw9wgyRqE5Px1wkV7naz8ang==} - - '@types/responselike@1.0.3': - resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} - - '@types/web-bluetooth@0.0.20': - resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} - - '@types/web-bluetooth@0.0.21': - resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} - - '@types/yauzl@2.10.3': - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - - '@vee-validate/zod@4.15.1': - resolution: {integrity: sha512-329Z4TDBE5Vx0FdbA8S4eR9iGCFFUNGbxjpQ20ff5b5wGueScjocUIx9JHPa79LTG06RnlUR4XogQsjN4tecKA==} - peerDependencies: - zod: ^3.24.0 - - '@vitejs/plugin-vue@6.0.1': - resolution: {integrity: sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - vue: ^3.2.25 - - '@volar/language-core@2.4.23': - resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==} - - '@volar/source-map@2.4.23': - resolution: {integrity: sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==} - - '@vue-macros/common@3.0.0-beta.16': - resolution: {integrity: sha512-8O2gWxWFiaoNkk7PGi0+p7NPGe/f8xJ3/INUufvje/RZOs7sJvlI1jnR4lydtRFa/mU0ylMXUXXjSK0fHDEYTA==} - engines: {node: '>=20.18.0'} - peerDependencies: - vue: ^2.7.0 || ^3.2.25 - peerDependenciesMeta: - vue: - optional: true - - '@vue/babel-helper-vue-transform-on@1.5.0': - resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==} - - '@vue/babel-plugin-jsx@1.5.0': - resolution: {integrity: sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - - '@vue/babel-plugin-resolve-type@1.5.0': - resolution: {integrity: sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@vue/compiler-core@3.5.22': - resolution: {integrity: sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==} - - '@vue/compiler-dom@3.5.22': - resolution: {integrity: sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==} - - '@vue/compiler-sfc@3.5.22': - resolution: {integrity: sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==} - - '@vue/compiler-ssr@3.5.22': - resolution: {integrity: sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==} - - '@vue/devtools-api@6.6.4': - resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - - '@vue/devtools-api@7.7.7': - resolution: {integrity: sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==} - - '@vue/devtools-core@8.0.2': - resolution: {integrity: sha512-V7eKTTHoS6KfK8PSGMLZMhGv/9yNDrmv6Qc3r71QILulnzPnqK2frsTyx3e2MrhdUZnENPEm6hcb4z0GZOqNhw==} - peerDependencies: - vue: ^3.0.0 - - '@vue/devtools-electron@8.0.2': - resolution: {integrity: sha512-Zc0Dh6sp60hF44Qom133PyDwqfbzdLTbxVc0nvwi4D/Ikpe/YF5kCkJHTv8WXcXiEkkzxWaEdOvYgX6CnjYt6w==} - - '@vue/devtools-kit@7.7.7': - resolution: {integrity: sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==} - - '@vue/devtools-kit@8.0.2': - resolution: {integrity: sha512-yjZKdEmhJzQqbOh4KFBfTOQjDPMrjjBNCnHBvnTGJX+YLAqoUtY2J+cg7BE+EA8KUv8LprECq04ts75wCoIGWA==} - - '@vue/devtools-shared@7.7.7': - resolution: {integrity: sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==} - - '@vue/devtools-shared@8.0.2': - resolution: {integrity: sha512-mLU0QVdy5Lp40PMGSixDw/Kbd6v5dkQXltd2r+mdVQV7iUog2NlZuLxFZApFZ/mObUBDhoCpf0T3zF2FWWdeHw==} - - '@vue/devtools@8.0.2': - resolution: {integrity: sha512-/v4J6TfYkcVUXmkqEnTMrN2UcU1r5tFo8toFANAQABvZuPw4nMRGsqHhuJaqOIdlubddOmDSZMO0Hbar5tB1+g==} - hasBin: true - - '@vue/language-core@3.1.0': - resolution: {integrity: sha512-a7ns+X9vTbdmk7QLrvnZs8s4E1wwtxG/sELzr6F2j4pU+r/OoAv6jJGSz+5tVTU6e4+3rjepGhSP8jDmBBcb3w==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@vue/reactivity@3.5.22': - resolution: {integrity: sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==} - - '@vue/runtime-core@3.5.22': - resolution: {integrity: sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==} - - '@vue/runtime-dom@3.5.22': - resolution: {integrity: sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==} - - '@vue/server-renderer@3.5.22': - resolution: {integrity: sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==} - peerDependencies: - vue: 3.5.22 - - '@vue/shared@3.5.22': - resolution: {integrity: sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==} - - '@vueuse/core@10.11.1': - resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} - - '@vueuse/core@12.8.2': - resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==} - - '@vueuse/core@13.9.0': - resolution: {integrity: sha512-ts3regBQyURfCE2BcytLqzm8+MmLlo5Ln/KLoxDVcsZ2gzIwVNnQpQOL/UKV8alUqjSZOlpFZcRNsLRqj+OzyA==} - peerDependencies: - vue: ^3.5.0 - - '@vueuse/metadata@10.11.1': - resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==} - - '@vueuse/metadata@12.8.2': - resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==} - - '@vueuse/metadata@13.9.0': - resolution: {integrity: sha512-1AFRvuiGphfF7yWixZa0KwjYH8ulyjDCC0aFgrGRz8+P4kvDFSdXLVfTk5xAN9wEuD1J6z4/myMoYbnHoX07zg==} - - '@vueuse/shared@10.11.1': - resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} - - '@vueuse/shared@12.8.2': - resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==} - - '@vueuse/shared@13.9.0': - resolution: {integrity: sha512-e89uuTLMh0U5cZ9iDpEI2senqPGfbPRTHM/0AaQkcxnpqjkZqDYP8rpfm7edOz8s+pOCOROEy1PIveSW8+fL5g==} - peerDependencies: - vue: ^3.5.0 - - accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - alien-signals@3.0.0: - resolution: {integrity: sha512-JHoRJf18Y6HN4/KZALr3iU+0vW9LKG+8FMThQlbn4+gv8utsLIkwpomjElGPccGeNwh0FI2HN6BLnyFLo6OyLQ==} - - ansis@4.2.0: - resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} - engines: {node: '>=14'} - - aria-hidden@1.2.6: - resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} - engines: {node: '>=10'} - - ast-kit@2.1.2: - resolution: {integrity: sha512-cl76xfBQM6pztbrFWRnxbrDm9EOqDr1BF6+qQnnDZG2Co2LjyUktkN9GTJfBAfdae+DbT2nJf2nCGAdDDN7W2g==} - engines: {node: '>=20.18.0'} - - ast-walker-scope@0.8.2: - resolution: {integrity: sha512-3pYeLyDZ6nJew9QeBhS4Nly02269Dkdk32+zdbbKmL6n4ZuaGorwwA+xx12xgOciA8BF1w9x+dlH7oUkFTW91w==} - engines: {node: '>=20.18.0'} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - axios@1.12.2: - resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} - - base64id@2.0.0: - resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} - engines: {node: ^4.5.0 || >= 5.9} - - baseline-browser-mapping@2.8.10: - resolution: {integrity: sha512-uLfgBi+7IBNay8ECBO2mVMGZAc1VgZWEChxm4lv+TobGdG82LnXMjuNGo/BSSZZL4UmkWhxEHP2f5ziLNwGWMA==} - hasBin: true - - birpc@2.6.1: - resolution: {integrity: sha512-LPnFhlDpdSH6FJhJyn4M0kFO7vtQ5iPw24FnG0y21q09xC7e8+1LeR31S1MAIrDAHp4m7aas4bEkTDTvMAtebQ==} - - boolean@3.2.0: - resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - - browserslist@4.26.3: - resolution: {integrity: sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - - bundle-name@4.1.0: - resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} - engines: {node: '>=18'} - - cacheable-lookup@5.0.4: - resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} - engines: {node: '>=10.6.0'} - - cacheable-request@7.0.4: - resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} - engines: {node: '>=8'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - caniuse-lite@1.0.30001746: - resolution: {integrity: sha512-eA7Ys/DGw+pnkWWSE/id29f2IcPHVoE8wxtvE5JdvD2V28VTDPy1yEeo11Guz0sJ4ZeGRcm3uaTcAqK1LXaphA==} - - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} - - chownr@3.0.0: - resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} - engines: {node: '>=18'} - - class-variance-authority@0.7.1: - resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} - - clone-response@1.0.3: - resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} - - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - - confbox@0.2.2: - resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - cookie-es@1.2.2: - resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} - - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - - copy-anything@3.0.5: - resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} - engines: {node: '>=12.13'} - - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - crossws@0.3.5: - resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} - - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - - debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - - default-browser-id@5.0.0: - resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} - engines: {node: '>=18'} - - default-browser@5.2.1: - resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} - engines: {node: '>=18'} - - defer-to-connect@2.0.1: - resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} - engines: {node: '>=10'} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} - engines: {node: '>=12'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - destr@2.0.5: - resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - - detect-libc@2.1.1: - resolution: {integrity: sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==} - engines: {node: '>=8'} - - detect-node@2.1.0: - resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - electron-to-chromium@1.5.228: - resolution: {integrity: sha512-nxkiyuqAn4MJ1QbobwqJILiDtu/jk14hEAWaMiJmNPh1Z+jqoFlBFZjdXwLWGeVSeu9hGLg6+2G9yJaW8rBIFA==} - - electron@36.9.3: - resolution: {integrity: sha512-eR5yswsA55zVTPDEIA/PSdVNBLOp0q0Wsavgx0S3BmJYOqKoH1gqzS+hggf0/aY5OvUjVNSHiJJA1VsB5aJUug==} - engines: {node: '>= 12.20.55'} - hasBin: true - - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - - engine.io-client@6.6.3: - resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==} - - engine.io-parser@5.2.3: - resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} - engines: {node: '>=10.0.0'} - - engine.io@6.6.4: - resolution: {integrity: sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==} - engines: {node: '>=10.2.0'} - - enhanced-resolve@5.18.3: - resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} - engines: {node: '>=10.13.0'} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - - error-stack-parser-es@1.0.5: - resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - es6-error@4.1.1: - resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} - - esbuild@0.25.10: - resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - execa@9.6.0: - resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} - engines: {node: ^18.19.0 || >=20.5.0} - - exsolve@1.0.7: - resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} - - extract-zip@2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - figures@6.1.0: - resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} - engines: {node: '>=18'} - - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} - engines: {node: '>= 6'} - - fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - - get-stream@9.0.1: - resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} - engines: {node: '>=18'} - - global-agent@3.0.0: - resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} - engines: {node: '>=10.0'} - - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - got@11.8.6: - resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} - engines: {node: '>=10.19.0'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - h3@1.15.4: - resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - hookable@5.5.3: - resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - - http-cache-semantics@4.2.0: - resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} - - http2-wrapper@1.0.3: - resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} - engines: {node: '>=10.19.0'} - - human-signals@8.0.1: - resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} - engines: {node: '>=18.18.0'} - - iron-webcrypto@1.2.1: - resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} - - is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true - - is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true - - is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - - is-stream@4.0.1: - resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} - engines: {node: '>=18'} - - is-unicode-supported@2.1.0: - resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} - engines: {node: '>=18'} - - is-what@4.1.16: - resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} - engines: {node: '>=12.13'} - - is-wsl@3.1.0: - resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} - engines: {node: '>=16'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} - hasBin: true - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - - lightningcss-darwin-arm64@1.30.1: - resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.30.1: - resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.30.1: - resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.30.1: - resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.30.1: - resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-arm64-musl@1.30.1: - resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-x64-gnu@1.30.1: - resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - lightningcss-linux-x64-musl@1.30.1: - resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - lightningcss-win32-arm64-msvc@1.30.1: - resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.30.1: - resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.30.1: - resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} - engines: {node: '>= 12.0.0'} - - local-pkg@1.1.2: - resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} - engines: {node: '>=14'} - - lowercase-keys@2.0.0: - resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} - engines: {node: '>=8'} - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - - lucide-react@0.544.0: - resolution: {integrity: sha512-t5tS44bqd825zAW45UQxpG2CvcC4urOwn2TrwSH8u+MjeE+1NnWl6QqeQ/6NdjMqdOygyiT9p3Ev0p1NJykxjw==} - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - lucide-vue-next@0.544.0: - resolution: {integrity: sha512-mDp/AdGOPIDkpFHnFiTWgQgCST9aBXHVaiobZfOMIvv7nrOukzF/TP+7KoOwrngdWRaH9TMiepMBIX1vsgKJ3g==} - peerDependencies: - vue: '>=3.0.1' - - magic-string-ast@1.0.2: - resolution: {integrity: sha512-8ngQgLhcT0t3YBdn9CGkZqCYlvwW9pm7aWJwd7AxseVWf1RU8ZHCQvG1mt3N5vvUme+pXTcHB8G/7fE666U8Vw==} - engines: {node: '>=20.18.0'} - - magic-string@0.30.19: - resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} - - marked@16.3.0: - resolution: {integrity: sha512-K3UxuKu6l6bmA5FUwYho8CfJBlsUWAooKtdGgMcERSpF7gcBUrCGsLH7wDaaNOzwq18JzSUDyoEb/YsrqMac3w==} - engines: {node: '>= 20'} - hasBin: true - - matcher@3.0.0: - resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} - engines: {node: '>=10'} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mimic-response@1.0.1: - resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} - engines: {node: '>=4'} - - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - minizlib@3.1.0: - resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} - engines: {node: '>= 18'} - - mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - - mlly@1.8.0: - resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} - - mrmime@2.0.1: - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} - engines: {node: '>=10'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - muggle-string@0.4.1: - resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - nanoid@5.1.6: - resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==} - engines: {node: ^18 || >=20} - hasBin: true - - negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - - node-mock-http@1.0.3: - resolution: {integrity: sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==} - - node-releases@2.0.21: - resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} - - normalize-url@6.1.0: - resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} - engines: {node: '>=10'} - - npm-run-path@6.0.0: - resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} - engines: {node: '>=18'} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - ohash@2.0.11: - resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - open@10.2.0: - resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} - engines: {node: '>=18'} - - p-cancelable@2.1.1: - resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} - engines: {node: '>=8'} - - parse-ms@4.0.0: - resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} - engines: {node: '>=18'} - - path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - - perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} - - perfect-debounce@2.0.0: - resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - pinia@3.0.3: - resolution: {integrity: sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==} - peerDependencies: - typescript: '>=4.4.4' - vue: ^2.7.0 || ^3.5.11 - peerDependenciesMeta: - typescript: - optional: true - - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - - pkg-types@2.3.0: - resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - - postcss-selector-parser@6.0.10: - resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} - engines: {node: '>=4'} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - pretty-ms@9.3.0: - resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} - engines: {node: '>=18'} - - progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} - - quansync@0.2.11: - resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} - - quick-lru@5.1.1: - resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} - engines: {node: '>=10'} - - radix-vue@1.9.17: - resolution: {integrity: sha512-mVCu7I2vXt1L2IUYHTt0sZMz7s1K2ZtqKeTIxG3yC5mMFfLBG4FtE1FDeRMpDd+Hhg/ybi9+iXmAP1ISREndoQ==} - peerDependencies: - vue: '>= 3.2.0' - - radix3@1.1.2: - resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} - - react@19.2.0: - resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} - engines: {node: '>=0.10.0'} - - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} - - reka-ui@2.5.1: - resolution: {integrity: sha512-QJGB3q21wQ1Kw28HhhNDpjfFe8qpePX1gK4FTBRd68XTh9aEnhR5bTJnlV0jxi8FBPh0xivZBeNFUc3jiGx7mQ==} - peerDependencies: - vue: '>= 3.2.0' - - resolve-alpn@1.2.1: - resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} - - responselike@2.0.1: - resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} - - rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - - roarr@2.15.4: - resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} - engines: {node: '>=8.0'} - - rollup@4.52.3: - resolution: {integrity: sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-applescript@7.1.0: - resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} - engines: {node: '>=18'} - - scule@1.3.0: - resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - - semver-compare@1.0.0: - resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - - serialize-error@7.0.1: - resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} - engines: {node: '>=10'} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sirv@3.0.2: - resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} - engines: {node: '>=18'} - - socket.io-adapter@2.5.5: - resolution: {integrity: sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==} - - socket.io-client@4.8.1: - resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} - engines: {node: '>=10.0.0'} - - socket.io-parser@4.2.4: - resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} - engines: {node: '>=10.0.0'} - - socket.io@4.8.1: - resolution: {integrity: sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==} - engines: {node: '>=10.2.0'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - speakingurl@14.0.1: - resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} - engines: {node: '>=0.10.0'} - - sprintf-js@1.1.3: - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - - strip-final-newline@4.0.0: - resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} - engines: {node: '>=18'} - - sumchecker@3.0.1: - resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} - engines: {node: '>= 8.0'} - - superjson@2.2.2: - resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} - engines: {node: '>=16'} - - tailwind-merge@3.3.1: - resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} - - tailwindcss@4.1.14: - resolution: {integrity: sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==} - - tapable@2.2.3: - resolution: {integrity: sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==} - engines: {node: '>=6'} - - tar@7.5.1: - resolution: {integrity: sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==} - engines: {node: '>=18'} - - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - - totalist@3.0.1: - resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} - engines: {node: '>=6'} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - tw-animate-css@1.4.0: - resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} - - type-fest@0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} - - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - - uncrypto@0.1.3: - resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - undici-types@7.13.0: - resolution: {integrity: sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ==} - - unicorn-magic@0.3.0: - resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} - engines: {node: '>=18'} - - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - - unplugin-utils@0.2.5: - resolution: {integrity: sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==} - engines: {node: '>=18.12.0'} - - unplugin-utils@0.3.0: - resolution: {integrity: sha512-JLoggz+PvLVMJo+jZt97hdIIIZ2yTzGgft9e9q8iMrC4ewufl62ekeW7mixBghonn2gVb/ICjyvlmOCUBnJLQg==} - engines: {node: '>=20.19.0'} - - unplugin-vue-router@0.15.0: - resolution: {integrity: sha512-PyGehCjd9Ny9h+Uer4McbBjjib3lHihcyUEILa7pHKl6+rh8N7sFyw4ZkV+N30Oq2zmIUG7iKs3qpL0r+gXAaQ==} - peerDependencies: - '@vue/compiler-sfc': ^3.5.17 - vue-router: ^4.5.1 - peerDependenciesMeta: - vue-router: - optional: true - - unplugin@2.3.10: - resolution: {integrity: sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==} - engines: {node: '>=18.12.0'} - - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - vee-validate@4.15.1: - resolution: {integrity: sha512-DkFsiTwEKau8VIxyZBGdO6tOudD+QoUBPuHj3e6QFqmbfCRj1ArmYWue9lEp6jLSWBIw4XPlDLjFIZNLdRAMSg==} - peerDependencies: - vue: ^3.4.26 - - vite-dev-rpc@1.1.0: - resolution: {integrity: sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==} - peerDependencies: - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 - - vite-hot-client@2.1.0: - resolution: {integrity: sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==} - peerDependencies: - vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 - - vite-plugin-inspect@11.3.3: - resolution: {integrity: sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==} - engines: {node: '>=14'} - peerDependencies: - '@nuxt/kit': '*' - vite: ^6.0.0 || ^7.0.0-0 - peerDependenciesMeta: - '@nuxt/kit': - optional: true - - vite-plugin-vue-devtools@8.0.2: - resolution: {integrity: sha512-1069qvMBcyAu3yXQlvYrkwoyLOk0lSSR/gTKy/vy+Det7TXnouGei6ZcKwr5TIe938v/14oLlp0ow6FSJkkORA==} - engines: {node: '>=v14.21.3'} - peerDependencies: - vite: ^6.0.0 || ^7.0.0-0 - - vite-plugin-vue-inspector@5.3.2: - resolution: {integrity: sha512-YvEKooQcSiBTAs0DoYLfefNja9bLgkFM7NI2b07bE2SruuvX0MEa9cMaxjKVMkeCp5Nz9FRIdcN1rOdFVBeL6Q==} - peerDependencies: - vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 - - vite@7.1.7: - resolution: {integrity: sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - 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 - - vue-demi@0.14.10: - resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} - engines: {node: '>=12'} - hasBin: true - peerDependencies: - '@vue/composition-api': ^1.0.0-rc.1 - vue: ^3.0.0-0 || ^2.6.0 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - - vue-router@4.5.1: - resolution: {integrity: sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==} - peerDependencies: - vue: ^3.2.0 - - vue-sonner@2.0.9: - resolution: {integrity: sha512-i6BokNlNDL93fpzNxN/LZSn6D6MzlO+i3qXt6iVZne3x1k7R46d5HlFB4P8tYydhgqOrRbIZEsnRd3kG7qGXyw==} - peerDependencies: - '@nuxt/kit': ^4.0.3 - '@nuxt/schema': ^4.0.3 - nuxt: ^4.0.3 - peerDependenciesMeta: - '@nuxt/kit': - optional: true - '@nuxt/schema': - optional: true - nuxt: - optional: true - - vue@3.5.22: - resolution: {integrity: sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - webpack-virtual-modules@0.6.2: - resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - ws@8.17.1: - resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - wsl-utils@0.1.0: - resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} - engines: {node: '>=18'} - - xmlhttprequest-ssl@2.1.2: - resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} - engines: {node: '>=0.4.0'} - - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - - yallist@5.0.0: - resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} - engines: {node: '>=18'} - - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} - engines: {node: '>= 14.6'} - hasBin: true - - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - - yoctocolors@2.1.2: - resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} - engines: {node: '>=18'} - - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - -snapshots: - - '@babel/code-frame@7.27.1': - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/compat-data@7.28.4': {} - - '@babel/core@7.28.4': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.4 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.28.3': - dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - - '@babel/helper-annotate-as-pure@7.27.3': - dependencies: - '@babel/types': 7.28.4 - - '@babel/helper-compilation-targets@7.27.2': - dependencies: - '@babel/compat-data': 7.28.4 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.26.3 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.27.1 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.4 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-globals@7.28.0': {} - - '@babel/helper-member-expression-to-functions@7.27.1': - dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-imports@7.27.1': - dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-optimise-call-expression@7.27.1': - dependencies: - '@babel/types': 7.28.4 - - '@babel/helper-plugin-utils@7.27.1': {} - - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-member-expression-to-functions': 7.27.1 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': - dependencies: - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.27.1': {} - - '@babel/helper-validator-option@7.27.1': {} - - '@babel/helpers@7.28.4': - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.4 - - '@babel/parser@7.28.4': - dependencies: - '@babel/types': 7.28.4 - - '@babel/plugin-proposal-decorators@7.28.0(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.28.4) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.4)': - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) - transitivePeerDependencies: - - supports-color - - '@babel/template@7.27.2': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - - '@babel/traverse@7.28.4': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.4 - '@babel/template': 7.27.2 - '@babel/types': 7.28.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.28.4': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - - '@electron/get@2.0.3': - dependencies: - debug: 4.4.3 - env-paths: 2.2.1 - fs-extra: 8.1.0 - got: 11.8.6 - progress: 2.0.3 - semver: 6.3.1 - sumchecker: 3.0.1 - optionalDependencies: - global-agent: 3.0.0 - transitivePeerDependencies: - - supports-color - - '@esbuild/aix-ppc64@0.25.10': - optional: true - - '@esbuild/android-arm64@0.25.10': - optional: true - - '@esbuild/android-arm@0.25.10': - optional: true - - '@esbuild/android-x64@0.25.10': - optional: true - - '@esbuild/darwin-arm64@0.25.10': - optional: true - - '@esbuild/darwin-x64@0.25.10': - optional: true - - '@esbuild/freebsd-arm64@0.25.10': - optional: true - - '@esbuild/freebsd-x64@0.25.10': - optional: true - - '@esbuild/linux-arm64@0.25.10': - optional: true - - '@esbuild/linux-arm@0.25.10': - optional: true - - '@esbuild/linux-ia32@0.25.10': - optional: true - - '@esbuild/linux-loong64@0.25.10': - optional: true - - '@esbuild/linux-mips64el@0.25.10': - optional: true - - '@esbuild/linux-ppc64@0.25.10': - optional: true - - '@esbuild/linux-riscv64@0.25.10': - optional: true - - '@esbuild/linux-s390x@0.25.10': - optional: true - - '@esbuild/linux-x64@0.25.10': - optional: true - - '@esbuild/netbsd-arm64@0.25.10': - optional: true - - '@esbuild/netbsd-x64@0.25.10': - optional: true - - '@esbuild/openbsd-arm64@0.25.10': - optional: true - - '@esbuild/openbsd-x64@0.25.10': - optional: true - - '@esbuild/openharmony-arm64@0.25.10': - optional: true - - '@esbuild/sunos-x64@0.25.10': - optional: true - - '@esbuild/win32-arm64@0.25.10': - optional: true - - '@esbuild/win32-ia32@0.25.10': - optional: true - - '@esbuild/win32-x64@0.25.10': - optional: true - - '@floating-ui/core@1.7.3': - dependencies: - '@floating-ui/utils': 0.2.10 - - '@floating-ui/dom@1.7.4': - dependencies: - '@floating-ui/core': 1.7.3 - '@floating-ui/utils': 0.2.10 - - '@floating-ui/utils@0.2.10': {} - - '@floating-ui/vue@1.1.9(vue@3.5.22)': - dependencies: - '@floating-ui/dom': 1.7.4 - '@floating-ui/utils': 0.2.10 - vue-demi: 0.14.10(vue@3.5.22) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - - '@internationalized/date@3.9.0': - dependencies: - '@swc/helpers': 0.5.17 - - '@internationalized/number@3.6.5': - dependencies: - '@swc/helpers': 0.5.17 - - '@isaacs/fs-minipass@4.0.1': - dependencies: - minipass: 7.1.2 - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@polka/url@1.0.0-next.29': {} - - '@radix-ui/react-compose-refs@1.1.2(react@19.2.0)': - dependencies: - react: 19.2.0 - - '@radix-ui/react-slot@1.2.3(react@19.2.0)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(react@19.2.0) - react: 19.2.0 - - '@rolldown/pluginutils@1.0.0-beta.29': {} - - '@rollup/rollup-android-arm-eabi@4.52.3': - optional: true - - '@rollup/rollup-android-arm64@4.52.3': - optional: true - - '@rollup/rollup-darwin-arm64@4.52.3': - optional: true - - '@rollup/rollup-darwin-x64@4.52.3': - optional: true - - '@rollup/rollup-freebsd-arm64@4.52.3': - optional: true - - '@rollup/rollup-freebsd-x64@4.52.3': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.52.3': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.52.3': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.52.3': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.52.3': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.52.3': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.52.3': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.52.3': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.52.3': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.52.3': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.52.3': - optional: true - - '@rollup/rollup-linux-x64-musl@4.52.3': - optional: true - - '@rollup/rollup-openharmony-arm64@4.52.3': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.52.3': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.52.3': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.52.3': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.52.3': - optional: true - - '@sec-ant/readable-stream@0.4.1': {} - - '@sindresorhus/is@4.6.0': {} - - '@sindresorhus/merge-streams@4.0.0': {} - - '@socket.io/component-emitter@3.1.2': {} - - '@swc/helpers@0.5.17': - dependencies: - tslib: 2.8.1 - - '@szmarczak/http-timer@4.0.6': - dependencies: - defer-to-connect: 2.0.1 - - '@tailwindcss/node@4.1.14': - dependencies: - '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.18.3 - jiti: 2.6.1 - lightningcss: 1.30.1 - magic-string: 0.30.19 - source-map-js: 1.2.1 - tailwindcss: 4.1.14 - - '@tailwindcss/oxide-android-arm64@4.1.14': - optional: true - - '@tailwindcss/oxide-darwin-arm64@4.1.14': - optional: true - - '@tailwindcss/oxide-darwin-x64@4.1.14': - optional: true - - '@tailwindcss/oxide-freebsd-x64@4.1.14': - optional: true - - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.14': - optional: true - - '@tailwindcss/oxide-linux-arm64-gnu@4.1.14': - optional: true - - '@tailwindcss/oxide-linux-arm64-musl@4.1.14': - optional: true - - '@tailwindcss/oxide-linux-x64-gnu@4.1.14': - optional: true - - '@tailwindcss/oxide-linux-x64-musl@4.1.14': - optional: true - - '@tailwindcss/oxide-wasm32-wasi@4.1.14': - optional: true - - '@tailwindcss/oxide-win32-arm64-msvc@4.1.14': - optional: true - - '@tailwindcss/oxide-win32-x64-msvc@4.1.14': - optional: true - - '@tailwindcss/oxide@4.1.14': - dependencies: - detect-libc: 2.1.1 - tar: 7.5.1 - optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.14 - '@tailwindcss/oxide-darwin-arm64': 4.1.14 - '@tailwindcss/oxide-darwin-x64': 4.1.14 - '@tailwindcss/oxide-freebsd-x64': 4.1.14 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.14 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.14 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.14 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.14 - '@tailwindcss/oxide-linux-x64-musl': 4.1.14 - '@tailwindcss/oxide-wasm32-wasi': 4.1.14 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.14 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.14 - - '@tailwindcss/typography@0.5.19(tailwindcss@4.1.14)': - dependencies: - postcss-selector-parser: 6.0.10 - tailwindcss: 4.1.14 - - '@tailwindcss/vite@4.1.14(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))': - dependencies: - '@tailwindcss/node': 4.1.14 - '@tailwindcss/oxide': 4.1.14 - tailwindcss: 4.1.14 - vite: 7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1) - - '@tanstack/table-core@8.21.3': {} - - '@tanstack/virtual-core@3.13.12': {} - - '@tanstack/vue-table@8.21.3(vue@3.5.22)': - dependencies: - '@tanstack/table-core': 8.21.3 - vue: 3.5.22 - - '@tanstack/vue-virtual@3.13.12(vue@3.5.22)': - dependencies: - '@tanstack/virtual-core': 3.13.12 - vue: 3.5.22 - - '@types/cacheable-request@6.0.3': - dependencies: - '@types/http-cache-semantics': 4.0.4 - '@types/keyv': 3.1.4 - '@types/node': 22.18.8 - '@types/responselike': 1.0.3 - - '@types/cors@2.8.19': - dependencies: - '@types/node': 24.6.2 - - '@types/estree@1.0.8': {} - - '@types/http-cache-semantics@4.0.4': {} - - '@types/keyv@3.1.4': - dependencies: - '@types/node': 22.18.8 - - '@types/node@22.18.8': - dependencies: - undici-types: 6.21.0 - - '@types/node@24.6.2': - dependencies: - undici-types: 7.13.0 - - '@types/responselike@1.0.3': - dependencies: - '@types/node': 22.18.8 - - '@types/web-bluetooth@0.0.20': {} - - '@types/web-bluetooth@0.0.21': {} - - '@types/yauzl@2.10.3': - dependencies: - '@types/node': 22.18.8 - optional: true - - '@vee-validate/zod@4.15.1(vue@3.5.22)(zod@3.25.76)': - dependencies: - type-fest: 4.41.0 - vee-validate: 4.15.1(vue@3.5.22) - zod: 3.25.76 - transitivePeerDependencies: - - vue - - '@vitejs/plugin-vue@6.0.1(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22)': - dependencies: - '@rolldown/pluginutils': 1.0.0-beta.29 - vite: 7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1) - vue: 3.5.22 - - '@volar/language-core@2.4.23': - dependencies: - '@volar/source-map': 2.4.23 - - '@volar/source-map@2.4.23': {} - - '@vue-macros/common@3.0.0-beta.16(vue@3.5.22)': - dependencies: - '@vue/compiler-sfc': 3.5.22 - ast-kit: 2.1.2 - local-pkg: 1.1.2 - magic-string-ast: 1.0.2 - unplugin-utils: 0.2.5 - optionalDependencies: - vue: 3.5.22 - - '@vue/babel-helper-vue-transform-on@1.5.0': {} - - '@vue/babel-plugin-jsx@1.5.0(@babel/core@7.28.4)': - dependencies: - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@vue/babel-helper-vue-transform-on': 1.5.0 - '@vue/babel-plugin-resolve-type': 1.5.0(@babel/core@7.28.4) - '@vue/shared': 3.5.22 - optionalDependencies: - '@babel/core': 7.28.4 - transitivePeerDependencies: - - supports-color - - '@vue/babel-plugin-resolve-type@1.5.0(@babel/core@7.28.4)': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/core': 7.28.4 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/parser': 7.28.4 - '@vue/compiler-sfc': 3.5.22 - transitivePeerDependencies: - - supports-color - - '@vue/compiler-core@3.5.22': - dependencies: - '@babel/parser': 7.28.4 - '@vue/shared': 3.5.22 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - - '@vue/compiler-dom@3.5.22': - dependencies: - '@vue/compiler-core': 3.5.22 - '@vue/shared': 3.5.22 - - '@vue/compiler-sfc@3.5.22': - dependencies: - '@babel/parser': 7.28.4 - '@vue/compiler-core': 3.5.22 - '@vue/compiler-dom': 3.5.22 - '@vue/compiler-ssr': 3.5.22 - '@vue/shared': 3.5.22 - estree-walker: 2.0.2 - magic-string: 0.30.19 - postcss: 8.5.6 - source-map-js: 1.2.1 - - '@vue/compiler-ssr@3.5.22': - dependencies: - '@vue/compiler-dom': 3.5.22 - '@vue/shared': 3.5.22 - - '@vue/devtools-api@6.6.4': {} - - '@vue/devtools-api@7.7.7': - dependencies: - '@vue/devtools-kit': 7.7.7 - - '@vue/devtools-core@8.0.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22)': - dependencies: - '@vue/devtools-kit': 8.0.2 - '@vue/devtools-shared': 8.0.2 - mitt: 3.0.1 - nanoid: 5.1.6 - pathe: 2.0.3 - vite-hot-client: 2.1.0(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)) - vue: 3.5.22 - transitivePeerDependencies: - - vite - - '@vue/devtools-electron@8.0.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22)': - dependencies: - '@vue/devtools-core': 8.0.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22) - '@vue/devtools-kit': 8.0.2 - '@vue/devtools-shared': 8.0.2 - electron: 36.9.3 - execa: 9.6.0 - h3: 1.15.4 - pathe: 2.0.3 - socket.io: 4.8.1 - socket.io-client: 4.8.1 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - vite - - vue - - '@vue/devtools-kit@7.7.7': - dependencies: - '@vue/devtools-shared': 7.7.7 - birpc: 2.6.1 - hookable: 5.5.3 - mitt: 3.0.1 - perfect-debounce: 1.0.0 - speakingurl: 14.0.1 - superjson: 2.2.2 - - '@vue/devtools-kit@8.0.2': - dependencies: - '@vue/devtools-shared': 8.0.2 - birpc: 2.6.1 - hookable: 5.5.3 - mitt: 3.0.1 - perfect-debounce: 2.0.0 - speakingurl: 14.0.1 - superjson: 2.2.2 - - '@vue/devtools-shared@7.7.7': - dependencies: - rfdc: 1.4.1 - - '@vue/devtools-shared@8.0.2': - dependencies: - rfdc: 1.4.1 - - '@vue/devtools@8.0.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22)': - dependencies: - '@vue/devtools-electron': 8.0.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22) - '@vue/devtools-kit': 8.0.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - vite - - vue - - '@vue/language-core@3.1.0': - dependencies: - '@volar/language-core': 2.4.23 - '@vue/compiler-dom': 3.5.22 - '@vue/shared': 3.5.22 - alien-signals: 3.0.0 - muggle-string: 0.4.1 - path-browserify: 1.0.1 - picomatch: 4.0.3 - - '@vue/reactivity@3.5.22': - dependencies: - '@vue/shared': 3.5.22 - - '@vue/runtime-core@3.5.22': - dependencies: - '@vue/reactivity': 3.5.22 - '@vue/shared': 3.5.22 - - '@vue/runtime-dom@3.5.22': - dependencies: - '@vue/reactivity': 3.5.22 - '@vue/runtime-core': 3.5.22 - '@vue/shared': 3.5.22 - csstype: 3.1.3 - - '@vue/server-renderer@3.5.22(vue@3.5.22)': - dependencies: - '@vue/compiler-ssr': 3.5.22 - '@vue/shared': 3.5.22 - vue: 3.5.22 - - '@vue/shared@3.5.22': {} - - '@vueuse/core@10.11.1(vue@3.5.22)': - dependencies: - '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 10.11.1 - '@vueuse/shared': 10.11.1(vue@3.5.22) - vue-demi: 0.14.10(vue@3.5.22) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - - '@vueuse/core@12.8.2': - dependencies: - '@types/web-bluetooth': 0.0.21 - '@vueuse/metadata': 12.8.2 - '@vueuse/shared': 12.8.2 - vue: 3.5.22 - transitivePeerDependencies: - - typescript - - '@vueuse/core@13.9.0(vue@3.5.22)': - dependencies: - '@types/web-bluetooth': 0.0.21 - '@vueuse/metadata': 13.9.0 - '@vueuse/shared': 13.9.0(vue@3.5.22) - vue: 3.5.22 - - '@vueuse/metadata@10.11.1': {} - - '@vueuse/metadata@12.8.2': {} - - '@vueuse/metadata@13.9.0': {} - - '@vueuse/shared@10.11.1(vue@3.5.22)': - dependencies: - vue-demi: 0.14.10(vue@3.5.22) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - - '@vueuse/shared@12.8.2': - dependencies: - vue: 3.5.22 - transitivePeerDependencies: - - typescript - - '@vueuse/shared@13.9.0(vue@3.5.22)': - dependencies: - vue: 3.5.22 - - accepts@1.3.8: - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - - acorn@8.15.0: {} - - alien-signals@3.0.0: {} - - ansis@4.2.0: {} - - aria-hidden@1.2.6: - dependencies: - tslib: 2.8.1 - - ast-kit@2.1.2: - dependencies: - '@babel/parser': 7.28.4 - pathe: 2.0.3 - - ast-walker-scope@0.8.2: - dependencies: - '@babel/parser': 7.28.4 - ast-kit: 2.1.2 - - asynckit@0.4.0: {} - - axios@1.12.2: - dependencies: - follow-redirects: 1.15.11 - form-data: 4.0.4 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - base64id@2.0.0: {} - - baseline-browser-mapping@2.8.10: {} - - birpc@2.6.1: {} - - boolean@3.2.0: - optional: true - - browserslist@4.26.3: - dependencies: - baseline-browser-mapping: 2.8.10 - caniuse-lite: 1.0.30001746 - electron-to-chromium: 1.5.228 - node-releases: 2.0.21 - update-browserslist-db: 1.1.3(browserslist@4.26.3) - - buffer-crc32@0.2.13: {} - - bundle-name@4.1.0: - dependencies: - run-applescript: 7.1.0 - - cacheable-lookup@5.0.4: {} - - cacheable-request@7.0.4: - dependencies: - clone-response: 1.0.3 - get-stream: 5.2.0 - http-cache-semantics: 4.2.0 - keyv: 4.5.4 - lowercase-keys: 2.0.0 - normalize-url: 6.1.0 - responselike: 2.0.1 - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - caniuse-lite@1.0.30001746: {} - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - - chownr@3.0.0: {} - - class-variance-authority@0.7.1: - dependencies: - clsx: 2.1.1 - - clone-response@1.0.3: - dependencies: - mimic-response: 1.0.1 - - clsx@2.1.1: {} - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - confbox@0.1.8: {} - - confbox@0.2.2: {} - - convert-source-map@2.0.0: {} - - cookie-es@1.2.2: {} - - cookie@0.7.2: {} - - copy-anything@3.0.5: - dependencies: - is-what: 4.1.16 - - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - crossws@0.3.5: - dependencies: - uncrypto: 0.1.3 - - cssesc@3.0.0: {} - - csstype@3.1.3: {} - - debug@4.3.7: - dependencies: - ms: 2.1.3 - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - decompress-response@6.0.0: - dependencies: - mimic-response: 3.1.0 - - default-browser-id@5.0.0: {} - - default-browser@5.2.1: - dependencies: - bundle-name: 4.1.0 - default-browser-id: 5.0.0 - - defer-to-connect@2.0.1: {} - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - optional: true - - define-lazy-prop@3.0.0: {} - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - optional: true - - defu@6.1.4: {} - - delayed-stream@1.0.0: {} - - destr@2.0.5: {} - - detect-libc@2.1.1: {} - - detect-node@2.1.0: - optional: true - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - electron-to-chromium@1.5.228: {} - - electron@36.9.3: - dependencies: - '@electron/get': 2.0.3 - '@types/node': 22.18.8 - extract-zip: 2.0.1 - transitivePeerDependencies: - - supports-color - - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - - engine.io-client@6.6.3: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 - engine.io-parser: 5.2.3 - ws: 8.17.1 - xmlhttprequest-ssl: 2.1.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - engine.io-parser@5.2.3: {} - - engine.io@6.6.4: - dependencies: - '@types/cors': 2.8.19 - '@types/node': 24.6.2 - accepts: 1.3.8 - base64id: 2.0.0 - cookie: 0.7.2 - cors: 2.8.5 - debug: 4.3.7 - engine.io-parser: 5.2.3 - ws: 8.17.1 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - enhanced-resolve@5.18.3: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.2.3 - - entities@4.5.0: {} - - env-paths@2.2.1: {} - - error-stack-parser-es@1.0.5: {} - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - es6-error@4.1.1: - optional: true - - esbuild@0.25.10: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.10 - '@esbuild/android-arm': 0.25.10 - '@esbuild/android-arm64': 0.25.10 - '@esbuild/android-x64': 0.25.10 - '@esbuild/darwin-arm64': 0.25.10 - '@esbuild/darwin-x64': 0.25.10 - '@esbuild/freebsd-arm64': 0.25.10 - '@esbuild/freebsd-x64': 0.25.10 - '@esbuild/linux-arm': 0.25.10 - '@esbuild/linux-arm64': 0.25.10 - '@esbuild/linux-ia32': 0.25.10 - '@esbuild/linux-loong64': 0.25.10 - '@esbuild/linux-mips64el': 0.25.10 - '@esbuild/linux-ppc64': 0.25.10 - '@esbuild/linux-riscv64': 0.25.10 - '@esbuild/linux-s390x': 0.25.10 - '@esbuild/linux-x64': 0.25.10 - '@esbuild/netbsd-arm64': 0.25.10 - '@esbuild/netbsd-x64': 0.25.10 - '@esbuild/openbsd-arm64': 0.25.10 - '@esbuild/openbsd-x64': 0.25.10 - '@esbuild/openharmony-arm64': 0.25.10 - '@esbuild/sunos-x64': 0.25.10 - '@esbuild/win32-arm64': 0.25.10 - '@esbuild/win32-ia32': 0.25.10 - '@esbuild/win32-x64': 0.25.10 - - escalade@3.2.0: {} - - escape-string-regexp@4.0.0: - optional: true - - estree-walker@2.0.2: {} - - execa@9.6.0: - dependencies: - '@sindresorhus/merge-streams': 4.0.0 - cross-spawn: 7.0.6 - figures: 6.1.0 - get-stream: 9.0.1 - human-signals: 8.0.1 - is-plain-obj: 4.1.0 - is-stream: 4.0.1 - npm-run-path: 6.0.0 - pretty-ms: 9.3.0 - signal-exit: 4.1.0 - strip-final-newline: 4.0.0 - yoctocolors: 2.1.2 - - exsolve@1.0.7: {} - - extract-zip@2.0.1: - dependencies: - debug: 4.4.3 - get-stream: 5.2.0 - yauzl: 2.10.0 - optionalDependencies: - '@types/yauzl': 2.10.3 - transitivePeerDependencies: - - supports-color - - fast-deep-equal@3.1.3: {} - - fd-slicer@1.1.0: - dependencies: - pend: 1.2.0 - - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - figures@6.1.0: - dependencies: - is-unicode-supported: 2.1.0 - - follow-redirects@1.15.11: {} - - form-data@4.0.4: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.2 - mime-types: 2.1.35 - - fs-extra@8.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - gensync@1.0.0-beta.2: {} - - get-intrinsic@1.3.0: - 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 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-stream@5.2.0: - dependencies: - pump: 3.0.3 - - get-stream@9.0.1: - dependencies: - '@sec-ant/readable-stream': 0.4.1 - is-stream: 4.0.1 - - global-agent@3.0.0: - dependencies: - boolean: 3.2.0 - es6-error: 4.1.1 - matcher: 3.0.0 - roarr: 2.15.4 - semver: 7.7.2 - serialize-error: 7.0.1 - optional: true - - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 - optional: true - - gopd@1.2.0: {} - - got@11.8.6: - dependencies: - '@sindresorhus/is': 4.6.0 - '@szmarczak/http-timer': 4.0.6 - '@types/cacheable-request': 6.0.3 - '@types/responselike': 1.0.3 - cacheable-lookup: 5.0.4 - cacheable-request: 7.0.4 - decompress-response: 6.0.0 - http2-wrapper: 1.0.3 - lowercase-keys: 2.0.0 - p-cancelable: 2.1.1 - responselike: 2.0.1 - - graceful-fs@4.2.11: {} - - h3@1.15.4: - dependencies: - cookie-es: 1.2.2 - crossws: 0.3.5 - defu: 6.1.4 - destr: 2.0.5 - iron-webcrypto: 1.2.1 - node-mock-http: 1.0.3 - radix3: 1.1.2 - ufo: 1.6.1 - uncrypto: 0.1.3 - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - optional: true - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - hookable@5.5.3: {} - - http-cache-semantics@4.2.0: {} - - http2-wrapper@1.0.3: - dependencies: - quick-lru: 5.1.1 - resolve-alpn: 1.2.1 - - human-signals@8.0.1: {} - - iron-webcrypto@1.2.1: {} - - is-docker@3.0.0: {} - - is-inside-container@1.0.0: - dependencies: - is-docker: 3.0.0 - - is-plain-obj@4.1.0: {} - - is-stream@4.0.1: {} - - is-unicode-supported@2.1.0: {} - - is-what@4.1.16: {} - - is-wsl@3.1.0: - dependencies: - is-inside-container: 1.0.0 - - isexe@2.0.0: {} - - jiti@2.6.1: {} - - js-tokens@4.0.0: {} - - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - - json-stringify-safe@5.0.1: - optional: true - - json5@2.2.3: {} - - jsonfile@4.0.0: - optionalDependencies: - graceful-fs: 4.2.11 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kolorist@1.8.0: {} - - lightningcss-darwin-arm64@1.30.1: - optional: true - - lightningcss-darwin-x64@1.30.1: - optional: true - - lightningcss-freebsd-x64@1.30.1: - optional: true - - lightningcss-linux-arm-gnueabihf@1.30.1: - optional: true - - lightningcss-linux-arm64-gnu@1.30.1: - optional: true - - lightningcss-linux-arm64-musl@1.30.1: - optional: true - - lightningcss-linux-x64-gnu@1.30.1: - optional: true - - lightningcss-linux-x64-musl@1.30.1: - optional: true - - lightningcss-win32-arm64-msvc@1.30.1: - optional: true - - lightningcss-win32-x64-msvc@1.30.1: - optional: true - - lightningcss@1.30.1: - dependencies: - detect-libc: 2.1.1 - optionalDependencies: - lightningcss-darwin-arm64: 1.30.1 - lightningcss-darwin-x64: 1.30.1 - lightningcss-freebsd-x64: 1.30.1 - lightningcss-linux-arm-gnueabihf: 1.30.1 - lightningcss-linux-arm64-gnu: 1.30.1 - lightningcss-linux-arm64-musl: 1.30.1 - lightningcss-linux-x64-gnu: 1.30.1 - lightningcss-linux-x64-musl: 1.30.1 - lightningcss-win32-arm64-msvc: 1.30.1 - lightningcss-win32-x64-msvc: 1.30.1 - - local-pkg@1.1.2: - dependencies: - mlly: 1.8.0 - pkg-types: 2.3.0 - quansync: 0.2.11 - - lowercase-keys@2.0.0: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - lucide-react@0.544.0(react@19.2.0): - dependencies: - react: 19.2.0 - - lucide-vue-next@0.544.0(vue@3.5.22): - dependencies: - vue: 3.5.22 - - magic-string-ast@1.0.2: - dependencies: - magic-string: 0.30.19 - - magic-string@0.30.19: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - marked@16.3.0: {} - - matcher@3.0.0: - dependencies: - escape-string-regexp: 4.0.0 - optional: true - - math-intrinsics@1.1.0: {} - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mimic-response@1.0.1: {} - - mimic-response@3.1.0: {} - - minipass@7.1.2: {} - - minizlib@3.1.0: - dependencies: - minipass: 7.1.2 - - mitt@3.0.1: {} - - mlly@1.8.0: - dependencies: - acorn: 8.15.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.1 - - mrmime@2.0.1: {} - - ms@2.1.3: {} - - muggle-string@0.4.1: {} - - nanoid@3.3.11: {} - - nanoid@5.1.6: {} - - negotiator@0.6.3: {} - - node-mock-http@1.0.3: {} - - node-releases@2.0.21: {} - - normalize-url@6.1.0: {} - - npm-run-path@6.0.0: - dependencies: - path-key: 4.0.0 - unicorn-magic: 0.3.0 - - object-assign@4.1.1: {} - - object-keys@1.1.1: - optional: true - - ohash@2.0.11: {} - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - open@10.2.0: - dependencies: - default-browser: 5.2.1 - define-lazy-prop: 3.0.0 - is-inside-container: 1.0.0 - wsl-utils: 0.1.0 - - p-cancelable@2.1.1: {} - - parse-ms@4.0.0: {} - - path-browserify@1.0.1: {} - - path-key@3.1.1: {} - - path-key@4.0.0: {} - - pathe@2.0.3: {} - - pend@1.2.0: {} - - perfect-debounce@1.0.0: {} - - perfect-debounce@2.0.0: {} - - picocolors@1.1.1: {} - - picomatch@4.0.3: {} - - pinia@3.0.3(vue@3.5.22): - dependencies: - '@vue/devtools-api': 7.7.7 - vue: 3.5.22 - - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.8.0 - pathe: 2.0.3 - - pkg-types@2.3.0: - dependencies: - confbox: 0.2.2 - exsolve: 1.0.7 - pathe: 2.0.3 - - postcss-selector-parser@6.0.10: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - pretty-ms@9.3.0: - dependencies: - parse-ms: 4.0.0 - - progress@2.0.3: {} - - proxy-from-env@1.1.0: {} - - pump@3.0.3: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - - quansync@0.2.11: {} - - quick-lru@5.1.1: {} - - radix-vue@1.9.17(vue@3.5.22): - dependencies: - '@floating-ui/dom': 1.7.4 - '@floating-ui/vue': 1.1.9(vue@3.5.22) - '@internationalized/date': 3.9.0 - '@internationalized/number': 3.6.5 - '@tanstack/vue-virtual': 3.13.12(vue@3.5.22) - '@vueuse/core': 10.11.1(vue@3.5.22) - '@vueuse/shared': 10.11.1(vue@3.5.22) - aria-hidden: 1.2.6 - defu: 6.1.4 - fast-deep-equal: 3.1.3 - nanoid: 5.1.6 - vue: 3.5.22 - transitivePeerDependencies: - - '@vue/composition-api' - - radix3@1.1.2: {} - - react@19.2.0: {} - - readdirp@4.1.2: {} - - reka-ui@2.5.1(vue@3.5.22): - dependencies: - '@floating-ui/dom': 1.7.4 - '@floating-ui/vue': 1.1.9(vue@3.5.22) - '@internationalized/date': 3.9.0 - '@internationalized/number': 3.6.5 - '@tanstack/vue-virtual': 3.13.12(vue@3.5.22) - '@vueuse/core': 12.8.2 - '@vueuse/shared': 12.8.2 - aria-hidden: 1.2.6 - defu: 6.1.4 - ohash: 2.0.11 - vue: 3.5.22 - transitivePeerDependencies: - - '@vue/composition-api' - - typescript - - resolve-alpn@1.2.1: {} - - responselike@2.0.1: - dependencies: - lowercase-keys: 2.0.0 - - rfdc@1.4.1: {} - - roarr@2.15.4: - dependencies: - boolean: 3.2.0 - detect-node: 2.1.0 - globalthis: 1.0.4 - json-stringify-safe: 5.0.1 - semver-compare: 1.0.0 - sprintf-js: 1.1.3 - optional: true - - rollup@4.52.3: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.52.3 - '@rollup/rollup-android-arm64': 4.52.3 - '@rollup/rollup-darwin-arm64': 4.52.3 - '@rollup/rollup-darwin-x64': 4.52.3 - '@rollup/rollup-freebsd-arm64': 4.52.3 - '@rollup/rollup-freebsd-x64': 4.52.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.52.3 - '@rollup/rollup-linux-arm-musleabihf': 4.52.3 - '@rollup/rollup-linux-arm64-gnu': 4.52.3 - '@rollup/rollup-linux-arm64-musl': 4.52.3 - '@rollup/rollup-linux-loong64-gnu': 4.52.3 - '@rollup/rollup-linux-ppc64-gnu': 4.52.3 - '@rollup/rollup-linux-riscv64-gnu': 4.52.3 - '@rollup/rollup-linux-riscv64-musl': 4.52.3 - '@rollup/rollup-linux-s390x-gnu': 4.52.3 - '@rollup/rollup-linux-x64-gnu': 4.52.3 - '@rollup/rollup-linux-x64-musl': 4.52.3 - '@rollup/rollup-openharmony-arm64': 4.52.3 - '@rollup/rollup-win32-arm64-msvc': 4.52.3 - '@rollup/rollup-win32-ia32-msvc': 4.52.3 - '@rollup/rollup-win32-x64-gnu': 4.52.3 - '@rollup/rollup-win32-x64-msvc': 4.52.3 - fsevents: 2.3.3 - - run-applescript@7.1.0: {} - - scule@1.3.0: {} - - semver-compare@1.0.0: - optional: true - - semver@6.3.1: {} - - semver@7.7.2: - optional: true - - serialize-error@7.0.1: - dependencies: - type-fest: 0.13.1 - optional: true - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - signal-exit@4.1.0: {} - - sirv@3.0.2: - dependencies: - '@polka/url': 1.0.0-next.29 - mrmime: 2.0.1 - totalist: 3.0.1 - - socket.io-adapter@2.5.5: - dependencies: - debug: 4.3.7 - ws: 8.17.1 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - socket.io-client@4.8.1: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 - engine.io-client: 6.6.3 - socket.io-parser: 4.2.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - socket.io-parser@4.2.4: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 - transitivePeerDependencies: - - supports-color - - socket.io@4.8.1: - dependencies: - accepts: 1.3.8 - base64id: 2.0.0 - cors: 2.8.5 - debug: 4.3.7 - engine.io: 6.6.4 - socket.io-adapter: 2.5.5 - socket.io-parser: 4.2.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - source-map-js@1.2.1: {} - - speakingurl@14.0.1: {} - - sprintf-js@1.1.3: - optional: true - - strip-final-newline@4.0.0: {} - - sumchecker@3.0.1: - dependencies: - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - superjson@2.2.2: - dependencies: - copy-anything: 3.0.5 - - tailwind-merge@3.3.1: {} - - tailwindcss@4.1.14: {} - - tapable@2.2.3: {} - - tar@7.5.1: - dependencies: - '@isaacs/fs-minipass': 4.0.1 - chownr: 3.0.0 - minipass: 7.1.2 - minizlib: 3.1.0 - yallist: 5.0.0 - - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - totalist@3.0.1: {} - - tslib@2.8.1: {} - - tw-animate-css@1.4.0: {} - - type-fest@0.13.1: - optional: true - - type-fest@4.41.0: {} - - ufo@1.6.1: {} - - uncrypto@0.1.3: {} - - undici-types@6.21.0: {} - - undici-types@7.13.0: {} - - unicorn-magic@0.3.0: {} - - universalify@0.1.2: {} - - unplugin-utils@0.2.5: - dependencies: - pathe: 2.0.3 - picomatch: 4.0.3 - - unplugin-utils@0.3.0: - dependencies: - pathe: 2.0.3 - picomatch: 4.0.3 - - unplugin-vue-router@0.15.0(@vue/compiler-sfc@3.5.22)(vue-router@4.5.1(vue@3.5.22))(vue@3.5.22): - dependencies: - '@vue-macros/common': 3.0.0-beta.16(vue@3.5.22) - '@vue/compiler-sfc': 3.5.22 - '@vue/language-core': 3.1.0 - ast-walker-scope: 0.8.2 - chokidar: 4.0.3 - json5: 2.2.3 - local-pkg: 1.1.2 - magic-string: 0.30.19 - mlly: 1.8.0 - muggle-string: 0.4.1 - pathe: 2.0.3 - picomatch: 4.0.3 - scule: 1.3.0 - tinyglobby: 0.2.15 - unplugin: 2.3.10 - unplugin-utils: 0.2.5 - yaml: 2.8.1 - optionalDependencies: - vue-router: 4.5.1(vue@3.5.22) - transitivePeerDependencies: - - typescript - - vue - - unplugin@2.3.10: - dependencies: - '@jridgewell/remapping': 2.3.5 - acorn: 8.15.0 - picomatch: 4.0.3 - webpack-virtual-modules: 0.6.2 - - update-browserslist-db@1.1.3(browserslist@4.26.3): - dependencies: - browserslist: 4.26.3 - escalade: 3.2.0 - picocolors: 1.1.1 - - util-deprecate@1.0.2: {} - - vary@1.1.2: {} - - vee-validate@4.15.1(vue@3.5.22): - dependencies: - '@vue/devtools-api': 7.7.7 - type-fest: 4.41.0 - vue: 3.5.22 - - vite-dev-rpc@1.1.0(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)): - dependencies: - birpc: 2.6.1 - vite: 7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1) - vite-hot-client: 2.1.0(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)) - - vite-hot-client@2.1.0(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)): - dependencies: - vite: 7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1) - - vite-plugin-inspect@11.3.3(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)): - dependencies: - ansis: 4.2.0 - debug: 4.4.3 - error-stack-parser-es: 1.0.5 - ohash: 2.0.11 - open: 10.2.0 - perfect-debounce: 2.0.0 - sirv: 3.0.2 - unplugin-utils: 0.3.0 - vite: 7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1) - vite-dev-rpc: 1.1.0(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)) - transitivePeerDependencies: - - supports-color - - vite-plugin-vue-devtools@8.0.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22): - dependencies: - '@vue/devtools-core': 8.0.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1))(vue@3.5.22) - '@vue/devtools-kit': 8.0.2 - '@vue/devtools-shared': 8.0.2 - execa: 9.6.0 - sirv: 3.0.2 - vite: 7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1) - vite-plugin-inspect: 11.3.3(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)) - vite-plugin-vue-inspector: 5.3.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)) - transitivePeerDependencies: - - '@nuxt/kit' - - supports-color - - vue - - vite-plugin-vue-inspector@5.3.2(vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1)): - dependencies: - '@babel/core': 7.28.4 - '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.4) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.4) - '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.4) - '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.4) - '@vue/compiler-dom': 3.5.22 - kolorist: 1.8.0 - magic-string: 0.30.19 - vite: 7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1) - transitivePeerDependencies: - - supports-color - - vite@7.1.7(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(yaml@2.8.1): - dependencies: - esbuild: 0.25.10 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.52.3 - tinyglobby: 0.2.15 - optionalDependencies: - '@types/node': 24.6.2 - fsevents: 2.3.3 - jiti: 2.6.1 - lightningcss: 1.30.1 - yaml: 2.8.1 - - vue-demi@0.14.10(vue@3.5.22): - dependencies: - vue: 3.5.22 - - vue-router@4.5.1(vue@3.5.22): - dependencies: - '@vue/devtools-api': 6.6.4 - vue: 3.5.22 - - vue-sonner@2.0.9: {} - - vue@3.5.22: - dependencies: - '@vue/compiler-dom': 3.5.22 - '@vue/compiler-sfc': 3.5.22 - '@vue/runtime-dom': 3.5.22 - '@vue/server-renderer': 3.5.22(vue@3.5.22) - '@vue/shared': 3.5.22 - - webpack-virtual-modules@0.6.2: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wrappy@1.0.2: {} - - ws@8.17.1: {} - - wsl-utils@0.1.0: - dependencies: - is-wsl: 3.1.0 - - xmlhttprequest-ssl@2.1.2: {} - - yallist@3.1.1: {} - - yallist@5.0.0: {} - - yaml@2.8.1: {} - - yauzl@2.10.0: - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - - yoctocolors@2.1.2: {} - - zod@3.25.76: {} diff --git a/kv-admin/public/vite.svg b/kv-admin/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/kv-admin/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/kv-admin/src/App.vue b/kv-admin/src/App.vue deleted file mode 100644 index 0270f57..0000000 --- a/kv-admin/src/App.vue +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/kv-admin/src/assets/vue.svg b/kv-admin/src/assets/vue.svg deleted file mode 100644 index 770e9d3..0000000 --- a/kv-admin/src/assets/vue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/kv-admin/src/components/AppCard.vue b/kv-admin/src/components/AppCard.vue deleted file mode 100644 index 39acfb6..0000000 --- a/kv-admin/src/components/AppCard.vue +++ /dev/null @@ -1,296 +0,0 @@ - - - diff --git a/kv-admin/src/components/DeviceRegisterDialog.vue b/kv-admin/src/components/DeviceRegisterDialog.vue deleted file mode 100644 index be9e136..0000000 --- a/kv-admin/src/components/DeviceRegisterDialog.vue +++ /dev/null @@ -1,400 +0,0 @@ - - - diff --git a/kv-admin/src/components/EditDeviceNameDialog.vue b/kv-admin/src/components/EditDeviceNameDialog.vue deleted file mode 100644 index 76d34e4..0000000 --- a/kv-admin/src/components/EditDeviceNameDialog.vue +++ /dev/null @@ -1,136 +0,0 @@ - - - diff --git a/kv-admin/src/components/HelloWorld.vue b/kv-admin/src/components/HelloWorld.vue deleted file mode 100644 index b58e52b..0000000 --- a/kv-admin/src/components/HelloWorld.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - - - diff --git a/kv-admin/src/components/LoginDialog.vue b/kv-admin/src/components/LoginDialog.vue deleted file mode 100644 index b106ed1..0000000 --- a/kv-admin/src/components/LoginDialog.vue +++ /dev/null @@ -1,220 +0,0 @@ - - - \ No newline at end of file diff --git a/kv-admin/src/components/PasswordInput.vue b/kv-admin/src/components/PasswordInput.vue deleted file mode 100644 index 55e5657..0000000 --- a/kv-admin/src/components/PasswordInput.vue +++ /dev/null @@ -1,262 +0,0 @@ - - - - - \ No newline at end of file diff --git a/kv-admin/src/components/ResetDevicePasswordDialog.vue b/kv-admin/src/components/ResetDevicePasswordDialog.vue deleted file mode 100644 index e7ef977..0000000 --- a/kv-admin/src/components/ResetDevicePasswordDialog.vue +++ /dev/null @@ -1,274 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/alert-dialog/AlertDialog.vue b/kv-admin/src/components/ui/alert-dialog/AlertDialog.vue deleted file mode 100644 index 266f5c7..0000000 --- a/kv-admin/src/components/ui/alert-dialog/AlertDialog.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/alert-dialog/AlertDialogAction.vue b/kv-admin/src/components/ui/alert-dialog/AlertDialogAction.vue deleted file mode 100644 index 98526b9..0000000 --- a/kv-admin/src/components/ui/alert-dialog/AlertDialogAction.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/alert-dialog/AlertDialogCancel.vue b/kv-admin/src/components/ui/alert-dialog/AlertDialogCancel.vue deleted file mode 100644 index 1c7fd6d..0000000 --- a/kv-admin/src/components/ui/alert-dialog/AlertDialogCancel.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/alert-dialog/AlertDialogContent.vue b/kv-admin/src/components/ui/alert-dialog/AlertDialogContent.vue deleted file mode 100644 index 54237cf..0000000 --- a/kv-admin/src/components/ui/alert-dialog/AlertDialogContent.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/alert-dialog/AlertDialogDescription.vue b/kv-admin/src/components/ui/alert-dialog/AlertDialogDescription.vue deleted file mode 100644 index 6617af9..0000000 --- a/kv-admin/src/components/ui/alert-dialog/AlertDialogDescription.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/alert-dialog/AlertDialogFooter.vue b/kv-admin/src/components/ui/alert-dialog/AlertDialogFooter.vue deleted file mode 100644 index c216b25..0000000 --- a/kv-admin/src/components/ui/alert-dialog/AlertDialogFooter.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/alert-dialog/AlertDialogHeader.vue b/kv-admin/src/components/ui/alert-dialog/AlertDialogHeader.vue deleted file mode 100644 index 00c5aaf..0000000 --- a/kv-admin/src/components/ui/alert-dialog/AlertDialogHeader.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/alert-dialog/AlertDialogTitle.vue b/kv-admin/src/components/ui/alert-dialog/AlertDialogTitle.vue deleted file mode 100644 index 5c48c2d..0000000 --- a/kv-admin/src/components/ui/alert-dialog/AlertDialogTitle.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/alert-dialog/AlertDialogTrigger.vue b/kv-admin/src/components/ui/alert-dialog/AlertDialogTrigger.vue deleted file mode 100644 index 2d546bd..0000000 --- a/kv-admin/src/components/ui/alert-dialog/AlertDialogTrigger.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/alert-dialog/index.js b/kv-admin/src/components/ui/alert-dialog/index.js deleted file mode 100644 index c48e47b..0000000 --- a/kv-admin/src/components/ui/alert-dialog/index.js +++ /dev/null @@ -1,9 +0,0 @@ -export { default as AlertDialog } from "./AlertDialog.vue"; -export { default as AlertDialogAction } from "./AlertDialogAction.vue"; -export { default as AlertDialogCancel } from "./AlertDialogCancel.vue"; -export { default as AlertDialogContent } from "./AlertDialogContent.vue"; -export { default as AlertDialogDescription } from "./AlertDialogDescription.vue"; -export { default as AlertDialogFooter } from "./AlertDialogFooter.vue"; -export { default as AlertDialogHeader } from "./AlertDialogHeader.vue"; -export { default as AlertDialogTitle } from "./AlertDialogTitle.vue"; -export { default as AlertDialogTrigger } from "./AlertDialogTrigger.vue"; diff --git a/kv-admin/src/components/ui/badge/Badge.vue b/kv-admin/src/components/ui/badge/Badge.vue deleted file mode 100644 index c050809..0000000 --- a/kv-admin/src/components/ui/badge/Badge.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/badge/index.js b/kv-admin/src/components/ui/badge/index.js deleted file mode 100644 index 447cf8e..0000000 --- a/kv-admin/src/components/ui/badge/index.js +++ /dev/null @@ -1,24 +0,0 @@ -import { cva } from "class-variance-authority"; - -export { default as Badge } from "./Badge.vue"; - -export const badgeVariants = cva( - "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", - { - variants: { - variant: { - default: - "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90", - secondary: - "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", - destructive: - "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", - outline: - "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", - }, - }, - defaultVariants: { - variant: "default", - }, - }, -); diff --git a/kv-admin/src/components/ui/button/Button.vue b/kv-admin/src/components/ui/button/Button.vue deleted file mode 100644 index 8abe477..0000000 --- a/kv-admin/src/components/ui/button/Button.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/button/index.js b/kv-admin/src/components/ui/button/index.js deleted file mode 100644 index 83eb0ed..0000000 --- a/kv-admin/src/components/ui/button/index.js +++ /dev/null @@ -1,34 +0,0 @@ -import { cva } from "class-variance-authority"; - -export { default as Button } from "./Button.vue"; - -export const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", - { - variants: { - variant: { - default: - "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", - destructive: - "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", - outline: - "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", - secondary: - "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", - ghost: - "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", - link: "text-primary underline-offset-4 hover:underline", - }, - size: { - default: "h-9 px-4 py-2 has-[>svg]:px-3", - sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", - lg: "h-10 rounded-md px-6 has-[>svg]:px-4", - icon: "size-9", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - }, -); diff --git a/kv-admin/src/components/ui/card/Card.vue b/kv-admin/src/components/ui/card/Card.vue deleted file mode 100644 index 16920e4..0000000 --- a/kv-admin/src/components/ui/card/Card.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/card/CardAction.vue b/kv-admin/src/components/ui/card/CardAction.vue deleted file mode 100644 index 4c13362..0000000 --- a/kv-admin/src/components/ui/card/CardAction.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/card/CardContent.vue b/kv-admin/src/components/ui/card/CardContent.vue deleted file mode 100644 index f54f541..0000000 --- a/kv-admin/src/components/ui/card/CardContent.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/card/CardDescription.vue b/kv-admin/src/components/ui/card/CardDescription.vue deleted file mode 100644 index 199875d..0000000 --- a/kv-admin/src/components/ui/card/CardDescription.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/card/CardFooter.vue b/kv-admin/src/components/ui/card/CardFooter.vue deleted file mode 100644 index a28c159..0000000 --- a/kv-admin/src/components/ui/card/CardFooter.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/card/CardHeader.vue b/kv-admin/src/components/ui/card/CardHeader.vue deleted file mode 100644 index cc387d1..0000000 --- a/kv-admin/src/components/ui/card/CardHeader.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/card/CardTitle.vue b/kv-admin/src/components/ui/card/CardTitle.vue deleted file mode 100644 index bb88bf0..0000000 --- a/kv-admin/src/components/ui/card/CardTitle.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/card/index.js b/kv-admin/src/components/ui/card/index.js deleted file mode 100644 index 409685b..0000000 --- a/kv-admin/src/components/ui/card/index.js +++ /dev/null @@ -1,7 +0,0 @@ -export { default as Card } from "./Card.vue"; -export { default as CardAction } from "./CardAction.vue"; -export { default as CardContent } from "./CardContent.vue"; -export { default as CardDescription } from "./CardDescription.vue"; -export { default as CardFooter } from "./CardFooter.vue"; -export { default as CardHeader } from "./CardHeader.vue"; -export { default as CardTitle } from "./CardTitle.vue"; diff --git a/kv-admin/src/components/ui/checkbox/Checkbox.vue b/kv-admin/src/components/ui/checkbox/Checkbox.vue deleted file mode 100644 index 32519de..0000000 --- a/kv-admin/src/components/ui/checkbox/Checkbox.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/checkbox/index.js b/kv-admin/src/components/ui/checkbox/index.js deleted file mode 100644 index 75be342..0000000 --- a/kv-admin/src/components/ui/checkbox/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as Checkbox } from "./Checkbox.vue"; diff --git a/kv-admin/src/components/ui/dialog/Dialog.vue b/kv-admin/src/components/ui/dialog/Dialog.vue deleted file mode 100644 index c261c6f..0000000 --- a/kv-admin/src/components/ui/dialog/Dialog.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/dialog/DialogClose.vue b/kv-admin/src/components/ui/dialog/DialogClose.vue deleted file mode 100644 index 80f6f53..0000000 --- a/kv-admin/src/components/ui/dialog/DialogClose.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/dialog/DialogContent.vue b/kv-admin/src/components/ui/dialog/DialogContent.vue deleted file mode 100644 index 50befa5..0000000 --- a/kv-admin/src/components/ui/dialog/DialogContent.vue +++ /dev/null @@ -1,57 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/dialog/DialogDescription.vue b/kv-admin/src/components/ui/dialog/DialogDescription.vue deleted file mode 100644 index b981e8e..0000000 --- a/kv-admin/src/components/ui/dialog/DialogDescription.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/dialog/DialogFooter.vue b/kv-admin/src/components/ui/dialog/DialogFooter.vue deleted file mode 100644 index eee552a..0000000 --- a/kv-admin/src/components/ui/dialog/DialogFooter.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/dialog/DialogHeader.vue b/kv-admin/src/components/ui/dialog/DialogHeader.vue deleted file mode 100644 index 91194b0..0000000 --- a/kv-admin/src/components/ui/dialog/DialogHeader.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/dialog/DialogOverlay.vue b/kv-admin/src/components/ui/dialog/DialogOverlay.vue deleted file mode 100644 index e47c602..0000000 --- a/kv-admin/src/components/ui/dialog/DialogOverlay.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/dialog/DialogScrollContent.vue b/kv-admin/src/components/ui/dialog/DialogScrollContent.vue deleted file mode 100644 index 95cbf42..0000000 --- a/kv-admin/src/components/ui/dialog/DialogScrollContent.vue +++ /dev/null @@ -1,71 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/dialog/DialogTitle.vue b/kv-admin/src/components/ui/dialog/DialogTitle.vue deleted file mode 100644 index 49cda6f..0000000 --- a/kv-admin/src/components/ui/dialog/DialogTitle.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/dialog/DialogTrigger.vue b/kv-admin/src/components/ui/dialog/DialogTrigger.vue deleted file mode 100644 index 2938e30..0000000 --- a/kv-admin/src/components/ui/dialog/DialogTrigger.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/dialog/index.js b/kv-admin/src/components/ui/dialog/index.js deleted file mode 100644 index 6c411de..0000000 --- a/kv-admin/src/components/ui/dialog/index.js +++ /dev/null @@ -1,10 +0,0 @@ -export { default as Dialog } from "./Dialog.vue"; -export { default as DialogClose } from "./DialogClose.vue"; -export { default as DialogContent } from "./DialogContent.vue"; -export { default as DialogDescription } from "./DialogDescription.vue"; -export { default as DialogFooter } from "./DialogFooter.vue"; -export { default as DialogHeader } from "./DialogHeader.vue"; -export { default as DialogOverlay } from "./DialogOverlay.vue"; -export { default as DialogScrollContent } from "./DialogScrollContent.vue"; -export { default as DialogTitle } from "./DialogTitle.vue"; -export { default as DialogTrigger } from "./DialogTrigger.vue"; diff --git a/kv-admin/src/components/ui/dropdown-menu/DropdownItem.vue b/kv-admin/src/components/ui/dropdown-menu/DropdownItem.vue deleted file mode 100644 index 48e8abf..0000000 --- a/kv-admin/src/components/ui/dropdown-menu/DropdownItem.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - \ No newline at end of file diff --git a/kv-admin/src/components/ui/dropdown-menu/DropdownMenu.vue b/kv-admin/src/components/ui/dropdown-menu/DropdownMenu.vue deleted file mode 100644 index 86333fb..0000000 --- a/kv-admin/src/components/ui/dropdown-menu/DropdownMenu.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - \ No newline at end of file diff --git a/kv-admin/src/components/ui/input/Input.vue b/kv-admin/src/components/ui/input/Input.vue deleted file mode 100644 index dc16a12..0000000 --- a/kv-admin/src/components/ui/input/Input.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/input/index.js b/kv-admin/src/components/ui/input/index.js deleted file mode 100644 index 110f046..0000000 --- a/kv-admin/src/components/ui/input/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as Input } from "./Input.vue"; diff --git a/kv-admin/src/components/ui/label/Label.vue b/kv-admin/src/components/ui/label/Label.vue deleted file mode 100644 index b20aec0..0000000 --- a/kv-admin/src/components/ui/label/Label.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/label/index.js b/kv-admin/src/components/ui/label/index.js deleted file mode 100644 index 38eaa35..0000000 --- a/kv-admin/src/components/ui/label/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as Label } from "./Label.vue"; diff --git a/kv-admin/src/components/ui/select/Select.vue b/kv-admin/src/components/ui/select/Select.vue deleted file mode 100644 index b2cab62..0000000 --- a/kv-admin/src/components/ui/select/Select.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/SelectContent.vue b/kv-admin/src/components/ui/select/SelectContent.vue deleted file mode 100644 index 459a179..0000000 --- a/kv-admin/src/components/ui/select/SelectContent.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/SelectGroup.vue b/kv-admin/src/components/ui/select/SelectGroup.vue deleted file mode 100644 index eecc39b..0000000 --- a/kv-admin/src/components/ui/select/SelectGroup.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/SelectItem.vue b/kv-admin/src/components/ui/select/SelectItem.vue deleted file mode 100644 index 18edeca..0000000 --- a/kv-admin/src/components/ui/select/SelectItem.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/SelectItemText.vue b/kv-admin/src/components/ui/select/SelectItemText.vue deleted file mode 100644 index eb87548..0000000 --- a/kv-admin/src/components/ui/select/SelectItemText.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/SelectLabel.vue b/kv-admin/src/components/ui/select/SelectLabel.vue deleted file mode 100644 index adb66ad..0000000 --- a/kv-admin/src/components/ui/select/SelectLabel.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/SelectScrollDownButton.vue b/kv-admin/src/components/ui/select/SelectScrollDownButton.vue deleted file mode 100644 index 6932136..0000000 --- a/kv-admin/src/components/ui/select/SelectScrollDownButton.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/SelectScrollUpButton.vue b/kv-admin/src/components/ui/select/SelectScrollUpButton.vue deleted file mode 100644 index c7a493f..0000000 --- a/kv-admin/src/components/ui/select/SelectScrollUpButton.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/SelectSeparator.vue b/kv-admin/src/components/ui/select/SelectSeparator.vue deleted file mode 100644 index 34f2f59..0000000 --- a/kv-admin/src/components/ui/select/SelectSeparator.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/SelectTrigger.vue b/kv-admin/src/components/ui/select/SelectTrigger.vue deleted file mode 100644 index 4bd93a8..0000000 --- a/kv-admin/src/components/ui/select/SelectTrigger.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/SelectValue.vue b/kv-admin/src/components/ui/select/SelectValue.vue deleted file mode 100644 index db9807f..0000000 --- a/kv-admin/src/components/ui/select/SelectValue.vue +++ /dev/null @@ -1,15 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/select/index.js b/kv-admin/src/components/ui/select/index.js deleted file mode 100644 index d911c4e..0000000 --- a/kv-admin/src/components/ui/select/index.js +++ /dev/null @@ -1,11 +0,0 @@ -export { default as Select } from "./Select.vue"; -export { default as SelectContent } from "./SelectContent.vue"; -export { default as SelectGroup } from "./SelectGroup.vue"; -export { default as SelectItem } from "./SelectItem.vue"; -export { default as SelectItemText } from "./SelectItemText.vue"; -export { default as SelectLabel } from "./SelectLabel.vue"; -export { default as SelectScrollDownButton } from "./SelectScrollDownButton.vue"; -export { default as SelectScrollUpButton } from "./SelectScrollUpButton.vue"; -export { default as SelectSeparator } from "./SelectSeparator.vue"; -export { default as SelectTrigger } from "./SelectTrigger.vue"; -export { default as SelectValue } from "./SelectValue.vue"; diff --git a/kv-admin/src/components/ui/separator/Separator.vue b/kv-admin/src/components/ui/separator/Separator.vue deleted file mode 100644 index 680a1d2..0000000 --- a/kv-admin/src/components/ui/separator/Separator.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/separator/index.js b/kv-admin/src/components/ui/separator/index.js deleted file mode 100644 index aae7f1a..0000000 --- a/kv-admin/src/components/ui/separator/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as Separator } from "./Separator.vue"; diff --git a/kv-admin/src/components/ui/sonner/Sonner.vue b/kv-admin/src/components/ui/sonner/Sonner.vue deleted file mode 100644 index 8802e9a..0000000 --- a/kv-admin/src/components/ui/sonner/Sonner.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/sonner/index.js b/kv-admin/src/components/ui/sonner/index.js deleted file mode 100644 index 39a59dd..0000000 --- a/kv-admin/src/components/ui/sonner/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as Toaster } from "./Sonner.vue"; diff --git a/kv-admin/src/components/ui/table/Table.vue b/kv-admin/src/components/ui/table/Table.vue deleted file mode 100644 index 71bd0a9..0000000 --- a/kv-admin/src/components/ui/table/Table.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/table/TableBody.vue b/kv-admin/src/components/ui/table/TableBody.vue deleted file mode 100644 index 3cfac53..0000000 --- a/kv-admin/src/components/ui/table/TableBody.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/table/TableCaption.vue b/kv-admin/src/components/ui/table/TableCaption.vue deleted file mode 100644 index 2a4488e..0000000 --- a/kv-admin/src/components/ui/table/TableCaption.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/table/TableCell.vue b/kv-admin/src/components/ui/table/TableCell.vue deleted file mode 100644 index aa0faef..0000000 --- a/kv-admin/src/components/ui/table/TableCell.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/table/TableEmpty.vue b/kv-admin/src/components/ui/table/TableEmpty.vue deleted file mode 100644 index 0a94d54..0000000 --- a/kv-admin/src/components/ui/table/TableEmpty.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/table/TableFooter.vue b/kv-admin/src/components/ui/table/TableFooter.vue deleted file mode 100644 index 89c5ac1..0000000 --- a/kv-admin/src/components/ui/table/TableFooter.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/table/TableHead.vue b/kv-admin/src/components/ui/table/TableHead.vue deleted file mode 100644 index 1e8dad9..0000000 --- a/kv-admin/src/components/ui/table/TableHead.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/table/TableHeader.vue b/kv-admin/src/components/ui/table/TableHeader.vue deleted file mode 100644 index 616e4dc..0000000 --- a/kv-admin/src/components/ui/table/TableHeader.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/table/TableRow.vue b/kv-admin/src/components/ui/table/TableRow.vue deleted file mode 100644 index 85f521c..0000000 --- a/kv-admin/src/components/ui/table/TableRow.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/table/index.js b/kv-admin/src/components/ui/table/index.js deleted file mode 100644 index 0afab4c..0000000 --- a/kv-admin/src/components/ui/table/index.js +++ /dev/null @@ -1,9 +0,0 @@ -export { default as Table } from "./Table.vue"; -export { default as TableBody } from "./TableBody.vue"; -export { default as TableCaption } from "./TableCaption.vue"; -export { default as TableCell } from "./TableCell.vue"; -export { default as TableEmpty } from "./TableEmpty.vue"; -export { default as TableFooter } from "./TableFooter.vue"; -export { default as TableHead } from "./TableHead.vue"; -export { default as TableHeader } from "./TableHeader.vue"; -export { default as TableRow } from "./TableRow.vue"; diff --git a/kv-admin/src/components/ui/table/utils.js b/kv-admin/src/components/ui/table/utils.js deleted file mode 100644 index ee61875..0000000 --- a/kv-admin/src/components/ui/table/utils.js +++ /dev/null @@ -1,7 +0,0 @@ -import { isFunction } from "@tanstack/vue-table"; - -export function valueUpdater(updaterOrValue, ref) { - ref.value = isFunction(updaterOrValue) - ? updaterOrValue(ref.value) - : updaterOrValue; -} diff --git a/kv-admin/src/components/ui/tabs/Tabs.vue b/kv-admin/src/components/ui/tabs/Tabs.vue deleted file mode 100644 index 31ba139..0000000 --- a/kv-admin/src/components/ui/tabs/Tabs.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/tabs/TabsContent.vue b/kv-admin/src/components/ui/tabs/TabsContent.vue deleted file mode 100644 index b9331fd..0000000 --- a/kv-admin/src/components/ui/tabs/TabsContent.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/tabs/TabsList.vue b/kv-admin/src/components/ui/tabs/TabsList.vue deleted file mode 100644 index 791ab3d..0000000 --- a/kv-admin/src/components/ui/tabs/TabsList.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/tabs/TabsTrigger.vue b/kv-admin/src/components/ui/tabs/TabsTrigger.vue deleted file mode 100644 index 03e10df..0000000 --- a/kv-admin/src/components/ui/tabs/TabsTrigger.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/kv-admin/src/components/ui/tabs/index.js b/kv-admin/src/components/ui/tabs/index.js deleted file mode 100644 index 3b3741b..0000000 --- a/kv-admin/src/components/ui/tabs/index.js +++ /dev/null @@ -1,4 +0,0 @@ -export { default as Tabs } from "./Tabs.vue"; -export { default as TabsContent } from "./TabsContent.vue"; -export { default as TabsList } from "./TabsList.vue"; -export { default as TabsTrigger } from "./TabsTrigger.vue"; diff --git a/kv-admin/src/composables/useOAuthCallback.js b/kv-admin/src/composables/useOAuthCallback.js deleted file mode 100644 index f01d598..0000000 --- a/kv-admin/src/composables/useOAuthCallback.js +++ /dev/null @@ -1,126 +0,0 @@ -import { onMounted, onUnmounted } from 'vue' -import { useRoute, useRouter } from 'vue-router' -import { useAccountStore } from '@/stores/account' -import { toast } from 'vue-sonner' - -/** - * 处理OAuth回调 - * 检查URL参数中是否有OAuth回调信息 - */ -export function useOAuthCallback() { - const route = useRoute() - const router = useRouter() - const accountStore = useAccountStore() - - const handleOAuthCallback = async () => { - const { token, provider, success, error } = route.query - - // 检查是否是OAuth回调 - if (!success && !error) { - return - } - - // 处理成功回调 - if (success === 'true' && token) { - try { - // 保存token到localStorage - localStorage.setItem('auth_token', token) - localStorage.setItem('auth_provider', provider) - - // 登录到store - await accountStore.login(token) - - // 显示成功提示 - toast.success('登录成功', { - description: `已通过 ${provider} 登录` - }) - - // 清除URL参数 - router.replace({ query: {} }) - - // 触发storage事件,通知其他窗口 - window.dispatchEvent(new StorageEvent('storage', { - key: 'auth_token', - newValue: token, - url: window.location.href - })) - - // 如果是在新窗口中打开的OAuth回调,自动关闭窗口 - if (window.opener) { - // 通知父窗口登录成功 - window.opener.postMessage({ - type: 'oauth_success', - token, - provider - }, window.location.origin) - - // 延迟关闭窗口,确保消息已发送 - setTimeout(() => { - window.close() - }, 1000) - } - - } catch (err) { - toast.error('登录失败', { - description: err.message || '处理登录信息时出错' - }) - } - } - - // 处理错误回调 - if (success === 'false' || error) { - const errorMessages = { - 'invalid_state': 'State验证失败,可能存在安全风险', - 'access_denied': '用户拒绝了授权请求', - 'temporarily_unavailable': '服务暂时不可用,请稍后重试' - } - - const errorMsg = errorMessages[error] || error || '登录过程中出现错误' - - toast.error('登录失败', { - description: errorMsg - }) - - // 清除URL参数 - router.replace({ query: {} }) - - // 如果是在新窗口中打开的OAuth回调,自动关闭窗口 - if (window.opener) { - // 通知父窗口登录失败 - window.opener.postMessage({ - type: 'oauth_error', - error: errorMsg - }, window.location.origin) - - // 延迟关闭窗口 - setTimeout(() => { - window.close() - }, 1000) - } - } - } - - onMounted(() => { - handleOAuthCallback() - }) - - // 监听storage事件,处理其他标签页的登录 - const handleStorageChange = (e) => { - if (e.key === 'auth_token' && e.newValue) { - // 其他标签页已登录,刷新当前页面的状态 - accountStore.login(e.newValue) - } - } - - onMounted(() => { - window.addEventListener('storage', handleStorageChange) - }) - - onUnmounted(() => { - window.removeEventListener('storage', handleStorageChange) - }) - - return { - handleOAuthCallback - } -} \ No newline at end of file diff --git a/kv-admin/src/lib/api.js b/kv-admin/src/lib/api.js deleted file mode 100644 index cc03606..0000000 --- a/kv-admin/src/lib/api.js +++ /dev/null @@ -1,533 +0,0 @@ -const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3030' -const SITE_KEY = import.meta.env.VITE_SITE_KEY || '' - -class ApiClient { - constructor(baseUrl, siteKey) { - this.baseUrl = baseUrl - this.siteKey = siteKey - } - - async fetch(endpoint, options = {}) { - const headers = { - 'Content-Type': 'application/json', - 'x-site-key': this.siteKey, - ...options.headers, - } - - const response = await fetch(`${this.baseUrl}${endpoint}`, { - ...options, - headers, - }) - - if (!response.ok) { - const error = await response.json().catch(() => ({ message: 'Unknown error' })) - throw new Error(error.message || `HTTP ${response.status}`) - } - - if (response.status === 204) { - return {} - } - - return response.json() - } - - // 带认证的fetch - async authenticatedFetch(endpoint, options = {}, token = null) { - const headers = { - ...options.headers, - } - - // 如果提供了token,添加Authorization头 - if (token) { - headers['Authorization'] = `Bearer ${token}` - } - - return this.fetch(endpoint, { - ...options, - headers, - }) - } - - // 应用相关 API - async getApps(params = {}) { - const query = new URLSearchParams(params).toString() - return this.fetch(`/apps${query ? `?${query}` : ''}`) - } - - async getApp(appId) { - return this.fetch(`/apps/info/${appId}`) - } - - async getAppInstallations(appId, deviceUuid, params = {}) { - const query = new URLSearchParams(params).toString() - return this.fetch(`/apps/info/${appId}/device-installations${query ? `?${query}` : ''}`, { - headers: { - 'x-device-uuid': deviceUuid, - }, - }) - } - - // Token 管理 API - async getDeviceTokens(deviceUuid, options = {}) { - const params = new URLSearchParams({ - uuid: deviceUuid, - }); - - return this.fetch(`/apps/tokens?${params}`); - } - - async revokeToken(targetToken, authOptions = {}) { - const { deviceUuid, password, usePathParam = true, bearerToken } = authOptions; - - if (usePathParam) { - // 使用路径参数方式 (推荐) - const headers = {}; - - if (bearerToken) { - headers['Authorization'] = `Bearer ${bearerToken}`; - } else if (deviceUuid) { - headers['x-device-uuid'] = deviceUuid; - if (password) { - headers['x-device-password'] = password; - } - } - - return this.fetch(`/apps/tokens/${targetToken}`, { - method: 'DELETE', - headers, - }); - } else { - // 使用查询参数方式 (向后兼容) - const params = new URLSearchParams({ token: targetToken }); - const headers = {}; - - if (bearerToken) { - headers['Authorization'] = `Bearer ${bearerToken}`; - } else if (deviceUuid) { - headers['x-device-uuid'] = deviceUuid; - if (password) { - headers['x-device-password'] = password; - } - } - - return this.fetch(`/apps/tokens?${params}`, { - method: 'DELETE', - headers, - }); - } - } - - // 应用安装接口 (对应后端的 /apps/devices/:uuid/install/:appId) - async authorizeApp(appId, deviceUuid, options = {}) { - const { password, note, token } = options; - - const headers = { - 'x-device-uuid': deviceUuid, - }; - - - if (token) { - headers['Authorization'] = `Bearer ${token}`; - } - - // 使用新的安装接口 - return this.fetch(`/apps/devices/${deviceUuid}/install/${appId}?password=${password}`, { - method: 'POST', - headers, - body: JSON.stringify({ note: note || '应用授权' }), - }); - } - - // 设备级别的应用卸载,使用新的 uninstall 接口 - async revokeDeviceToken(deviceUuid, installId, password = null, token = null) { - const params = new URLSearchParams({ uuid: deviceUuid }); - const headers = {}; - - if (password) { - params.set('password', password); - } - - if (token) { - headers['Authorization'] = `Bearer ${token}`; - } - - return this.fetch(`/apps/devices/${deviceUuid}/uninstall/${installId}?${params}`, { - method: 'DELETE', - headers, - }); - } - - // 设备密码管理 API - async setDevicePassword(deviceUuid, data, token = null) { - const { newPassword, currentPassword, passwordHint } = data; - - // 检查设备是否已设置密码 - const deviceInfo = await this.getDeviceInfo(deviceUuid); - const hasPassword = deviceInfo.hasPassword; - - if (hasPassword) { - // 使用PUT修改密码 - const params = new URLSearchParams(); - params.set('uuid', deviceUuid); - params.set('newPassword', newPassword); - if (currentPassword) { - params.set('currentPassword', currentPassword); - } - if (passwordHint !== undefined) { - params.set('passwordHint', passwordHint); - } - - const headers = {}; - if (token) { - headers['Authorization'] = `Bearer ${token}`; - } - - return this.fetch(`/devices/${deviceUuid}/password?${params}`, { - method: 'PUT', - headers, - }); - } else { - // 使用POST初次设置密码 - const params = new URLSearchParams(); - params.set('newPassword', newPassword); - if (passwordHint !== undefined) { - params.set('passwordHint', passwordHint); - } - - return this.fetch(`/devices/${deviceUuid}/password?${params}`, { - method: 'POST', - }); - } - } - - async deleteDevicePassword(deviceUuid, password, token = null) { - const params = new URLSearchParams({ uuid: deviceUuid }); - const headers = {}; - - // 如果提供了账户token,使用JWT认证 - if (token) { - headers['Authorization'] = `Bearer ${token}`; - } else if (password) { - params.set('password', password); - } - - return this.fetch(`/devices/${deviceUuid}/password?${params}`, { - method: 'DELETE', - headers, - }); - } - - async setDevicePasswordHint(deviceUuid, hint, password = null, token = null) { - return this.authenticatedFetch(`/devices/${deviceUuid}/password-hint`, { - method: 'PUT', - body: JSON.stringify({ hint, password }), - }, token) - } - - async getDevicePasswordHint(deviceUuid) { - return this.fetch(`/devices/${deviceUuid}/password-hint`) - } - - // 设备授权相关 API - async bindDeviceCode(deviceCode, token) { - return this.fetch('/auth/device/bind', { - method: 'POST', - body: JSON.stringify({ device_code: deviceCode, token }), - }) - } - - async getDeviceCodeStatus(deviceCode) { - return this.fetch(`/auth/device/status?device_code=${deviceCode}`) - } - - // KV 存储管理 API - async listKVItems(token, params = {}) { - const query = new URLSearchParams(params).toString() - return this.fetch(`/kv${query ? `?${query}` : ''}`, { - headers: { 'x-app-token': token } - }) - } - - async getKVItem(token, key) { - return this.fetch(`/kv/${encodeURIComponent(key)}`, { - headers: { 'x-app-token': token } - }) - } - - async setKVItem(token, key, value) { - return this.fetch(`/kv/${encodeURIComponent(key)}`, { - method: 'POST', - headers: { 'x-app-token': token }, - body: JSON.stringify(value), - }) - } - - async deleteKVItem(token, key) { - return this.fetch(`/kv/${encodeURIComponent(key)}`, { - method: 'DELETE', - headers: { 'x-app-token': token } - }) - } - - async getKVKeys(token, pattern = '*') { - return this.fetch(`/kv/_keys?pattern=${encodeURIComponent(pattern)}`, { - headers: { 'x-app-token': token } - }) - } - - // 设备信息 API - async getDeviceInfo(deviceUuid) { - return this.fetch(`/devices/${deviceUuid}`) - } - - // 获取设备应用列表 API (公开接口,无需认证) - async getDeviceApps(deviceUuid) { - return this.fetch(`/apps/devices/${deviceUuid}/apps`) - } - - // 密码提示管理 API - async getPasswordHint(deviceUuid) { - try { - const response = await this.fetch(`/devices/${deviceUuid}`) - return { hint: response.device?.passwordHint || '' } - } catch (error) { - // 如果接口不存在,返回空提示 - return { hint: '' } - } - } - - async setPasswordHint(deviceUuid, hint, password) { - try { - return await this.fetch(`/devices/${deviceUuid}/password-hint?password=${encodeURIComponent(password)}`, { - method: 'PUT', - headers: { - 'x-device-uuid': deviceUuid, - }, - body: JSON.stringify({ passwordHint: hint }), - }) - } catch (error) { - // 如果接口不存在,忽略错误 - console.log('Password hint API not available') - return { success: false } - } - } - - // 账户相关 API - async getOAuthProviders() { - return this.fetch('/accounts/oauth/providers') - } - - async getAccountProfile(token) { - return this.fetch('/accounts/profile', { - headers: { 'Authorization': `Bearer ${token}` } - }) - } - - async getAccountDevices(token) { - return this.fetch('/accounts/devices', { - headers: { 'Authorization': `Bearer ${token}` } - }) - } - - async bindDevice(token, deviceUuid) { - return this.fetch('/accounts/devices/bind', { - method: 'POST', - headers: { 'Authorization': `Bearer ${token}` }, - body: JSON.stringify({ uuid: deviceUuid }), - }) - } - - async unbindDevice(token, deviceUuid) { - return this.fetch('/accounts/devices/unbind', { - method: 'POST', - headers: { 'Authorization': `Bearer ${token}` }, - body: JSON.stringify({ uuid: deviceUuid }), - }) - } - - async getDeviceAccount(deviceUuid) { - return this.fetch(`/accounts/device/${deviceUuid}/account`) - } - - // 绑定设备到当前账户 - async bindDeviceToAccount(token, deviceUuid) { - return this.authenticatedFetch('/accounts/devices/bind', { - method: 'POST', - body: JSON.stringify({ uuid: deviceUuid }), - }, token) - } - - // 解绑设备 - async unbindDeviceFromAccount(token, deviceUuid) { - return this.authenticatedFetch('/accounts/devices/unbind', { - method: 'POST', - body: JSON.stringify({ uuid: deviceUuid }), - }, token) - } - - // 批量解绑设备 - async batchUnbindDevices(token, deviceUuids) { - return this.authenticatedFetch('/accounts/devices/unbind', { - method: 'POST', - body: JSON.stringify({ uuids: deviceUuids }), - }, token) - } - - // 设备名称管理 API - async setDeviceName(deviceUuid, name, password = null, token = null) { - const headers = { - 'x-device-uuid': deviceUuid, - }; - if (token) { - headers['Authorization'] = `Bearer ${token}`; - } - if (password) { - headers['x-device-password'] = password; - } - - return this.fetch(`/devices/${deviceUuid}/name`, { - method: 'PUT', - headers, - body: JSON.stringify({ name }), - }); - } - - // 修改设备密码 API - async updateDevicePassword(deviceUuid, currentPassword, newPassword, passwordHint = null, token = null) { - const headers = { - 'x-device-uuid': deviceUuid, - }; - - // 如果提供了账户token,使用JWT认证(账户拥有者无需当前密码) - if (token) { - headers['Authorization'] = `Bearer ${token}`; - } else if (currentPassword) { - headers['x-device-password'] = currentPassword; - } - - const body = { newPassword, passwordHint }; - // 只有在非账户拥有者时才需要发送当前密码 - if (!token && currentPassword) { - body.currentPassword = currentPassword; - } - - return this.fetch(`/devices/${deviceUuid}/password`, { - method: 'PUT', - headers, - body: JSON.stringify(body), - }); - } - - // 验证设备密码 API - async verifyDevicePassword(deviceUuid, password) { - return this.fetch(`/devices/${deviceUuid}`, { - method: 'GET', - headers: { - 'x-device-uuid': deviceUuid, - 'x-device-password': password, - }, - }); - } - - // 设备注册 API - async registerDevice(uuid, deviceName, token = null) { - return this.authenticatedFetch('/devices', { - method: 'POST', - body: JSON.stringify({ uuid, deviceName }), - }, token) - } - - // 账户拥有者重置设备密码 API - async resetDevicePasswordAsOwner(deviceUuid, newPassword, passwordHint = null, token) { - return this.fetch(`/devices/${deviceUuid}/password`, { - method: 'PUT', - headers: { - 'Authorization': `Bearer ${token}`, - 'x-device-uuid': deviceUuid, - }, - body: JSON.stringify({ newPassword, passwordHint }), - }); - } - - // 兼容性方法 - 保持旧的API调用方式 - async getTokens(deviceUuid, options = {}) { - return this.getDeviceTokens(deviceUuid, options); - } - - async deleteToken(targetToken, deviceUuid = null) { - // 向后兼容的删除方法 - return this.revokeToken(targetToken, { deviceUuid, usePathParam: true }); - } - - // 便捷方法:使用设备UUID和密码删除token - async revokeTokenByDevice(targetToken, deviceUuid, password = null) { - return this.revokeToken(targetToken, { - deviceUuid, - password, - usePathParam: true - }); - } - - // 便捷方法:使用账户token删除token - async revokeTokenByAccount(targetToken, bearerToken) { - return this.revokeToken(targetToken, { - bearerToken, - usePathParam: true - }); - } - - // 便捷方法:应用自撤销 - async revokeOwnToken(targetToken) { - return this.fetch(`/apps/tokens/${targetToken}`, { - method: 'DELETE', - headers: { - 'x-app-token': targetToken, - }, - }); - } - - // 新的便捷方法 - async getTokensWithAuth(authType, authValue, options = {}) { - const headers = {}; - const params = new URLSearchParams(options); - - switch (authType) { - case 'uuid': - headers['x-device-uuid'] = authValue; - params.set('uuid', authValue); - break; - case 'token': - headers['x-app-token'] = authValue; - break; - case 'bearer': - headers['Authorization'] = `Bearer ${authValue}`; - break; - } - - return this.fetch(`/apps/tokens?${params}`, { headers }); - } - - async revokeTokenWithAuth(targetToken, authType, authValue) { - const headers = {}; - const params = new URLSearchParams({ token: targetToken }); - - switch (authType) { - case 'uuid': - headers['x-device-uuid'] = authValue; - break; - case 'token': - headers['x-app-token'] = authValue; - break; - case 'bearer': - headers['Authorization'] = `Bearer ${authValue}`; - break; - } - - return this.fetch(`/apps/tokens?${params}`, { - method: 'DELETE', - headers, - }); - } -} - -export const apiClient = new ApiClient(API_BASE_URL, SITE_KEY) diff --git a/kv-admin/src/lib/axios.js b/kv-admin/src/lib/axios.js deleted file mode 100644 index 67a6b02..0000000 --- a/kv-admin/src/lib/axios.js +++ /dev/null @@ -1,37 +0,0 @@ -import axios from 'axios' - -const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3030' -const SITE_KEY = import.meta.env.VITE_SITE_KEY || '' - -// 创建 axios 实例 -const axiosInstance = axios.create({ - baseURL: API_BASE_URL, - timeout: 30000, - headers: { - 'Content-Type': 'application/json', - 'x-site-key': SITE_KEY, - }, -}) - -// 请求拦截器 -axiosInstance.interceptors.request.use( - (config) => { - return config - }, - (error) => { - return Promise.reject(error) - } -) - -// 响应拦截器 -axiosInstance.interceptors.response.use( - (response) => { - return response.data - }, - (error) => { - const message = error.response?.data?.message || error.message || 'Unknown error' - return Promise.reject(new Error(message)) - } -) - -export default axiosInstance diff --git a/kv-admin/src/lib/deviceStore.js b/kv-admin/src/lib/deviceStore.js deleted file mode 100644 index 7877e02..0000000 --- a/kv-admin/src/lib/deviceStore.js +++ /dev/null @@ -1,191 +0,0 @@ -// 生成 UUID v4 -export function generateUUID() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - const r = Math.random() * 16 | 0 - const v = c === 'x' ? r : (r & 0x3 | 0x8) - return v.toString(16) - }) -} - -// 设备 UUID 管理 - 使用多种缓存策略确保UUID不丢失 -export const deviceStore = { - // 存储键名 - STORAGE_KEY: 'device_uuid', - BACKUP_KEY: 'device_uuid_backup', - SESSION_KEY: 'device_uuid_session', - - // 获取当前设备 UUID(从多个存储位置尝试读取) - getDeviceUuid() { - // 1. 首先从 localStorage 获取 - let uuid = localStorage.getItem(this.STORAGE_KEY) - - // 2. 如果没有,尝试从备份位置获取 - if (!uuid) { - uuid = localStorage.getItem(this.BACKUP_KEY) - if (uuid) { - // 恢复到主存储位置 - this.setDeviceUuid(uuid) - } - } - - // 3. 如果还没有,尝试从 sessionStorage 获取 - if (!uuid) { - uuid = sessionStorage.getItem(this.SESSION_KEY) - if (uuid) { - // 恢复到主存储位置 - this.setDeviceUuid(uuid) - } - } - - // 4. 如果还没有,尝试从 cookie 获取(如果有的话) - if (!uuid) { - uuid = this.getFromCookie() - if (uuid) { - // 恢复到所有存储位置 - this.setDeviceUuid(uuid) - } - } - - return uuid - }, - - // 设置设备 UUID(同时存储到多个位置) - setDeviceUuid(uuid) { - // 1. 存储到 localStorage 主位置 - localStorage.setItem(this.STORAGE_KEY, uuid) - - // 2. 存储到备份位置 - localStorage.setItem(this.BACKUP_KEY, uuid) - - // 3. 存储到 sessionStorage - sessionStorage.setItem(this.SESSION_KEY, uuid) - - // 4. 存储到 cookie(设置较长的过期时间) - this.saveToCookie(uuid) - - // 5. 尝试存储到 IndexedDB(异步) - this.saveToIndexedDB(uuid) - }, - - // 生成并保存新的设备 UUID - generateAndSave() { - const uuid = generateUUID() - this.setDeviceUuid(uuid) - return uuid - }, - - // 获取或生成设备 UUID - getOrGenerate() { - let uuid = this.getDeviceUuid() - if (!uuid) { - uuid = this.generateAndSave() - } else { - // 确保UUID被保存到所有位置 - this.setDeviceUuid(uuid) - } - return uuid - }, - - // 清除设备 UUID(从所有存储位置清除) - clear() { - localStorage.removeItem(this.STORAGE_KEY) - localStorage.removeItem(this.BACKUP_KEY) - sessionStorage.removeItem(this.SESSION_KEY) - this.clearCookie() - this.clearIndexedDB() - }, - - // Cookie 操作 - saveToCookie(uuid) { - try { - const expires = new Date() - expires.setFullYear(expires.getFullYear() + 10) // 10年过期 - document.cookie = `device_uuid=${uuid}; expires=${expires.toUTCString()}; path=/; SameSite=Strict` - } catch (e) { - console.log('Failed to save UUID to cookie:', e) - } - }, - - getFromCookie() { - try { - const match = document.cookie.match(/(?:^|; )device_uuid=([^;]*)/) - return match ? match[1] : null - } catch (e) { - console.log('Failed to get UUID from cookie:', e) - return null - } - }, - - clearCookie() { - try { - document.cookie = 'device_uuid=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;' - } catch (e) { - console.log('Failed to clear UUID cookie:', e) - } - }, - - // IndexedDB 操作(异步,作为额外的备份) - async saveToIndexedDB(uuid) { - try { - const db = await this.openDB() - const transaction = db.transaction(['device'], 'readwrite') - const store = transaction.objectStore('device') - await store.put({ id: 'uuid', value: uuid }) - } catch (e) { - console.log('Failed to save UUID to IndexedDB:', e) - } - }, - - async getFromIndexedDB() { - try { - const db = await this.openDB() - const transaction = db.transaction(['device'], 'readonly') - const store = transaction.objectStore('device') - const result = await store.get('uuid') - return result?.value || null - } catch (e) { - console.log('Failed to get UUID from IndexedDB:', e) - return null - } - }, - - async clearIndexedDB() { - try { - const db = await this.openDB() - const transaction = db.transaction(['device'], 'readwrite') - const store = transaction.objectStore('device') - await store.delete('uuid') - } catch (e) { - console.log('Failed to clear UUID from IndexedDB:', e) - } - }, - - openDB() { - return new Promise((resolve, reject) => { - const request = indexedDB.open('ClassworksKV', 1) - - request.onerror = () => reject(request.error) - request.onsuccess = () => resolve(request.result) - - request.onupgradeneeded = (event) => { - const db = event.target.result - if (!db.objectStoreNames.contains('device')) { - db.createObjectStore('device', { keyPath: 'id' }) - } - } - }) - }, - - // 尝试从 IndexedDB 恢复 UUID(在初始化时调用) - async tryRestoreFromIndexedDB() { - const uuid = await this.getFromIndexedDB() - if (uuid && !this.getDeviceUuid()) { - this.setDeviceUuid(uuid) - } - } -} - -// 在页面加载时尝试从 IndexedDB 恢复 -if (typeof window !== 'undefined') { - deviceStore.tryRestoreFromIndexedDB() -} diff --git a/kv-admin/src/lib/tokenStore.js b/kv-admin/src/lib/tokenStore.js deleted file mode 100644 index 7d6e469..0000000 --- a/kv-admin/src/lib/tokenStore.js +++ /dev/null @@ -1,66 +0,0 @@ -// 生成随机设备码 -export function generateDeviceCode() { - const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' - const segments = [] - - for (let i = 0; i < 4; i++) { - let segment = '' - for (let j = 0; j < 4; j++) { - segment += chars[Math.floor(Math.random() * chars.length)] - } - segments.push(segment) - } - - return segments.join('-') -} - -// Token 管理 -export const tokenStore = { - // 获取所有 token - getTokens() { - const tokens = localStorage.getItem('kv_tokens') - return tokens ? JSON.parse(tokens) : [] - }, - - // 添加 token - addToken(token, appName = '') { - const tokens = this.getTokens() - const newToken = { - id: Date.now().toString(), - token, - appName, - deviceCode: generateDeviceCode(), - createdAt: new Date().toISOString(), - lastUsed: new Date().toISOString() - } - tokens.push(newToken) - localStorage.setItem('kv_tokens', JSON.stringify(tokens)) - return newToken - }, - - // 删除 token - removeToken(id) { - const tokens = this.getTokens().filter(t => t.id !== id) - localStorage.setItem('kv_tokens', JSON.stringify(tokens)) - }, - - // 更新 token - updateToken(id, updates) { - const tokens = this.getTokens().map(t => - t.id === id ? { ...t, ...updates } : t - ) - localStorage.setItem('kv_tokens', JSON.stringify(tokens)) - }, - - // 获取当前活跃的 token - getActiveToken() { - const activeId = localStorage.getItem('kv_active_token') - if (!activeId) return null - return this.getTokens().find(t => t.id === activeId) - }, - - // 设置活跃 token - setActiveToken(id) { - localStorage.setItem('kv_active_token', id) - } -} diff --git a/kv-admin/src/lib/utils.js b/kv-admin/src/lib/utils.js deleted file mode 100644 index b20bf01..0000000 --- a/kv-admin/src/lib/utils.js +++ /dev/null @@ -1,6 +0,0 @@ -import { clsx } from "clsx"; -import { twMerge } from "tailwind-merge" - -export function cn(...inputs) { - return twMerge(clsx(inputs)); -} diff --git a/kv-admin/src/main.js b/kv-admin/src/main.js deleted file mode 100644 index 7389876..0000000 --- a/kv-admin/src/main.js +++ /dev/null @@ -1,45 +0,0 @@ -import { createApp } from 'vue' -import { createRouter, createWebHistory } from 'vue-router' -import { createPinia } from 'pinia' -import { routes } from 'vue-router/auto-routes' -import { tokenStore } from './lib/tokenStore' -import { deviceStore } from './lib/deviceStore' -import './style.css' -import App from './App.vue' - -// 检查 URL 参数中的 uuid 并设置到本地存储 -const urlParams = new URLSearchParams(window.location.search) -const urlUuid = urlParams.get('uuid') -if (urlUuid) { - deviceStore.setDeviceUuid(urlUuid) - // 清除 URL 中的 uuid 参数 - urlParams.delete('uuid') - const newUrl = urlParams.toString() - ? `${window.location.pathname}?${urlParams.toString()}` - : window.location.pathname - window.history.replaceState({}, '', newUrl) -} - -const pinia = createPinia() - -const router = createRouter({ - history: createWebHistory(), - routes, -}) - -// Navigation guard for authentication -router.beforeEach((to, _from, next) => { - const requiresAuth = to.meta?.requiresAuth - const activeToken = tokenStore.getActiveToken() - - if (requiresAuth && !activeToken) { - next({ path: '/' }) - } else { - next() - } -}) - -const app = createApp(App) -app.use(pinia) -app.use(router) -app.mount('#app') diff --git a/kv-admin/src/pages/authorize.vue b/kv-admin/src/pages/authorize.vue deleted file mode 100644 index 2526087..0000000 --- a/kv-admin/src/pages/authorize.vue +++ /dev/null @@ -1,493 +0,0 @@ - - - diff --git a/kv-admin/src/pages/device-management.vue b/kv-admin/src/pages/device-management.vue deleted file mode 100644 index ca35341..0000000 --- a/kv-admin/src/pages/device-management.vue +++ /dev/null @@ -1,276 +0,0 @@ - - - diff --git a/kv-admin/src/pages/index.vue b/kv-admin/src/pages/index.vue deleted file mode 100644 index 1ae2d8d..0000000 --- a/kv-admin/src/pages/index.vue +++ /dev/null @@ -1,861 +0,0 @@ - - - \ No newline at end of file diff --git a/kv-admin/src/pages/kv-manager.vue b/kv-admin/src/pages/kv-manager.vue deleted file mode 100644 index ca8713e..0000000 --- a/kv-admin/src/pages/kv-manager.vue +++ /dev/null @@ -1,615 +0,0 @@ - - - - - diff --git a/kv-admin/src/pages/password-manager.vue b/kv-admin/src/pages/password-manager.vue deleted file mode 100644 index 67d07be..0000000 --- a/kv-admin/src/pages/password-manager.vue +++ /dev/null @@ -1,615 +0,0 @@ - - - \ No newline at end of file diff --git a/kv-admin/src/stores/account.js b/kv-admin/src/stores/account.js deleted file mode 100644 index 3aed301..0000000 --- a/kv-admin/src/stores/account.js +++ /dev/null @@ -1,116 +0,0 @@ -import { defineStore } from 'pinia' -import { ref, computed } from 'vue' -import { apiClient } from '@/lib/api' - -export const useAccountStore = defineStore('account', () => { - // 状态 - const token = ref(localStorage.getItem('auth_token') || null) - const profile = ref(null) - const devices = ref([]) - const loading = ref(false) - - // 计算属性 - const isAuthenticated = computed(() => !!token.value) - const userName = computed(() => profile.value?.name || '') - const userAvatar = computed(() => profile.value?.avatarUrl || '') - - // 方法 - const setToken = (newToken) => { - token.value = newToken - if (newToken) { - localStorage.setItem('auth_token', newToken) - } else { - localStorage.removeItem('auth_token') - localStorage.removeItem('auth_provider') - } - } - - const loadProfile = async () => { - if (!token.value) return - - loading.value = true - try { - const response = await apiClient.getAccountProfile(token.value) - profile.value = response.data - } catch (error) { - console.error('Failed to load profile:', error) - // Token可能无效,清除 - if (error.message.includes('401')) { - logout() - } - } finally { - loading.value = false - } - } - - const loadDevices = async () => { - if (!token.value) return - - try { - const response = await apiClient.getAccountDevices(token.value) - devices.value = response.data || [] - return devices.value - } catch (error) { - console.error('Failed to load devices:', error) - return [] - } - } - - const bindDevice = async (deviceUuid) => { - if (!token.value) throw new Error('未登录') - - const response = await apiClient.bindDevice(token.value, deviceUuid) - // 重新加载设备列表 - await loadDevices() - return response - } - - const unbindDevice = async (deviceUuid) => { - if (!token.value) throw new Error('未登录') - - const response = await apiClient.unbindDevice(token.value, deviceUuid) - // 重新加载设备列表 - await loadDevices() - return response - } - - const login = async (authToken) => { - setToken(authToken) - await loadProfile() - await loadDevices() - } - - const logout = () => { - token.value = null - profile.value = null - devices.value = [] - localStorage.removeItem('auth_token') - localStorage.removeItem('auth_provider') - } - - // 初始化时加载用户信息 - if (token.value) { - loadProfile() - loadDevices() - } - - return { - // 状态 - token, - profile, - devices, - loading, - // 计算属性 - isAuthenticated, - userName, - userAvatar, - // 方法 - setToken, - loadProfile, - loadDevices, - bindDevice, - unbindDevice, - login, - logout, - } -}) \ No newline at end of file diff --git a/kv-admin/src/style.css b/kv-admin/src/style.css deleted file mode 100644 index 1949175..0000000 --- a/kv-admin/src/style.css +++ /dev/null @@ -1,124 +0,0 @@ -@import "tailwindcss"; -@plugin "@tailwindcss/typography"; -@import "tw-animate-css"; - -@custom-variant dark (&:is(.dark *)); - -@theme inline { - --color-background: var(--background); - --color-foreground: var(--foreground); - --color-card: var(--card); - --color-card-foreground: var(--card-foreground); - --color-popover: var(--popover); - --color-popover-foreground: var(--popover-foreground); - --color-primary: var(--primary); - --color-primary-foreground: var(--primary-foreground); - --color-secondary: var(--secondary); - --color-secondary-foreground: var(--secondary-foreground); - --color-muted: var(--muted); - --color-muted-foreground: var(--muted-foreground); - --color-accent: var(--accent); - --color-accent-foreground: var(--accent-foreground); - --color-destructive: var(--destructive); - --color-destructive-foreground: var(--destructive-foreground); - --color-border: var(--border); - --color-input: var(--input); - --color-ring: var(--ring); - --color-chart-1: var(--chart-1); - --color-chart-2: var(--chart-2); - --color-chart-3: var(--chart-3); - --color-chart-4: var(--chart-4); - --color-chart-5: var(--chart-5); - --radius-sm: calc(var(--radius) - 4px); - --radius-md: calc(var(--radius) - 2px); - --radius-lg: var(--radius); - --radius-xl: calc(var(--radius) + 4px); - --color-sidebar: var(--sidebar); - --color-sidebar-foreground: var(--sidebar-foreground); - --color-sidebar-primary: var(--sidebar-primary); - --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); - --color-sidebar-accent: var(--sidebar-accent); - --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); - --color-sidebar-border: var(--sidebar-border); - --color-sidebar-ring: var(--sidebar-ring); -} - -:root { - --background: oklch(1 0 0); - --foreground: oklch(0.145 0 0); - --card: oklch(1 0 0); - --card-foreground: oklch(0.145 0 0); - --popover: oklch(1 0 0); - --popover-foreground: oklch(0.145 0 0); - --primary: oklch(0.205 0 0); - --primary-foreground: oklch(0.985 0 0); - --secondary: oklch(0.97 0 0); - --secondary-foreground: oklch(0.205 0 0); - --muted: oklch(0.97 0 0); - --muted-foreground: oklch(0.556 0 0); - --accent: oklch(0.97 0 0); - --accent-foreground: oklch(0.205 0 0); - --destructive: oklch(0.577 0.245 27.325); - --destructive-foreground: oklch(0.577 0.245 27.325); - --border: oklch(0.922 0 0); - --input: oklch(0.922 0 0); - --ring: oklch(0.708 0 0); - --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); - --radius: 0.625rem; - --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.145 0 0); - --sidebar-primary: oklch(0.205 0 0); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.97 0 0); - --sidebar-accent-foreground: oklch(0.205 0 0); - --sidebar-border: oklch(0.922 0 0); - --sidebar-ring: oklch(0.708 0 0); -} - -.dark { - --background: oklch(0.145 0 0); - --foreground: oklch(0.985 0 0); - --card: oklch(0.145 0 0); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.145 0 0); - --popover-foreground: oklch(0.985 0 0); - --primary: oklch(0.985 0 0); - --primary-foreground: oklch(0.205 0 0); - --secondary: oklch(0.269 0 0); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.269 0 0); - --muted-foreground: oklch(0.708 0 0); - --accent: oklch(0.269 0 0); - --accent-foreground: oklch(0.985 0 0); - --destructive: oklch(0.396 0.141 25.723); - --destructive-foreground: oklch(0.637 0.237 25.331); - --border: oklch(0.269 0 0); - --input: oklch(0.269 0 0); - --ring: oklch(0.439 0 0); - --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.205 0 0); - --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.269 0 0); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(0.269 0 0); - --sidebar-ring: oklch(0.439 0 0); -} - -@layer base { - * { - @apply border-border outline-ring/50; - } - body { - @apply bg-background text-foreground; - } -} diff --git a/kv-admin/vite.config.js b/kv-admin/vite.config.js deleted file mode 100644 index 98f70fd..0000000 --- a/kv-admin/vite.config.js +++ /dev/null @@ -1,26 +0,0 @@ -import path from "path" -import { fileURLToPath, URL } from 'node:url' -import tailwindcss from "@tailwindcss/vite" -import vue from '@vitejs/plugin-vue' -import { defineConfig } from 'vite' -import VueRouter from 'unplugin-vue-router/vite' -import vueDevTools from 'vite-plugin-vue-devtools' - - -// https://vite.dev/config/ -export default defineConfig({ - plugins: [ - VueRouter({ - routesFolder: 'src/pages', - dts: false, - }), - vue(), - tailwindcss(), - vueDevTools(), - ], - resolve: { - alias: { - "@": fileURLToPath(new URL('./src', import.meta.url)), - }, - }, -}) diff --git a/package.json b/package.json index 430b891..4cb8c65 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "start": "node ./bin/www", "prisma": "prisma generate", "dev": "NODE_ENV=development nodemon node .bin/www", - "migrate": "node ./scripts/batchMigrate.js", "get-token": "node ./cli/get-token.js" }, "type": "module", diff --git a/prisma/migrations/20250524123413_2025_05_24/migration.sql b/prisma/migrations/20250524123413_2025_05_24/migration.sql deleted file mode 100644 index e18c7e6..0000000 --- a/prisma/migrations/20250524123413_2025_05_24/migration.sql +++ /dev/null @@ -1,24 +0,0 @@ --- CreateTable -CREATE TABLE `KVStore` ( - `namespace` VARCHAR(191) NOT NULL, - `key` VARCHAR(191) NOT NULL, - `value` JSON NOT NULL, - `creatorIp` VARCHAR(191) NULL DEFAULT '', - `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - `updatedAt` DATETIME(3) NOT NULL, - - PRIMARY KEY (`namespace`, `key`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - --- CreateTable -CREATE TABLE `Device` ( - `uuid` VARCHAR(191) NOT NULL, - `password` VARCHAR(191) NULL, - `passwordHint` VARCHAR(191) NULL, - `name` VARCHAR(191) NULL, - `accessType` ENUM('PUBLIC', 'PROTECTED', 'PRIVATE') NOT NULL DEFAULT 'PUBLIC', - `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - `updatedAt` DATETIME(3) NOT NULL, - - PRIMARY KEY (`uuid`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/prisma/migrations/20250524123414_2025_05_25/migration.sql b/prisma/migrations/20250524123414_2025_05_25/migration.sql deleted file mode 100644 index 6bada85..0000000 --- a/prisma/migrations/20250524123414_2025_05_25/migration.sql +++ /dev/null @@ -1,117 +0,0 @@ --- 安全迁移脚本:从第一个版本迁移到当前版本 --- 此脚本保留所有现有数据,使用中间表处理主键变更 - --- ==================================== --- 步骤1: 使用中间表迁移 Device 表 --- ==================================== - --- 1.1 创建新的 Device_new 表,使用目标结构 -CREATE TABLE `Device_new` ( - `id` INT NOT NULL AUTO_INCREMENT, - `uuid` VARCHAR(191) NOT NULL, - `password` VARCHAR(191) NULL, - `passwordHint` VARCHAR(191) NULL, - `name` VARCHAR(191) NULL, - `accountId` VARCHAR(191) NULL, - `accessType` ENUM('PUBLIC', 'PROTECTED', 'PRIVATE') NOT NULL DEFAULT 'PUBLIC', - `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - `updatedAt` DATETIME(3) NOT NULL, - - PRIMARY KEY (`id`), - UNIQUE INDEX `Device_uuid_key`(`uuid`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - --- 1.2 从旧表迁移数据到新表(自动分配id) -INSERT INTO `Device_new` (`uuid`, `password`, `passwordHint`, `name`, `accessType`, `createdAt`, `updatedAt`) -SELECT `uuid`, `password`, `passwordHint`, `name`, `accessType`, `createdAt`, `updatedAt` -FROM `Device` -ORDER BY `uuid`; - --- ==================================== --- 步骤2: 使用中间表迁移 KVStore 表 --- ==================================== - --- 2.1 创建新的 KVStore_new 表,使用目标结构 -CREATE TABLE `KVStore_new` ( - `deviceId` INT NOT NULL, - `key` VARCHAR(191) NOT NULL, - `value` JSON NOT NULL, - `creatorIp` VARCHAR(191) NULL DEFAULT '', - `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - `updatedAt` DATETIME(3) NOT NULL, - - PRIMARY KEY (`deviceId`, `key`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - --- 2.2 从旧表迁移数据到新表(通过uuid映射到id) -INSERT INTO `KVStore_new` (`deviceId`, `key`, `value`, `creatorIp`, `createdAt`, `updatedAt`) -SELECT d.`id`, k.`key`, k.`value`, k.`creatorIp`, k.`createdAt`, k.`updatedAt` -FROM `KVStore` k -INNER JOIN `Device_new` d ON k.`namespace` = d.`uuid`; - --- 2.3 删除旧表 -DROP TABLE `KVStore`; - --- 2.4 重命名新表 -RENAME TABLE `KVStore_new` TO `KVStore`; - --- ==================================== --- 步骤3: 完成 Device 表迁移 --- ==================================== - --- 3.1 删除旧的 Device 表 -DROP TABLE `Device`; - --- 3.2 重命名新表 -RENAME TABLE `Device_new` TO `Device`; - --- 3.3 为 KVStore 添加外键约束(必须在两个表都重命名后) -ALTER TABLE `KVStore` ADD CONSTRAINT `KVStore_deviceId_fkey` - FOREIGN KEY (`deviceId`) REFERENCES `Device`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; - --- ==================================== --- 步骤4: 创建 App 表 --- ==================================== - -CREATE TABLE `App` ( - `id` INT NOT NULL AUTO_INCREMENT, - `name` VARCHAR(191) NOT NULL, - `description` VARCHAR(191) NULL, - `developerName` VARCHAR(191) NOT NULL, - `developerLink` VARCHAR(191) NULL, - `homepageLink` VARCHAR(191) NULL, - `iconHash` VARCHAR(191) NULL, - `metadata` JSON NULL, - `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - `updatedAt` DATETIME(3) NOT NULL, - - PRIMARY KEY (`id`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - --- ==================================== --- 步骤5: 创建 AppInstall 表 --- ==================================== - -CREATE TABLE `AppInstall` ( - `id` VARCHAR(191) NOT NULL, - `deviceId` INT NOT NULL, - `appId` INT NOT NULL, - `token` VARCHAR(191) NOT NULL, - `note` VARCHAR(191) NULL, - `installedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - `updatedAt` DATETIME(3) NOT NULL, - - UNIQUE INDEX `AppInstall_token_key`(`token`), - PRIMARY KEY (`id`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - --- 5.1 添加外键约束 -ALTER TABLE `AppInstall` ADD CONSTRAINT `AppInstall_deviceId_fkey` - FOREIGN KEY (`deviceId`) REFERENCES `Device`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; - -ALTER TABLE `AppInstall` ADD CONSTRAINT `AppInstall_appId_fkey` - FOREIGN KEY (`appId`) REFERENCES `App`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; - --- ==================================== --- 迁移完成 --- ==================================== \ No newline at end of file diff --git a/prisma/migrations/20250930_remove_access_type/migration.sql b/prisma/migrations/20250930_remove_access_type/migration.sql deleted file mode 100644 index 1fa56b0..0000000 --- a/prisma/migrations/20250930_remove_access_type/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ --- 移除 Device 表的 accessType 字段 --- 简化密码逻辑:设备只有有密码或没有密码两种状态 - --- 1. 移除 accessType 列 -ALTER TABLE `Device` DROP COLUMN `accessType`; - --- 2. 移除 AccessType 枚举(如果数据库支持,MySQL会自动处理) --- MySQL 不需要显式删除枚举类型 \ No newline at end of file diff --git a/prisma/migrations/20251002032512_update/migration.sql b/prisma/migrations/20251002032512_update/migration.sql deleted file mode 100644 index cf5056d..0000000 --- a/prisma/migrations/20251002032512_update/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE `App` ADD COLUMN `repositoryUrl` VARCHAR(191) NULL; diff --git a/prisma/migrations/20251002074755_update/migration.sql b/prisma/migrations/20251002074755_update/migration.sql deleted file mode 100644 index 0321915..0000000 --- a/prisma/migrations/20251002074755_update/migration.sql +++ /dev/null @@ -1,21 +0,0 @@ --- CreateTable -CREATE TABLE `Account` ( - `id` VARCHAR(191) NOT NULL, - `provider` VARCHAR(191) NOT NULL, - `providerId` VARCHAR(191) NOT NULL, - `email` VARCHAR(191) NULL, - `name` VARCHAR(191) NULL, - `avatarUrl` VARCHAR(191) NULL, - `providerData` JSON NULL, - `accessToken` VARCHAR(191) NOT NULL, - `refreshToken` VARCHAR(191) NULL, - `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - `updatedAt` DATETIME(3) NOT NULL, - - UNIQUE INDEX `Account_accessToken_key`(`accessToken`), - UNIQUE INDEX `Account_provider_providerId_key`(`provider`, `providerId`), - PRIMARY KEY (`id`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - --- AddForeignKey -ALTER TABLE `Device` ADD CONSTRAINT `Device_accountId_fkey` FOREIGN KEY (`accountId`) REFERENCES `Account`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20251005011323_update/migration.sql b/prisma/migrations/20251005011323_update/migration.sql deleted file mode 100644 index 109bf20..0000000 --- a/prisma/migrations/20251005011323_update/migration.sql +++ /dev/null @@ -1,17 +0,0 @@ -/* - Warnings: - - - You are about to drop the `App` table. If the table is not empty, all the data it contains will be lost. - -*/ --- DropForeignKey -ALTER TABLE `AppInstall` DROP FOREIGN KEY `AppInstall_appId_fkey`; - --- DropIndex -DROP INDEX `AppInstall_appId_fkey` ON `AppInstall`; - --- AlterTable -ALTER TABLE `AppInstall` MODIFY `appId` VARCHAR(191) NOT NULL; - --- DropTable -DROP TABLE `App`; diff --git a/prisma/migrations/20251006025039_init/migration.sql b/prisma/migrations/20251006025039_init/migration.sql new file mode 100644 index 0000000..3c9a235 --- /dev/null +++ b/prisma/migrations/20251006025039_init/migration.sql @@ -0,0 +1,68 @@ +-- CreateTable +CREATE TABLE `KVStore` ( + `deviceId` INTEGER NOT NULL, + `key` VARCHAR(191) NOT NULL, + `value` JSON NOT NULL, + `creatorIp` VARCHAR(191) NULL DEFAULT '', + `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updatedAt` DATETIME(3) NOT NULL, + + PRIMARY KEY (`deviceId`, `key`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `Account` ( + `id` VARCHAR(191) NOT NULL, + `provider` VARCHAR(191) NOT NULL, + `providerId` VARCHAR(191) NOT NULL, + `email` VARCHAR(191) NULL, + `name` VARCHAR(191) NULL, + `avatarUrl` VARCHAR(191) NULL, + `providerData` JSON NULL, + `accessToken` VARCHAR(191) NOT NULL, + `refreshToken` VARCHAR(191) NULL, + `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updatedAt` DATETIME(3) NOT NULL, + + UNIQUE INDEX `Account_accessToken_key`(`accessToken`), + UNIQUE INDEX `Account_provider_providerId_key`(`provider`, `providerId`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `Device` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `uuid` VARCHAR(191) NOT NULL, + `name` VARCHAR(191) NULL, + `accountId` VARCHAR(191) NULL, + `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updatedAt` DATETIME(3) NOT NULL, + `password` VARCHAR(191) NULL, + `passwordHint` VARCHAR(191) NULL, + + UNIQUE INDEX `Device_uuid_key`(`uuid`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `AppInstall` ( + `id` VARCHAR(191) NOT NULL, + `deviceId` INTEGER NOT NULL, + `appId` VARCHAR(191) NOT NULL, + `token` VARCHAR(191) NOT NULL, + `note` VARCHAR(191) NULL, + `installedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updatedAt` DATETIME(3) NOT NULL, + + UNIQUE INDEX `AppInstall_token_key`(`token`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- AddForeignKey +ALTER TABLE `KVStore` ADD CONSTRAINT `KVStore_deviceId_fkey` FOREIGN KEY (`deviceId`) REFERENCES `Device`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `Device` ADD CONSTRAINT `Device_accountId_fkey` FOREIGN KEY (`accountId`) REFERENCES `Account`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `AppInstall` ADD CONSTRAINT `AppInstall_deviceId_fkey` FOREIGN KEY (`deviceId`) REFERENCES `Device`(`id`) ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/scripts/batchMigrate.js b/scripts/batchMigrate.js deleted file mode 100644 index 3668b84..0000000 --- a/scripts/batchMigrate.js +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/env node -import fs from 'fs'; -import path from 'path'; -import { execSync } from 'child_process'; -import dotenv from 'dotenv'; - -// 加载环境变量 -dotenv.config(); - -const PRISMA_DIR = path.join(process.cwd(), 'prisma'); -const DATABASE_DIR = path.join(PRISMA_DIR, 'database'); -const MIGRATIONS_DIR = path.join(PRISMA_DIR, 'migrations'); - -// 数据库 URL 环境变量映射 -const DB_URL_VARS = { - mysql: 'MYSQL_DATABASE_URL', - postgres: 'PG_DATABASE_URL' -}; - -function copyDirectory(source, destination) { - // 如果目标目录不存在,创建它 - if (!fs.existsSync(destination)) { - fs.mkdirSync(destination, { recursive: true }); - } - - // 读取源目录中的所有内容 - const items = fs.readdirSync(source); - - for (const item of items) { - const sourcePath = path.join(source, item); - const destPath = path.join(destination, item); - - const stats = fs.statSync(sourcePath); - if (stats.isDirectory()) { - // 如果是目录,递归复制 - copyDirectory(sourcePath, destPath); - } else { - // 如果是文件,直接复制 - fs.copyFileSync(sourcePath, destPath); - } - } -} - -function deleteMigrationsDir() { - if (fs.existsSync(MIGRATIONS_DIR)) { - console.log('🗑️ 删除现有的 migrations 目录...'); - fs.rmSync(MIGRATIONS_DIR, { recursive: true, force: true }); - } -} - -// 修改 schema 文件中的数据库配置 -function updateSchemaConfig(schemaPath, dbType) { - console.log(`📝 更新 schema 文件配置...`); - - // 读取原始内容 - let content = fs.readFileSync(schemaPath, 'utf8'); - const originalContent = content; - - if (dbType === 'sqlite') { - // 修改 SQLite 数据库路径为 ../../data/db.db(用于迁移) - content = content.replace( - /url\s*=\s*"file:..\/data\/db.db"/, - 'url = "file:../../data/db.db"' - ); - } else { - // 获取对应的环境变量名 - const urlEnvVar = DB_URL_VARS[dbType]; - if (!urlEnvVar) { - throw new Error(`未找到 ${dbType} 的数据库 URL 环境变量映射`); - } - - // 替换 env("DATABASE_URL") 为对应的环境变量 - content = content.replace( - /env\s*\(\s*"DATABASE_URL"\s*\)/, - `env("${urlEnvVar}")` - ); - } - - // 写入修改后的内容 - fs.writeFileSync(schemaPath, content, 'utf8'); - - return originalContent; -} - -// 恢复 schema 文件的原始内容,对于 SQLite 恢复为 ../data/db.db -function restoreSchema(schemaPath, dbType, originalContent) { - if (originalContent) { - console.log(`📝 恢复 schema 文件的原始内容...`); - if (dbType === 'sqlite') { - // 确保恢复为 ../data/db.db - let content = originalContent; - if (content.includes('../../data/db.db')) { - content = content.replace( - /url\s*=\s*"file:..\/..\/data\/db.db"/, - 'url = "file:../data/db.db"' - ); - } - fs.writeFileSync(schemaPath, content, 'utf8'); - } else { - fs.writeFileSync(schemaPath, originalContent, 'utf8'); - } - } -} - -async function processDatabaseType(dbType) { - const schemaPath = path.join(DATABASE_DIR, dbType, 'schema.prisma'); - const dbMigrationsDir = path.join(DATABASE_DIR, dbType, 'migrations'); - - if (!fs.existsSync(schemaPath)) { - console.log(`⚠️ 跳过 ${dbType}: schema.prisma 文件不存在`); - return; - } - - let originalContent; - try { - console.log(`\n🔄 处理 ${dbType} 数据库迁移...`); - - // 删除旧的迁移目录 - deleteMigrationsDir(); - - // 修改 schema 文件配置 - originalContent = updateSchemaConfig(schemaPath, dbType); - - // 先尝试部署现有迁移 - console.log(`📦 部署现有迁移...`); - try { - execSync(`npx prisma migrate deploy --schema=${schemaPath}`, { - stdio: 'inherit' - }); - } catch (error) { - console.log(`⚠️ 部署现有迁移失败,将创建新迁移`); - } - - // 执行新迁移 - console.log(`📦 创建新迁移...`); - execSync(`npx prisma migrate dev --name ${new Date().toISOString().split('T')[0]} --schema=${schemaPath}`, { - stdio: 'inherit' - }); - - // 复制迁移文件到数据库特定目录 - if (fs.existsSync(MIGRATIONS_DIR)) { - console.log(`📋 复制迁移文件到 ${dbType} 目录...`); - copyDirectory(MIGRATIONS_DIR, dbMigrationsDir); - } - - console.log(`✅ ${dbType} 迁移完成`); - } catch (error) { - console.error(`❌ ${dbType} 迁移失败:`, error.message); - } finally { - // 确保无论成功还是失败都恢复原始内容,对于 SQLite 恢复为 ../data/db.db - restoreSchema(schemaPath, dbType, originalContent); - } -} - -async function main() { - try { - // 确保数据库目录存在 - if (!fs.existsSync(DATABASE_DIR)) { - console.error('❌ database 目录不存在'); - process.exit(1); - } - - // 获取所有数据库类型目录 - const dbTypes = fs.readdirSync(DATABASE_DIR).filter(item => { - const itemPath = path.join(DATABASE_DIR, item); - return fs.statSync(itemPath).isDirectory(); - }); - - console.log('📊 发现的数据库类型:', dbTypes.join(', ')); - console.log('🔑 数据库配置:'); - for (const [dbType, envVar] of Object.entries(DB_URL_VARS)) { - console.log(` - ${dbType}: 使用环境变量 ${envVar}`); - } - console.log(' - sqlite: 迁移时使用 ../../data/db.db,完成后恢复为 ../data/db.db'); - - // 依次处理每个数据库类型 - for (const dbType of dbTypes) { - await processDatabaseType(dbType); - } - - console.log('\n🎉 所有数据库迁移处理完成!'); - } catch (error) { - console.error('❌ 批量迁移失败:', error); - process.exit(1); - } -} - -// 执行主函数 -main().catch(error => { - console.error('❌ 程序执行失败:', error); - process.exit(1); -}); \ No newline at end of file