diff --git a/.gitignore b/.gitignore index 75f5c4633..1d677a877 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ build logs web/default/dist web/classic/dist +web/daisy/dist web/node_modules web/dist .env diff --git a/.trae/documents/prd.md b/.trae/documents/prd.md new file mode 100644 index 000000000..cc33bbca2 --- /dev/null +++ b/.trae/documents/prd.md @@ -0,0 +1,170 @@ +# ModelsToken 管理平台 - 产品需求文档 (PRD) + +## 1. 产品概述 + +ModelsToken 是一个 AI API 管理与分发平台,为开发者和企业提供统一的 AI 模型接入、密钥管理、用量计费、渠道代理等一站式服务。新前端将采用 React + DaisyUI 5 + TypeScript 构建,替换现有的 Default/Classic 双前端,同时新增本地文档管理功能。 + +- 目标用户:AI 应用开发者、企业运维人员、API 服务管理者 +- 核心价值:简化 AI API 的管理复杂度,提供直观的操作界面和完整的文档支持 + +## 2. 核心功能 + +### 2.1 用户角色 + +| 角色 | 注册方式 | 核心权限 | +|------|----------|----------| +| 普通用户 | 用户名/邮箱/OAuth | 密钥管理、充值、订阅、日志查看、文档访问 | +| 管理员 | 由超级管理员指定 | 渠道管理、用户管理、兑换码、模型管理、订阅管理 | +| 超级管理员 | 系统初始化 | 全部权限 + 系统设置 | + +### 2.2 功能模块 + +#### 公共页面(无需登录) +1. **首页**:Hero 区域、特性展示、快速入门指引 +2. **登录页**:用户名/密码、OAuth 登录(GitHub/Discord/OIDC/LinuxDO/微信/Telegram/自定义) +3. **注册页**:注册表单 + Turnstile 人机验证 +4. **忘记密码**:邮箱重置链接 +5. **模型定价**:模型价格列表、搜索筛选 +6. **关于页面**:项目信息、版本、许可证 +7. **用户协议/隐私政策** +8. **初始化向导**:首次部署配置 + +#### 用户功能(需登录) +1. **仪表盘**:额度概览、使用趋势图、API 信息面板、公告、FAQ +2. **API 密钥管理**:创建/编辑/删除/批量操作、额度限制、模型限制、IP 限制 +3. **钱包/充值**:余额查看、兑换码充值、在线支付(易支付/Stripe/Creem/Waffo)、签到 +4. **订阅管理**:查看计划、购买订阅、当前订阅状态 +5. **使用日志**:请求日志搜索/筛选、MJ 日志、任务日志、统计图表 +6. **个人设置**:资料编辑、2FA 设置、Passkey 管理、OAuth 绑定、语言切换 +7. **Playground**:API 在线调试、Chat Completions 测试 +8. **文档中心**(新增):本地文档管理、分类浏览、搜索、Markdown 渲染 + +#### 管理员功能 +1. **渠道管理**:CRUD、测试、余额更新、标签管理、批量操作、多密钥、Codex OAuth、Ollama 管理 +2. **用户管理**:列表/搜索/创建/编辑/升降级/启禁/额度调整 +3. **兑换码管理**:CRUD、批量删除无效码 +4. **模型管理**:模型元数据 CRUD、上游同步、缺失模型检测 +5. **供应商管理**:CRUD +6. **订阅管理**:计划 CRUD、用户订阅管理 +7. **部署管理**:io.net 部署 CRUD、容器管理、日志 + +#### 超级管理员 - 系统设置 +1. **站点设置**:名称/Logo/页脚/公告/首页内容/服务器地址 +2. **认证设置**:注册/登录开关、OAuth 配置、Turnstile、Passkey、自定义 OAuth +3. **计费设置**:额度/倍率/支付配置/签到/分组倍率 +4. **内容设置**:公告/FAQ/Uptime Kuma/聊天/绘图/Midjourney +5. **模型设置**:透传/思维模型/Gemini/Claude 配置 +6. **运维设置**:重试/自动禁用/SMTP/性能监控/日志 +7. **安全设置**:速率限制/敏感词/SSRF 防护/IP 过滤 + +### 2.3 新增功能 - 本地文档管理 + +| 功能 | 说明 | +|------|------| +| 文档分类 | 支持多级分类树,管理员可创建/编辑/删除分类 | +| 文档 CRUD | 管理员创建/编辑/删除文档,支持 Markdown 编辑器 | +| 文档浏览 | 用户按分类浏览文档,支持搜索 | +| 文档搜索 | 全文搜索文档标题和内容 | +| 文档版本 | 文档更新历史记录 | +| 权限控制 | 可设置文档为公开/登录可见/管理员可见 | + +## 3. 核心流程 + +### 3.1 用户认证流程 + +```mermaid +flowchart TD + "访问平台" --> "已登录?" + "已登录?" -->|"是"| "仪表盘" + "已登录?" -->|"否"| "登录页" + "登录页" --> "输入凭证" + "输入凭证" --> "需要2FA?" + "需要2FA?" -->|"是"| "输入2FA码" + "需要2FA?" -->|"否"| "验证成功" + "输入2FA码" --> "验证成功" + "验证成功" --> "仪表盘" + "登录页" --> "OAuth登录" + "OAuth登录" --> "OAuth回调" + "OAuth回调" --> "已绑定账号?" + "已绑定账号?" -->|"是"| "仪表盘" + "已绑定账号?" -->|"否"| "绑定/注册" +``` + +### 3.2 API 调用流程 + +```mermaid +flowchart TD + "创建API密钥" --> "配置密钥参数" + "配置密钥参数" --> "使用密钥调用API" + "使用密钥调用API" --> "平台路由到渠道" + "平台路由到渠道" --> "返回结果" + "返回结果" --> "记录日志" + "记录日志" --> "扣除额度" +``` + +### 3.3 文档管理流程(新增) + +```mermaid +flowchart TD + "管理员创建分类" --> "创建文档" + "创建文档" --> "Markdown编辑" + "Markdown编辑" --> "设置可见性" + "设置可见性" --> "发布文档" + "发布文档" --> "用户浏览/搜索" +``` + +## 4. 用户界面设计 + +### 4.1 设计风格 + +- **主色调**:深蓝 (#1e293b) + 亮蓝 (#3b82f6) 渐变,搭配 DaisyUI 的 `business` 主题 +- **辅助色**:翡翠绿 (#10b981) 用于成功/在线状态,琥珀色 (#f59e0b) 用于警告 +- **按钮风格**:DaisyUI 默认圆角按钮,主要操作用 `btn-primary`,危险操作用 `btn-error` +- **字体**:JetBrains Mono(代码/密钥)+ Noto Sans SC(中文正文) +- **布局风格**:左侧固定导航栏 + 顶部状态栏 + 主内容区,响应式折叠 +- **图标**:Lucide React 图标库 +- **动效**:DaisyUI 内置动画 + 页面切换淡入 + +### 4.2 页面设计概览 + +| 页面 | 模块 | UI 元素 | +|------|------|---------| +| 首页 | Hero | 渐变背景、特性卡片、快速开始按钮 | +| 登录 | 表单 | 居中卡片、OAuth 按钮组、Turnstile | +| 仪表盘 | 统计卡片 | 4 列额度卡片、折线图、公告栏、API 信息 | +| 密钥管理 | 数据表 | 搜索栏、筛选器、表格、批量操作栏 | +| 渠道管理 | 数据表+表单 | 标签筛选、测试按钮、多密钥管理抽屉 | +| 系统设置 | 标签页 | 7 大分类侧边导航、表单分组、开关/输入框 | +| 文档中心 | 侧边树+内容 | 分类树导航、Markdown 渲染、搜索框、面包屑 | +| Playground | 分栏 | 左侧参数面板、右侧响应面板、模型选择器 | + +### 4.3 响应式设计 + +- 桌面优先(1280px+) +- 平板适配(768px-1279px):侧边栏折叠为抽屉 +- 移动端适配(<768px):单列布局,表格改为卡片列表 + +### 4.4 布局结构 + +``` +┌──────────────────────────────────────────────┐ +│ 顶部导航栏 (Navbar) │ +│ Logo | 搜索 | 通知 | 用户菜单 | 主题切换 │ +├──────┬───────────────────────────────────────┤ +│ │ │ +│ 侧边 │ 主内容区 │ +│ 导航 │ │ +│ 栏 │ ┌─────────────────────────────────┐ │ +│ │ │ 面包屑 + 页面标题 + 操作按钮 │ │ +│ 仪表盘│ ├─────────────────────────────────┤ │ +│ 密钥 │ │ │ │ +│ 渠道 │ │ 页面内容 │ │ +│ 用户 │ │ │ │ +│ 日志 │ │ │ │ +│ 钱包 │ └─────────────────────────────────┘ │ +│ 订阅 │ │ +│ 文档 │ │ +│ 设置 │ │ +│ │ │ +└──────┴───────────────────────────────────────┘ +``` diff --git a/.trae/documents/tech-architecture.md b/.trae/documents/tech-architecture.md new file mode 100644 index 000000000..b3c4708c4 --- /dev/null +++ b/.trae/documents/tech-architecture.md @@ -0,0 +1,459 @@ +# ModelsToken 管理平台 - 技术架构文档 + +## 1. 架构设计 + +```mermaid +flowchart TB + subgraph "前端 (React + DaisyUI 5)" + A["React 18"] --> B["React Router v6"] + B --> C["页面组件"] + C --> D["DaisyUI 5 组件"] + D --> E["Tailwind CSS 4"] + A --> F["Zustand 状态管理"] + A --> G["React Query 数据请求"] + A --> H["i18next 国际化"] + A --> I["React Markdown 渲染"] + end + subgraph "后端 (Go + Gin)" + J["Gin HTTP Server"] + J --> K["API 路由"] + J --> L["Relay 代理"] + K --> M["控制器"] + M --> N["模型层"] + N --> O["数据库 (SQLite/MySQL/PostgreSQL)"] + end + C -->|"Axios HTTP"| K +``` + +## 2. 技术说明 + +- **前端框架**:React 18 + TypeScript +- **UI 库**:DaisyUI 5 + Tailwind CSS 4 +- **构建工具**:Vite 6 +- **路由**:React Router v6(懒加载) +- **状态管理**:Zustand(轻量级,替代 Redux) +- **数据请求**:TanStack React Query v5 + Axios +- **国际化**:i18next + react-i18next +- **图表**:Recharts +- **Markdown**:react-markdown + remark-gfm + rehype-highlight +- **图标**:Lucide React +- **代码高亮**:highlight.js +- **表单验证**:React Hook Form + Zod +- **通知**:react-hot-toast +- **项目目录**:`web/daisy/` + +## 3. 路由定义 + +### 3.1 公共路由 + +| 路由 | 用途 | +|------|------| +| `/` | 首页 | +| `/login` | 登录 | +| `/register` | 注册 | +| `/forgot-password` | 忘记密码 | +| `/reset-password` | 密码重置确认 | +| `/setup` | 初始化向导 | +| `/pricing` | 模型定价 | +| `/about` | 关于 | +| `/user-agreement` | 用户协议 | +| `/privacy-policy` | 隐私政策 | +| `/oauth/callback/:provider` | OAuth 回调 | + +### 3.2 认证后路由 + +| 路由 | 用途 | +|------|------| +| `/dashboard` | 仪表盘 | +| `/tokens` | API 密钥管理 | +| `/wallet` | 钱包/充值 | +| `/subscriptions` | 订阅管理 | +| `/logs` | 使用日志 | +| `/logs/midjourney` | MJ 日志 | +| `/logs/tasks` | 任务日志 | +| `/profile` | 个人设置 | +| `/playground` | Playground | +| `/docs` | 文档中心(新增) | +| `/docs/:slug` | 文档详情(新增) | + +### 3.3 管理员路由 + +| 路由 | 用途 | +|------|------| +| `/admin/channels` | 渠道管理 | +| `/admin/users` | 用户管理 | +| `/admin/redemptions` | 兑换码管理 | +| `/admin/models` | 模型管理 | +| `/admin/vendors` | 供应商管理 | +| `/admin/deployments` | 部署管理 | +| `/admin/subscriptions` | 订阅计划管理 | + +### 3.4 超级管理员路由 + +| 路由 | 用途 | +|------|------| +| `/settings/site` | 站点设置 | +| `/settings/auth` | 认证设置 | +| `/settings/billing` | 计费设置 | +| `/settings/content` | 内容设置 | +| `/settings/models` | 模型设置 | +| `/settings/operations` | 运维设置 | +| `/settings/security` | 安全设置 | +| `/settings/docs` | 文档管理(新增) | + +## 4. API 定义 + +### 4.1 核心类型 + +```typescript +// 用户 +interface User { + id: number; + username: string; + display_name: string; + email: string; + role: number; // 1=user, 10=admin, 100=root + status: number; + quota: number; + used_quota: number; + request_count: number; + group: string; + aff_code: string; + inviter_id: number; + language: string; + access_token: string; + created_time: number; +} + +// 渠道 +interface Channel { + id: number; + type: number; + key: string; + openai_organization?: string; + base_url: string; + models: string; + model_mapping?: string; + group: string; + groups: string[]; + name: string; + priority: number; + weight: number; + status: number; + tag?: string; + setting?: string; + test_time: number; + response_time: number; + balance: number; + balance_updated_time: number; + created_time: number; +} + +// 令牌 +interface Token { + id: number; + user_id: number; + key: string; + status: number; + name: string; + created_time: number; + accessed_time: number; + expired_time: number; + remain_quota: number; + unlimited_quota: boolean; + used_quota: number; + models: string; + subnet: string; + group: string; +} + +// 日志 +interface Log { + id: number; + user_id: number; + created_at: number; + type: number; + content: string; + username: string; + token_name: string; + model_name: string; + quota: number; + prompt_tokens: number; + completion_tokens: number; + channel_id: number; + token_id: number; + group: string; + request_id: string; + ip: string; + detail: string; +} + +// 订阅计划 +interface SubscriptionPlan { + id: number; + name: string; + description: string; + price: number; + currency: string; + duration_days: number; + quota: number; + models: string; + enabled: boolean; + sort_order: number; + created_time: number; +} + +// 文档(新增) +interface Document { + id: number; + title: string; + slug: string; + content: string; // Markdown + category_id: number; + category?: DocumentCategory; + visibility: 'public' | 'auth' | 'admin'; + sort_order: number; + created_at: string; + updated_at: string; + author_id: number; + author?: User; + versions?: DocumentVersion[]; +} + +interface DocumentCategory { + id: number; + name: string; + slug: string; + parent_id: number | null; + children?: DocumentCategory[]; + sort_order: number; +} + +interface DocumentVersion { + id: number; + document_id: number; + content: string; + created_at: string; + author_id: number; +} +``` + +### 4.2 新增文档管理 API + +| 端点 | 方法 | 权限 | 说明 | +|------|------|------|------| +| `/api/docs/categories` | GET | 公开 | 获取分类树 | +| `/api/docs/categories` | POST | Admin | 创建分类 | +| `/api/docs/categories/:id` | PUT | Admin | 更新分类 | +| `/api/docs/categories/:id` | DELETE | Admin | 删除分类 | +| `/api/docs/` | GET | 按可见性 | 文档列表(支持搜索) | +| `/api/docs/:slug` | GET | 按可见性 | 获取文档详情 | +| `/api/docs/` | POST | Admin | 创建文档 | +| `/api/docs/:id` | PUT | Admin | 更新文档 | +| `/api/docs/:id` | DELETE | Admin | 删除文档 | +| `/api/docs/:id/versions` | GET | Admin | 文档版本历史 | + +## 5. 项目目录结构 + +``` +web/daisy/ +├── index.html +├── package.json +├── tsconfig.json +├── vite.config.ts +├── tailwind.config.ts +├── public/ +│ └── manifest.json +└── src/ + ├── main.tsx # 入口 + ├── App.tsx # 根组件 + 路由 + ├── vite-env.d.ts + ├── api/ # API 请求层 + │ ├── client.ts # Axios 实例 + 拦截器 + │ ├── auth.ts # 认证 API + │ ├── channel.ts # 渠道 API + │ ├── token.ts # 令牌 API + │ ├── user.ts # 用户 API + │ ├── log.ts # 日志 API + │ ├── subscription.ts # 订阅 API + │ ├── redemption.ts # 兑换码 API + │ ├── model.ts # 模型 API + │ ├── vendor.ts # 供应商 API + │ ├── deployment.ts # 部署 API + │ ├── option.ts # 系统设置 API + │ ├── payment.ts # 支付 API + │ └── doc.ts # 文档 API(新增) + ├── stores/ # Zustand 状态 + │ ├── auth.ts # 认证状态 + │ └── ui.ts # UI 状态(侧边栏/主题) + ├── hooks/ # 自定义 Hooks + │ ├── useAuth.ts + │ ├── usePermission.ts + │ └── useQuota.ts + ├── components/ # 通用组件 + │ ├── layout/ + │ │ ├── AppLayout.tsx # 主布局 + │ │ ├── Sidebar.tsx # 侧边导航 + │ │ ├── Navbar.tsx # 顶部导航 + │ │ └── Breadcrumb.tsx # 面包屑 + │ ├── common/ + │ │ ├── QuotaDisplay.tsx # 额度显示 + │ │ ├── ModelBadge.tsx # 模型标签 + │ │ ├── StatusBadge.tsx # 状态标签 + │ │ ├── SearchInput.tsx # 搜索框 + │ │ ├── DataTable.tsx # 数据表格 + │ │ ├── ConfirmDialog.tsx # 确认对话框 + │ │ └── LoadingSpinner.tsx # 加载动画 + │ └── charts/ + │ ├── QuotaChart.tsx # 额度趋势图 + │ └── StatsChart.tsx # 统计图表 + ├── pages/ # 页面组件 + │ ├── public/ + │ │ ├── Home.tsx + │ │ ├── Login.tsx + │ │ ├── Register.tsx + │ │ ├── ForgotPassword.tsx + │ │ ├── Pricing.tsx + │ │ ├── About.tsx + │ │ └── Setup.tsx + │ ├── dashboard/ + │ │ └── Dashboard.tsx + │ ├── tokens/ + │ │ ├── TokenList.tsx + │ │ └── TokenForm.tsx + │ ├── channels/ + │ │ ├── ChannelList.tsx + │ │ └── ChannelForm.tsx + │ ├── users/ + │ │ ├── UserList.tsx + │ │ └── UserForm.tsx + │ ├── logs/ + │ │ ├── LogList.tsx + │ │ ├── MidjourneyLog.tsx + │ │ └── TaskLog.tsx + │ ├── wallet/ + │ │ └── Wallet.tsx + │ ├── subscriptions/ + │ │ ├── PlanList.tsx + │ │ └── MySubscription.tsx + │ ├── redemptions/ + │ │ └── RedemptionList.tsx + │ ├── models/ + │ │ └── ModelList.tsx + │ ├── vendors/ + │ │ └── VendorList.tsx + │ ├── deployments/ + │ │ └── DeploymentList.tsx + │ ├── playground/ + │ │ └── Playground.tsx + │ ├── profile/ + │ │ └── Profile.tsx + │ ├── docs/ # 文档中心(新增) + │ │ ├── DocCenter.tsx # 文档浏览主页 + │ │ ├── DocViewer.tsx # 文档阅读页 + │ │ ├── DocEditor.tsx # 文档编辑页(管理员) + │ │ └── DocCategoryManager.tsx # 分类管理(管理员) + │ └── settings/ + │ ├── SiteSettings.tsx + │ ├── AuthSettings.tsx + │ ├── BillingSettings.tsx + │ ├── ContentSettings.tsx + │ ├── ModelSettings.tsx + │ ├── OperationsSettings.tsx + │ ├── SecuritySettings.tsx + │ └── DocSettings.tsx # 文档设置(新增) + ├── i18n/ # 国际化 + │ ├── index.ts + │ └── locales/ + │ ├── en.json + │ └── zh.json + ├── lib/ # 工具函数 + │ ├── constants.ts + │ ├── utils.ts + │ ├── quota.ts + │ └── channel-types.ts + └── types/ # TypeScript 类型 + ├── api.ts + ├── channel.ts + ├── token.ts + ├── user.ts + ├── log.ts + ├── subscription.ts + ├── doc.ts + └── option.ts +``` + +## 6. 数据模型(新增文档管理) + +```mermaid +erDiagram + "document_categories" { + int id PK + string name + string slug UK + int parent_id FK + int sort_order + timestamp created_at + } + "documents" { + int id PK + string title + string slug UK + text content + int category_id FK + string visibility + int sort_order + int author_id FK + timestamp created_at + timestamp updated_at + } + "document_versions" { + int id PK + int document_id FK + text content + int author_id FK + timestamp created_at + } + "document_categories" ||--o{ "document_categories" : "parent" + "document_categories" ||--o{ "documents" : "has" + "documents" ||--o{ "document_versions" : "has" +``` + +### DDL + +```sql +CREATE TABLE document_categories ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR(100) NOT NULL, + slug VARCHAR(100) NOT NULL UNIQUE, + parent_id INTEGER REFERENCES document_categories(id) ON DELETE SET NULL, + sort_order INTEGER DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE documents ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title VARCHAR(200) NOT NULL, + slug VARCHAR(200) NOT NULL UNIQUE, + content TEXT NOT NULL, + category_id INTEGER REFERENCES document_categories(id) ON DELETE SET NULL, + visibility VARCHAR(20) DEFAULT 'public' CHECK (visibility IN ('public', 'auth', 'admin')), + sort_order INTEGER DEFAULT 0, + author_id INTEGER NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE document_versions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + document_id INTEGER NOT NULL REFERENCES documents(id) ON DELETE CASCADE, + content TEXT NOT NULL, + author_id INTEGER NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +); + +CREATE INDEX idx_documents_slug ON documents(slug); +CREATE INDEX idx_documents_category ON documents(category_id); +CREATE INDEX idx_documents_visibility ON documents(visibility); +CREATE INDEX idx_document_versions_doc ON document_versions(document_id); +``` diff --git a/Dockerfile b/Dockerfile index d01ab3f0f..4f03121da 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,6 +20,15 @@ COPY ./web/classic ./classic COPY ./VERSION /build/VERSION RUN cd classic && VITE_REACT_APP_VERSION=$(cat /build/VERSION) bun run build +FROM node:22-alpine AS builder-daisy + +WORKDIR /build +COPY web/daisy/package.json web/daisy/package-lock.json ./ +RUN npm ci +COPY ./web/daisy ./ +COPY ./VERSION /build/VERSION +RUN VITE_REACT_APP_VERSION=$(cat /build/VERSION) npm run build + FROM golang:1.26.1-alpine@sha256:2389ebfa5b7f43eeafbd6be0c3700cc46690ef842ad962f6c5bd6be49ed82039 AS builder2 ENV GO111MODULE=on CGO_ENABLED=0 @@ -36,6 +45,7 @@ RUN go mod download COPY . . COPY --from=builder /build/web/default/dist ./web/default/dist COPY --from=builder-classic /build/web/classic/dist ./web/classic/dist +COPY --from=builder-daisy /build/dist ./web/daisy/dist RUN go build -ldflags "-s -w -X 'github.com/QuantumNous/new-api/common.Version=$(cat VERSION)'" -o new-api FROM debian:bookworm-slim@sha256:f06537653ac770703bc45b4b113475bd402f451e85223f0f2837acbf89ab020a diff --git a/common/constants.go b/common/constants.go index ec2cbf1db..37e6d077c 100644 --- a/common/constants.go +++ b/common/constants.go @@ -30,9 +30,9 @@ func GetTheme() string { } // SetTheme updates the frontend theme atomically. -// Only "default" and "classic" are accepted; other values are silently ignored. +// Only "default", "classic", and "daisy" are accepted; other values are silently ignored. func SetTheme(t string) { - if t == "default" || t == "classic" { + if t == "default" || t == "classic" || t == "daisy" { themeValue.Store(t) } } diff --git a/common/embed-file-system.go b/common/embed-file-system.go index e76fbb801..7926b7d26 100644 --- a/common/embed-file-system.go +++ b/common/embed-file-system.go @@ -48,22 +48,31 @@ func EmbedFolder(fsEmbed embed.FS, targetPath string) static.ServeFileSystem { type themeAwareFileSystem struct { defaultFS static.ServeFileSystem classicFS static.ServeFileSystem + daisyFS static.ServeFileSystem } func (t *themeAwareFileSystem) Exists(prefix string, path string) bool { - if GetTheme() == "classic" { + switch GetTheme() { + case "classic": return t.classicFS.Exists(prefix, path) + case "daisy": + return t.daisyFS.Exists(prefix, path) + default: + return t.defaultFS.Exists(prefix, path) } - return t.defaultFS.Exists(prefix, path) } func (t *themeAwareFileSystem) Open(name string) (http.File, error) { - if GetTheme() == "classic" { + switch GetTheme() { + case "classic": return t.classicFS.Open(name) + case "daisy": + return t.daisyFS.Open(name) + default: + return t.defaultFS.Open(name) } - return t.defaultFS.Open(name) } -func NewThemeAwareFS(defaultFS, classicFS static.ServeFileSystem) static.ServeFileSystem { - return &themeAwareFileSystem{defaultFS: defaultFS, classicFS: classicFS} +func NewThemeAwareFS(defaultFS, classicFS, daisyFS static.ServeFileSystem) static.ServeFileSystem { + return &themeAwareFileSystem{defaultFS: defaultFS, classicFS: classicFS, daisyFS: daisyFS} } diff --git a/controller/document.go b/controller/document.go new file mode 100644 index 000000000..b42ad5bed --- /dev/null +++ b/controller/document.go @@ -0,0 +1,250 @@ +package controller + +import ( + "net/http" + "strconv" + + "github.com/QuantumNous/new-api/common" + "github.com/QuantumNous/new-api/model" + + "github.com/gin-gonic/gin" +) + +// GetCategories 获取文档分类列表(公开) +func GetCategories(c *gin.Context) { + categories, err := model.GetDocumentCategories() + if err != nil { + common.ApiError(c, err) + return + } + common.ApiSuccess(c, categories) +} + +// CreateCategory 创建文档分类(管理员) +func CreateCategory(c *gin.Context) { + var category model.DocumentCategory + if err := c.ShouldBindJSON(&category); err != nil { + common.ApiError(c, err) + return + } + if category.Name == "" { + common.ApiErrorMsg(c, "分类名称不能为空") + return + } + if category.Slug == "" { + common.ApiErrorMsg(c, "分类标识不能为空") + return + } + if err := model.CreateDocumentCategory(&category); err != nil { + common.ApiError(c, err) + return + } + common.ApiSuccess(c, &category) +} + +// UpdateCategory 更新文档分类(管理员) +func UpdateCategory(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + common.ApiError(c, err) + return + } + var category model.DocumentCategory + if err := c.ShouldBindJSON(&category); err != nil { + common.ApiError(c, err) + return + } + category.Id = id + if err := model.UpdateDocumentCategory(&category); err != nil { + common.ApiError(c, err) + return + } + common.ApiSuccess(c, &category) +} + +// DeleteCategory 删除文档分类(管理员) +func DeleteCategory(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + common.ApiError(c, err) + return + } + if err := model.DeleteDocumentCategory(id); err != nil { + common.ApiError(c, err) + return + } + common.ApiSuccess(c, nil) +} + +// GetDocuments 获取文档列表(公开,根据认证状态过滤可见性) +func GetDocuments(c *gin.Context) { + keyword := c.Query("keyword") + categoryIdStr := c.Query("category_id") + + var categoryId *int + if categoryIdStr != "" { + id, err := strconv.Atoi(categoryIdStr) + if err == nil { + categoryId = &id + } + } + + // 根据用户认证状态决定可见性过滤 + visibility := c.Query("visibility") + role := c.GetInt("role") + if role >= common.RoleAdminUser { + // 管理员可看所有,如果指定了 visibility 则按指定值过滤 + // visibility 保持原值 + } else if role >= common.RoleCommonUser { + // 普通用户只能看 public 和 auth + if visibility == "admin" { + visibility = "" // 不允许看 admin + } + // 如果没有指定 visibility,则过滤出 public 和 auth + } else { + // 未登录用户只能看 public + visibility = "public" + } + + pageInfo := common.GetPageQuery(c) + documents, total, err := model.GetDocuments(keyword, visibility, categoryId, pageInfo.GetStartIdx(), pageInfo.GetPageSize()) + if err != nil { + common.ApiError(c, err) + return + } + pageInfo.SetTotal(int(total)) + pageInfo.SetItems(documents) + common.ApiSuccess(c, pageInfo) +} + +// GetDocument 获取单个文档(根据可见性检查权限) +func GetDocument(c *gin.Context) { + slug := c.Param("slug") + doc, err := model.GetDocumentBySlug(slug) + if err != nil { + common.ApiError(c, err) + return + } + + // 检查可见性权限 + role := c.GetInt("role") + switch doc.Visibility { + case "admin": + if role < common.RoleAdminUser { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": "无权访问该文档", + }) + return + } + case "auth": + if role < common.RoleCommonUser { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": "请先登录后查看该文档", + }) + return + } + } + + common.ApiSuccess(c, doc) +} + +// CreateDocument 创建文档(管理员) +func CreateDocument(c *gin.Context) { + var doc model.Document + if err := c.ShouldBindJSON(&doc); err != nil { + common.ApiError(c, err) + return + } + if doc.Title == "" { + common.ApiErrorMsg(c, "文档标题不能为空") + return + } + if doc.Slug == "" { + common.ApiErrorMsg(c, "文档标识不能为空") + return + } + if doc.Content == "" { + common.ApiErrorMsg(c, "文档内容不能为空") + return + } + if doc.Visibility == "" { + doc.Visibility = "public" + } + doc.AuthorId = c.GetInt("id") + if err := model.CreateDocument(&doc); err != nil { + common.ApiError(c, err) + return + } + common.ApiSuccess(c, &doc) +} + +// UpdateDocument 更新文档(管理员,自动创建版本记录) +func UpdateDocument(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + common.ApiError(c, err) + return + } + var doc model.Document + if err := c.ShouldBindJSON(&doc); err != nil { + common.ApiError(c, err) + return + } + doc.Id = id + + // 获取旧文档内容,自动创建版本记录 + oldDoc, err := model.GetDocumentById(id) + if err != nil { + common.ApiError(c, err) + return + } + version := &model.DocumentVersion{ + DocumentId: oldDoc.Id, + Content: oldDoc.Content, + AuthorId: oldDoc.AuthorId, + } + if err := model.CreateDocumentVersion(version); err != nil { + common.ApiError(c, err) + return + } + + if err := model.UpdateDocument(&doc); err != nil { + common.ApiError(c, err) + return + } + common.ApiSuccess(c, &doc) +} + +// DeleteDocument 删除文档(管理员) +func DeleteDocument(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + common.ApiError(c, err) + return + } + if err := model.DeleteDocument(id); err != nil { + common.ApiError(c, err) + return + } + common.ApiSuccess(c, nil) +} + +// GetDocumentVersions 获取文档版本历史(管理员) +func GetDocumentVersions(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + common.ApiError(c, err) + return + } + pageInfo := common.GetPageQuery(c) + versions, total, err := model.GetDocumentVersions(id, pageInfo.GetStartIdx(), pageInfo.GetPageSize()) + if err != nil { + common.ApiError(c, err) + return + } + pageInfo.SetTotal(int(total)) + pageInfo.SetItems(versions) + common.ApiSuccess(c, pageInfo) +} diff --git a/controller/option.go b/controller/option.go index 7566d5a41..c74463282 100644 --- a/controller/option.go +++ b/controller/option.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/QuantumNous/new-api/common" - "github.com/QuantumNous/new-api/i18n" "github.com/QuantumNous/new-api/model" "github.com/QuantumNous/new-api/setting" "github.com/QuantumNous/new-api/setting/console_setting" @@ -205,10 +204,10 @@ func UpdateOption(c *gin.Context) { return } case "theme.frontend": - if option.Value != "default" && option.Value != "classic" { + if option.Value != "default" && option.Value != "classic" && option.Value != "daisy" { c.JSON(http.StatusOK, gin.H{ "success": false, - "message": "无效的主题值,可选值:default(新版前端)、classic(经典前端)", + "message": "无效的主题值,可选值:default(新版前端)、classic(经典前端)、daisy(DaisyUI 前端)", }) return } diff --git a/main.go b/main.go index 2470e8656..58049487f 100644 --- a/main.go +++ b/main.go @@ -47,6 +47,12 @@ var classicBuildFS embed.FS //go:embed web/classic/dist/index.html var classicIndexPage []byte +//go:embed web/daisy/dist +var daisyBuildFS embed.FS + +//go:embed web/daisy/dist/index.html +var daisyIndexPage []byte + func main() { startTime := time.Now() @@ -195,6 +201,8 @@ func main() { DefaultIndexPage: indexPage, ClassicBuildFS: classicBuildFS, ClassicIndexPage: classicIndexPage, + DaisyBuildFS: daisyBuildFS, + DaisyIndexPage: daisyIndexPage, }) var port = os.Getenv("PORT") if port == "" { diff --git a/model/document.go b/model/document.go new file mode 100644 index 000000000..936a1646d --- /dev/null +++ b/model/document.go @@ -0,0 +1,71 @@ +package model + +import ( + "time" +) + +type Document struct { + Id int `json:"id" gorm:"primaryKey"` + Title string `json:"title" gorm:"not null"` + Slug string `json:"slug" gorm:"uniqueIndex;not null"` + Content string `json:"content" gorm:"type:text;not null"` + CategoryId *int `json:"category_id" gorm:"index"` + Visibility string `json:"visibility" gorm:"default:'public'"` // public, auth, admin + SortOrder int `json:"sort_order" gorm:"default:0"` + AuthorId int `json:"author_id" gorm:"not null"` + CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"` + UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"` +} + +func GetDocuments(keyword string, visibility string, categoryId *int, startIdx int, num int) ([]*Document, int64, error) { + query := DB.Model(&Document{}) + if keyword != "" { + like := "%" + keyword + "%" + query = query.Where("title LIKE ? OR content LIKE ?", like, like) + } + if visibility != "" { + query = query.Where("visibility = ?", visibility) + } + if categoryId != nil { + query = query.Where("category_id = ?", *categoryId) + } + var total int64 + if err := query.Count(&total).Error; err != nil { + return nil, 0, err + } + var documents []*Document + if err := query.Order("sort_order ASC, id DESC").Offset(startIdx).Limit(num).Find(&documents).Error; err != nil { + return nil, 0, err + } + return documents, total, nil +} + +func GetDocumentBySlug(slug string) (*Document, error) { + var doc Document + err := DB.Where("slug = ?", slug).First(&doc).Error + if err != nil { + return nil, err + } + return &doc, nil +} + +func GetDocumentById(id int) (*Document, error) { + var doc Document + err := DB.First(&doc, id).Error + if err != nil { + return nil, err + } + return &doc, nil +} + +func CreateDocument(doc *Document) error { + return DB.Create(doc).Error +} + +func UpdateDocument(doc *Document) error { + return DB.Model(doc).Select("title", "slug", "content", "category_id", "visibility", "sort_order").Updates(doc).Error +} + +func DeleteDocument(id int) error { + return DB.Delete(&Document{}, id).Error +} diff --git a/model/document_category.go b/model/document_category.go new file mode 100644 index 000000000..eb0ff0b60 --- /dev/null +++ b/model/document_category.go @@ -0,0 +1,38 @@ +package model + +import ( + "time" +) + +type DocumentCategory struct { + Id int `json:"id" gorm:"primaryKey"` + Name string `json:"name" gorm:"not null"` + Slug string `json:"slug" gorm:"uniqueIndex;not null"` + ParentId *int `json:"parent_id" gorm:"index"` + SortOrder int `json:"sort_order" gorm:"default:0"` + CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"` +} + +func GetDocumentCategories() ([]*DocumentCategory, error) { + var categories []*DocumentCategory + err := DB.Order("sort_order ASC, id ASC").Find(&categories).Error + return categories, err +} + +func GetDocumentCategoryTree() ([]*DocumentCategory, error) { + var categories []*DocumentCategory + err := DB.Order("sort_order ASC, id ASC").Find(&categories).Error + return categories, err +} + +func CreateDocumentCategory(category *DocumentCategory) error { + return DB.Create(category).Error +} + +func UpdateDocumentCategory(category *DocumentCategory) error { + return DB.Model(category).Select("name", "slug", "parent_id", "sort_order").Updates(category).Error +} + +func DeleteDocumentCategory(id int) error { + return DB.Delete(&DocumentCategory{}, id).Error +} diff --git a/model/document_version.go b/model/document_version.go new file mode 100644 index 000000000..e9cf589e2 --- /dev/null +++ b/model/document_version.go @@ -0,0 +1,30 @@ +package model + +import ( + "time" +) + +type DocumentVersion struct { + Id int `json:"id" gorm:"primaryKey"` + DocumentId int `json:"document_id" gorm:"index;not null"` + Content string `json:"content" gorm:"type:text;not null"` + AuthorId int `json:"author_id" gorm:"not null"` + CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"` +} + +func GetDocumentVersions(documentId int, startIdx int, num int) ([]*DocumentVersion, int64, error) { + query := DB.Model(&DocumentVersion{}).Where("document_id = ?", documentId) + var total int64 + if err := query.Count(&total).Error; err != nil { + return nil, 0, err + } + var versions []*DocumentVersion + if err := query.Order("id DESC").Offset(startIdx).Limit(num).Find(&versions).Error; err != nil { + return nil, 0, err + } + return versions, total, nil +} + +func CreateDocumentVersion(version *DocumentVersion) error { + return DB.Create(version).Error +} diff --git a/model/main.go b/model/main.go index 6d9002462..107b0d9a2 100644 --- a/model/main.go +++ b/model/main.go @@ -281,6 +281,9 @@ func migrateDB() error { &CustomOAuthProvider{}, &UserOAuthBinding{}, &PerfMetric{}, + &DocumentCategory{}, + &Document{}, + &DocumentVersion{}, ) if err != nil { return err @@ -330,6 +333,9 @@ func migrateDBFast() error { {&CustomOAuthProvider{}, "CustomOAuthProvider"}, {&UserOAuthBinding{}, "UserOAuthBinding"}, {&PerfMetric{}, "PerfMetric"}, + {&DocumentCategory{}, "DocumentCategory"}, + {&Document{}, "Document"}, + {&DocumentVersion{}, "DocumentVersion"}, } // 动态计算migration数量,确保errChan缓冲区足够大 errChan := make(chan error, len(migrations)) diff --git a/router/api-router.go b/router/api-router.go index 288d72689..c9ac500cf 100644 --- a/router/api-router.go +++ b/router/api-router.go @@ -346,6 +346,28 @@ func SetApiRouter(router *gin.Engine) { taskRoute.GET("/", middleware.AdminAuth(), controller.GetAllTask) } + // Document routes (public) + docsPublic := apiRouter.Group("/docs") + docsPublic.Use(middleware.TryUserAuth()) + { + docsPublic.GET("/categories", controller.GetCategories) + docsPublic.GET("/", controller.GetDocuments) + docsPublic.GET("/:slug", controller.GetDocument) + } + + // Document routes (admin) + docsAdmin := apiRouter.Group("/docs") + docsAdmin.Use(middleware.AdminAuth()) + { + docsAdmin.POST("/categories", controller.CreateCategory) + docsAdmin.PUT("/categories/:id", controller.UpdateCategory) + docsAdmin.DELETE("/categories/:id", controller.DeleteCategory) + docsAdmin.POST("/", controller.CreateDocument) + docsAdmin.PUT("/:id", controller.UpdateDocument) + docsAdmin.DELETE("/:id", controller.DeleteDocument) + docsAdmin.GET("/:id/versions", controller.GetDocumentVersions) + } + vendorRoute := apiRouter.Group("/vendors") vendorRoute.Use(middleware.AdminAuth()) { diff --git a/router/web-router.go b/router/web-router.go index 0d475e90d..678402719 100644 --- a/router/web-router.go +++ b/router/web-router.go @@ -13,18 +13,21 @@ import ( "github.com/gin-gonic/gin" ) -// ThemeAssets holds the embedded frontend assets for both themes. +// ThemeAssets holds the embedded frontend assets for all themes. type ThemeAssets struct { DefaultBuildFS embed.FS DefaultIndexPage []byte ClassicBuildFS embed.FS ClassicIndexPage []byte + DaisyBuildFS embed.FS + DaisyIndexPage []byte } func SetWebRouter(router *gin.Engine, assets ThemeAssets) { defaultFS := common.EmbedFolder(assets.DefaultBuildFS, "web/default/dist") classicFS := common.EmbedFolder(assets.ClassicBuildFS, "web/classic/dist") - themeFS := common.NewThemeAwareFS(defaultFS, classicFS) + daisyFS := common.EmbedFolder(assets.DaisyBuildFS, "web/daisy/dist") + themeFS := common.NewThemeAwareFS(defaultFS, classicFS, daisyFS) router.Use(gzip.Gzip(gzip.DefaultCompression)) router.Use(middleware.GlobalWebRateLimit()) @@ -37,9 +40,12 @@ func SetWebRouter(router *gin.Engine, assets ThemeAssets) { return } c.Header("Cache-Control", "no-cache") - if common.GetTheme() == "classic" { + switch common.GetTheme() { + case "classic": c.Data(http.StatusOK, "text/html; charset=utf-8", assets.ClassicIndexPage) - } else { + case "daisy": + c.Data(http.StatusOK, "text/html; charset=utf-8", assets.DaisyIndexPage) + default: c.Data(http.StatusOK, "text/html; charset=utf-8", assets.DefaultIndexPage) } }) diff --git a/web/daisy/.gitignore b/web/daisy/.gitignore new file mode 100644 index 000000000..54f07af58 --- /dev/null +++ b/web/daisy/.gitignore @@ -0,0 +1,24 @@ +# 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? \ No newline at end of file diff --git a/web/daisy/README.md b/web/daisy/README.md new file mode 100644 index 000000000..7515059c2 --- /dev/null +++ b/web/daisy/README.md @@ -0,0 +1,57 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default tseslint.config({ + extends: [ + // Remove ...tseslint.configs.recommended and replace with this + ...tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + ...tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + ...tseslint.configs.stylisticTypeChecked, + ], + languageOptions: { + // other options... + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, +}) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default tseslint.config({ + extends: [ + // other configs... + // Enable lint rules for React + reactX.configs['recommended-typescript'], + // Enable lint rules for React DOM + reactDom.configs.recommended, + ], + languageOptions: { + // other options... + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, +}) +``` diff --git a/web/daisy/eslint.config.js b/web/daisy/eslint.config.js new file mode 100644 index 000000000..092408a9f --- /dev/null +++ b/web/daisy/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/web/daisy/index.html b/web/daisy/index.html new file mode 100644 index 000000000..7962dab46 --- /dev/null +++ b/web/daisy/index.html @@ -0,0 +1,13 @@ + + + + + + + ModelsToken + + +
+ + + diff --git a/web/daisy/package-lock.json b/web/daisy/package-lock.json new file mode 100644 index 000000000..6b6c3e9e9 --- /dev/null +++ b/web/daisy/package-lock.json @@ -0,0 +1,6545 @@ +{ + "name": "modelstoken-daisy", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "modelstoken-daisy", + "version": "1.0.0", + "dependencies": { + "@hookform/resolvers": "^5.4.0", + "@tanstack/react-query": "^5.77.0", + "axios": "^1.9.0", + "clsx": "^2.1.1", + "daisyui": "^5.0.0", + "i18next": "^24.2.2", + "i18next-browser-languagedetector": "^8.0.4", + "lucide-react": "^0.511.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-hook-form": "^7.56.4", + "react-hot-toast": "^2.5.2", + "react-i18next": "^15.5.2", + "react-markdown": "^10.1.0", + "react-router-dom": "^7.3.0", + "recharts": "^2.15.3", + "rehype-highlight": "^7.0.2", + "remark-gfm": "^4.0.1", + "tailwind-merge": "^3.0.2", + "zod": "^3.25.0", + "zustand": "^5.0.3" + }, + "devDependencies": { + "@eslint/js": "^9.25.0", + "@tailwindcss/vite": "^4.1.0", + "@types/node": "^22.15.30", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.4.1", + "autoprefixer": "^10.4.21", + "eslint": "^9.25.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^16.0.0", + "postcss": "^8.5.3", + "tailwindcss": "^4.1.0", + "typescript": "~5.8.3", + "typescript-eslint": "^8.30.1", + "vite": "^6.3.5", + "vite-tsconfig-paths": "^5.1.4" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@hookform/resolvers": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.4.0.tgz", + "integrity": "sha512-EIsqr/t/qbinPIhGjMdtvutIN1Kk4uwbROE9/UQ93CAVGR7GkA7Y92+fX80OzXi/OB67jVFYwKGO1WzkxmkFZw==", + "license": "MIT", + "dependencies": { + "@standard-schema/utils": "^0.3.0" + }, + "peerDependencies": { + "react-hook-form": "^7.55.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", + "integrity": "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.1.tgz", + "integrity": "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.1.tgz", + "integrity": "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.1.tgz", + "integrity": "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.1.tgz", + "integrity": "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.1.tgz", + "integrity": "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.1.tgz", + "integrity": "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.1.tgz", + "integrity": "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.1.tgz", + "integrity": "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.1.tgz", + "integrity": "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.1.tgz", + "integrity": "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.1.tgz", + "integrity": "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.1.tgz", + "integrity": "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.1.tgz", + "integrity": "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.1.tgz", + "integrity": "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.1.tgz", + "integrity": "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.1.tgz", + "integrity": "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", + "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.1.tgz", + "integrity": "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.1.tgz", + "integrity": "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.1.tgz", + "integrity": "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.1.tgz", + "integrity": "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.1.tgz", + "integrity": "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.1.tgz", + "integrity": "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.1.tgz", + "integrity": "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz", + "integrity": "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.21.0", + "jiti": "^2.6.1", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.0" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz", + "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.0", + "@tailwindcss/oxide-darwin-arm64": "4.3.0", + "@tailwindcss/oxide-darwin-x64": "4.3.0", + "@tailwindcss/oxide-freebsd-x64": "4.3.0", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.0", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.0", + "@tailwindcss/oxide-linux-x64-musl": "4.3.0", + "@tailwindcss/oxide-wasm32-wasi": "4.3.0", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.0" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.0.tgz", + "integrity": "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.0.tgz", + "integrity": "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.0.tgz", + "integrity": "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.0.tgz", + "integrity": "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.0.tgz", + "integrity": "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.0.tgz", + "integrity": "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.0.tgz", + "integrity": "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.0.tgz", + "integrity": "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.0.tgz", + "integrity": "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.0.tgz", + "integrity": "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.10.0", + "@emnapi/runtime": "^1.10.0", + "@emnapi/wasi-threads": "^1.2.1", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.0.tgz", + "integrity": "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.0.tgz", + "integrity": "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.0.tgz", + "integrity": "sha512-t6J3OrB5Fc0ExuhohouH0fWUGMYL6PTLhW+E7zIk/pdbnJARZDCwjBznFnkh5ynRnIRSI4YjtTH0t6USjJISrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.3.0", + "@tailwindcss/oxide": "4.3.0", + "tailwindcss": "4.3.0" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.101.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.101.0.tgz", + "integrity": "sha512-cQetA74EB+seWySv1TTKr828TnP0u39m6LykwDXIo84SNortpDkp30TMEjkqtYCNP9c40uT/iwl6MLiufEt0Ow==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.101.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.101.0.tgz", + "integrity": "sha512-rLlJXSpkqfizLWgkR5+eLeIk0MvTx/meEIR7LRjxic+qxiQP8zVjq7BqQkiCMNLQBlLfuOLqqr6KO5GtrDlmSg==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.101.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.21.tgz", + "integrity": "sha512-VMeFBSCKQKmm2swI2kW51SFusDqekC6q9trBCvJ/JliDchFSuoYYKN7yVNjPthP1HKZcx3U1gI/wTcEBjEFKTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz", + "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.0.tgz", + "integrity": "sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/type-utils": "8.61.0", + "@typescript-eslint/utils": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.61.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.0.tgz", + "integrity": "sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.0.tgz", + "integrity": "sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.61.0", + "@typescript-eslint/types": "^8.61.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.0.tgz", + "integrity": "sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.0.tgz", + "integrity": "sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.0.tgz", + "integrity": "sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.0.tgz", + "integrity": "sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.0.tgz", + "integrity": "sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.61.0", + "@typescript-eslint/tsconfig-utils": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.0.tgz", + "integrity": "sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.0.tgz", + "integrity": "sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", + "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", + "license": "ISC" + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz", + "integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "caniuse-lite": "^1.0.30001787", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.17.0.tgz", + "integrity": "sha512-J8SwNxprqqpbfenehxWYXE7CW+wM1BB4w3+N+g+/Wx40xM4rsLrfPmHHxSWIxJLYDgSY/HqlFPIYb2/S3rxafw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.36", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.36.tgz", + "integrity": "sha512-lVq/Df7LXlO79MVaaUHztSwWiG9oXoWHlgvNS51v8Dpd4+G4/VIy6qYePTw31nAVls33nUtnfezYeLkYAak9dg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001799", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", + "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/daisyui": { + "version": "5.5.23", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.5.23.tgz", + "integrity": "sha512-xuheNUSL4T6ZVtWXoioqcNkjoyGX85QTDz4HTw2aBPfqk4fuMjax5HDo8qCmpV6M1YN8bGvfx5BpYCoDeRlt+A==", + "license": "MIT", + "funding": { + "url": "https://github.com/saadeghi/daisyui?sponsor=1" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.372", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.372.tgz", + "integrity": "sha512-M3yhbAlilnwqC8D21t28UCDGHyitShTmmLRU/H+b74P6Ski16Nb9HONYEaVpMj/pwC7BEo5B95FpjODLCWbtfA==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.24.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.0.tgz", + "integrity": "sha512-SkE2t82KlkkxQRVMVLAGKxLfORGQfrkx5dkj+vlgXRVNEdPc4eZcR+J/Fvj8C+yKSFH5L0q3NFlyufOVQnCcYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.26", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz", + "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-equals": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz", + "integrity": "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/goober": { + "version": "2.1.19", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.19.tgz", + "integrity": "sha512-U7veizMqxyKlM58+Z5j2ngJBH/r9siDmxpvNxSw0PylF6WQvrASJEZrxh1hidRBJc2jqoBVSyOban5u8m+6Rxg==", + "license": "MIT", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "license": "MIT", + "dependencies": { + "void-elements": "3.1.0" + } + }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/i18next": { + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-24.2.3.tgz", + "integrity": "sha512-lfbf80OzkocvX7nmZtu7nSTNbrTYR52sLWxPtlXX1zAhVw8WEnFk4puUkCR4B1dNQwbSpEHHHemcZu//7EcB7A==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.10" + }, + "peerDependencies": { + "typescript": "^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.1.tgz", + "integrity": "sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", + "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowlight": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.3.0.tgz", + "integrity": "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "highlight.js": "~11.11.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.511.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.511.0.tgz", + "integrity": "sha512-VK5a2ydJ7xm8GvBeKLS9mu1pVK6ucef9780JVUjw6bAjJL/QXnd4Y0p7SPeOUMC27YhzNCZvm5d/QX0Tp3rc0w==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/property-information": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-hook-form": { + "version": "7.78.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.78.0.tgz", + "integrity": "sha512-EEZqc+N23moyzTlz61Pj+JvcXo76ICkpfOZo8JZw+sM4+wLQGh6nI2Ms+PdMOYNluFu0ghlM7B8mCzhRYtJCnA==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-hot-toast": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.6.0.tgz", + "integrity": "sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg==", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.3", + "goober": "^2.1.16" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/react-i18next": { + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.7.4.tgz", + "integrity": "sha512-nyU8iKNrI5uDJch0z9+Y5XEr34b0wkyYj3Rp+tfbahxtlswxSCjcUL9H0nqXo9IR3/t5Y5PKIA3fx3MfUyR9Xw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.6", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.4.0", + "react": ">= 16.8.0", + "typescript": "^5" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/react-markdown": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", + "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.17.0.tgz", + "integrity": "sha512-FDELK7rTMlCHO5+reyXsPlmfr7N1F91lPHsWYfMEGQm/KQ+F4JFM8jGoeQDmDvdTs93Fw9aSilH+uKRb4/jXvQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.17.0.tgz", + "integrity": "sha512-fyU2yjGups/hE6Xz0I5ZYbVL8Gx29eCjgpHaRaTaVU+OOAdfRX05KsvyRm0GO8YQwOkhpU3MurW1jyMUJn+zSw==", + "license": "MIT", + "dependencies": { + "react-router": "7.17.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-smooth": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", + "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", + "license": "MIT", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/recharts": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz", + "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==", + "deprecated": "1.x and 2.x branches are no longer active. Bump to Recharts v3 to receive latest features and bugfixes. See https://github.com/recharts/recharts/wiki/3.0-migration-guide", + "license": "MIT", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^18.3.1", + "react-smooth": "^4.0.4", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "license": "MIT", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/rehype-highlight": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.2.tgz", + "integrity": "sha512-k158pK7wdC2qL3M5NcZROZ2tR/l7zOzjxXd5VGdcfIyoijjQqpHd3JKtYSBDpDZ38UI2WJWuFAtkMDxmx5kstA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-text": "^4.0.0", + "lowlight": "^3.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/rollup": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.1.tgz", + "integrity": "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.61.1", + "@rollup/rollup-android-arm64": "4.61.1", + "@rollup/rollup-darwin-arm64": "4.61.1", + "@rollup/rollup-darwin-x64": "4.61.1", + "@rollup/rollup-freebsd-arm64": "4.61.1", + "@rollup/rollup-freebsd-x64": "4.61.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", + "@rollup/rollup-linux-arm-musleabihf": "4.61.1", + "@rollup/rollup-linux-arm64-gnu": "4.61.1", + "@rollup/rollup-linux-arm64-musl": "4.61.1", + "@rollup/rollup-linux-loong64-gnu": "4.61.1", + "@rollup/rollup-linux-loong64-musl": "4.61.1", + "@rollup/rollup-linux-ppc64-gnu": "4.61.1", + "@rollup/rollup-linux-ppc64-musl": "4.61.1", + "@rollup/rollup-linux-riscv64-gnu": "4.61.1", + "@rollup/rollup-linux-riscv64-musl": "4.61.1", + "@rollup/rollup-linux-s390x-gnu": "4.61.1", + "@rollup/rollup-linux-x64-gnu": "4.61.1", + "@rollup/rollup-linux-x64-musl": "4.61.1", + "@rollup/rollup-openbsd-x64": "4.61.1", + "@rollup/rollup-openharmony-arm64": "4.61.1", + "@rollup/rollup-win32-arm64-msvc": "4.61.1", + "@rollup/rollup-win32-ia32-msvc": "4.61.1", + "@rollup/rollup-win32-x64-gnu": "4.61.1", + "@rollup/rollup-win32-x64-msvc": "4.61.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tailwind-merge": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz", + "integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.61.0.tgz", + "integrity": "sha512-8y31Rd0eGTrDKqhy6vT0HtzhN+YLjQizwX3aA3hPXP/ynSfnrBXcQY5IzsP9/DM7+klX4IUncZZjkchP0z+rUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.61.0", + "@typescript-eslint/parser": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/vite": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", + "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-tsconfig-paths": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz", + "integrity": "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zustand": { + "version": "5.0.14", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.14.tgz", + "integrity": "sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/web/daisy/package.json b/web/daisy/package.json new file mode 100644 index 000000000..e946d6332 --- /dev/null +++ b/web/daisy/package.json @@ -0,0 +1,54 @@ +{ + "name": "modelstoken-daisy", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview", + "check": "tsc -b --noEmit" + }, + "dependencies": { + "axios": "^1.9.0", + "clsx": "^2.1.1", + "daisyui": "^5.0.0", + "i18next": "^24.2.2", + "i18next-browser-languagedetector": "^8.0.4", + "lucide-react": "^0.511.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-hook-form": "^7.56.4", + "react-hot-toast": "^2.5.2", + "react-i18next": "^15.5.2", + "react-markdown": "^10.1.0", + "react-router-dom": "^7.3.0", + "recharts": "^2.15.3", + "rehype-highlight": "^7.0.2", + "remark-gfm": "^4.0.1", + "@tanstack/react-query": "^5.77.0", + "tailwind-merge": "^3.0.2", + "zod": "^3.25.0", + "zustand": "^5.0.3" + }, + "devDependencies": { + "@eslint/js": "^9.25.0", + "@tailwindcss/vite": "^4.1.0", + "@types/node": "^22.15.30", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.4.1", + "autoprefixer": "^10.4.21", + "eslint": "^9.25.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^16.0.0", + "postcss": "^8.5.3", + "tailwindcss": "^4.1.0", + "typescript": "~5.8.3", + "typescript-eslint": "^8.30.1", + "vite": "^6.3.5", + "vite-tsconfig-paths": "^5.1.4" + } +} diff --git a/web/daisy/public/favicon.svg b/web/daisy/public/favicon.svg new file mode 100644 index 000000000..c04c3c179 --- /dev/null +++ b/web/daisy/public/favicon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/daisy/src/App.tsx b/web/daisy/src/App.tsx new file mode 100644 index 000000000..bcfd99740 --- /dev/null +++ b/web/daisy/src/App.tsx @@ -0,0 +1,112 @@ +import { Routes, Route } from 'react-router-dom' +import AppLayout from '@/components/layout/AppLayout' + +// Public pages +import Home from '@/pages/public/Home' +import Login from '@/pages/public/Login' +import Register from '@/pages/public/Register' +import ForgotPassword from '@/pages/public/ForgotPassword' +import ResetPassword from '@/pages/public/ResetPassword' +import Setup from '@/pages/public/Setup' +import Pricing from '@/pages/public/Pricing' +import About from '@/pages/public/About' +import UserAgreement from '@/pages/public/UserAgreement' +import PrivacyPolicy from '@/pages/public/PrivacyPolicy' +import OAuthCallback from '@/pages/public/OAuthCallback' +import NotFound from '@/pages/NotFound' + +// User pages +import Dashboard from '@/pages/dashboard/Dashboard' +import TokenList from '@/pages/tokens/TokenList' +import Wallet from '@/pages/wallet/Wallet' +import MySubscription from '@/pages/subscriptions/MySubscription' +import LogList from '@/pages/logs/LogList' +import MidjourneyLog from '@/pages/logs/MidjourneyLog' +import TaskLog from '@/pages/logs/TaskLog' +import Profile from '@/pages/profile/Profile' +import DocCenter from '@/pages/docs/DocCenter' +import DocViewer from '@/pages/docs/DocViewer' +import DocEditor from '@/pages/docs/DocEditor' +import Playground from '@/pages/playground/Playground' + +// Admin pages +import ChannelList from '@/pages/admin/ChannelList' +import UserList from '@/pages/admin/UserList' +import RedemptionList from '@/pages/admin/RedemptionList' +import ModelList from '@/pages/admin/ModelList' +import VendorList from '@/pages/admin/VendorList' +import DeploymentList from '@/pages/admin/DeploymentList' +import SubscriptionAdmin from '@/pages/admin/SubscriptionAdmin' + +// Settings pages +import SettingsLayout from '@/pages/settings/SettingsLayout' +import SiteSettings from '@/pages/settings/SiteSettings' +import AuthSettings from '@/pages/settings/AuthSettings' +import BillingSettings from '@/pages/settings/BillingSettings' +import ContentSettings from '@/pages/settings/ContentSettings' +import ModelSettings from '@/pages/settings/ModelSettings' +import OperationsSettings from '@/pages/settings/OperationsSettings' +import SecuritySettings from '@/pages/settings/SecuritySettings' +import DocSettings from '@/pages/settings/DocSettings' + +function App() { + return ( + + {/* Public routes */} + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + {/* Authenticated routes */} + }> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + {/* Admin routes */} + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + {/* Root routes - Settings */} + }> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + {/* 404 */} + } /> + + ) +} + +export default App diff --git a/web/daisy/src/api/admin-subscription.ts b/web/daisy/src/api/admin-subscription.ts new file mode 100644 index 000000000..c489e79a5 --- /dev/null +++ b/web/daisy/src/api/admin-subscription.ts @@ -0,0 +1,27 @@ +import { get, post, put, del } from './client' +import type { SubscriptionPlan, SubscriptionOrder } from '@/types/subscription' +import type { PaginatedResponse } from '@/types/api' + +export function getAdminPlans() { + return get('/subscription/admin/plans') +} + +export function createPlan(data: Partial) { + return post('/subscription/admin/plans', data) +} + +export function updatePlan(data: Partial) { + return put(`/subscription/admin/plans/${data.id}`, data) +} + +export function deletePlan(id: number) { + return del<{ success: boolean }>(`/subscription/admin/plans/${id}`) +} + +export function getUserSubscriptions(params: Record = {}) { + return get>('/subscription/admin/subscriptions', params) +} + +export function bindSubscription(data: { user_id: number; plan_id: number }) { + return post<{ success: boolean; message: string }>('/subscription/admin/bind', data) +} diff --git a/web/daisy/src/api/admin-user.ts b/web/daisy/src/api/admin-user.ts new file mode 100644 index 000000000..8e27ab388 --- /dev/null +++ b/web/daisy/src/api/admin-user.ts @@ -0,0 +1,35 @@ +import { get, post, put, del } from './client' +import type { User } from '@/types/user' +import type { PaginatedResponse } from '@/types/api' + +export function getUsers(page = 1, size = 10, search = '') { + return get>('/user/', { + page, + page_size: size, + keyword: search, + }) +} + +export function searchUsers(params: Record = {}) { + return get>('/user/search', params) +} + +export function getUser(id: number) { + return get(`/user/${id}`) +} + +export function createUser(data: Partial & { password: string }) { + return post('/user/', data) +} + +export function updateUser(data: Partial) { + return put(`/user/${data.id}`, data) +} + +export function deleteUser(id: number) { + return del<{ success: boolean }>(`/user/${id}`) +} + +export function manageUser(id: number, action: string) { + return post<{ success: boolean; message: string }>(`/user/manage`, { id, action }) +} diff --git a/web/daisy/src/api/auth.ts b/web/daisy/src/api/auth.ts new file mode 100644 index 000000000..fb0b422ee --- /dev/null +++ b/web/daisy/src/api/auth.ts @@ -0,0 +1,74 @@ +import { get, post } from '@/api/client' +import type { ApiResponse } from '@/types/api' + +export interface LoginRequest { + username: string + password: string +} + +export interface RegisterRequest { + username: string + password: string + email: string + aff_code?: string +} + +export interface SetupRequest { + username: string + password: string + server_address?: string +} + +export interface SystemStatus { + success: boolean + message: string + data: { + system_name: string + logo: string + footer_html: string + version: string + registration_enabled: boolean + password_login_enabled: boolean + password_register_enabled: boolean + email_verification_enabled: boolean + github_oauth_enabled: boolean + discord_oauth_enabled: boolean + oidc_enabled: boolean + wechat_enabled: boolean + telegram_enabled: boolean + linux_do_enabled: boolean + turnstile_check_enabled: boolean + turnstile_site_key: string + aff_enabled: boolean + setup: boolean + } +} + +export async function login(username: string, password: string) { + return post('/user/login', { username, password }) +} + +export async function register(username: string, email: string, password: string, affCode?: string) { + return post('/user/register', { + username, + password, + email, + aff_code: affCode, + }) +} + +export async function sendResetEmail(email: string) { + return get('/reset_password', { email }) +} + +export async function resetPassword(token: string, password: string) { + return post('/user/reset', { token, password }) +} + +export async function getSystemStatus() { + return get('/status') +} + +export async function setup(data: SetupRequest) { + return post('/setup', data) +} diff --git a/web/daisy/src/api/channel.ts b/web/daisy/src/api/channel.ts new file mode 100644 index 000000000..bf5711597 --- /dev/null +++ b/web/daisy/src/api/channel.ts @@ -0,0 +1,51 @@ +import { get, post, put, del } from './client' +import type { Channel } from '@/types/channel' +import type { PaginatedResponse } from '@/types/api' + +export function getChannels(page = 1, size = 10, search = '') { + return get>('/channel/', { + page, + page_size: size, + keyword: search, + }) +} + +export function searchChannels(params: Record = {}) { + return get>('/channel/search', params) +} + +export function getChannel(id: number) { + return get(`/channel/${id}`) +} + +export function createChannel(data: Partial) { + return post('/channel/', data) +} + +export function updateChannel(data: Partial) { + return put(`/channel/${data.id}`, data) +} + +export function deleteChannel(id: number) { + return del<{ success: boolean }>(`/channel/${id}`) +} + +export function testChannel(id: number) { + return get<{ success: boolean; message: string; time: number }>(`/channel/test/${id}`) +} + +export function updateChannelBalance(id: number) { + return get<{ success: boolean; balance: number }>(`/channel/update_balance/${id}`) +} + +export function fetchChannelModels(id: number) { + return get<{ success: boolean; models: string[] }>(`/channel/fetch_models/${id}`) +} + +export function batchDeleteChannels(ids: number[]) { + return post<{ success: boolean }>('/channel/batch_delete', { ids }) +} + +export function batchTagChannels(ids: number[], tag: string) { + return post<{ success: boolean }>('/channel/batch_tag', { ids, tag }) +} diff --git a/web/daisy/src/api/client.ts b/web/daisy/src/api/client.ts new file mode 100644 index 000000000..39ace1489 --- /dev/null +++ b/web/daisy/src/api/client.ts @@ -0,0 +1,60 @@ +import axios from 'axios' + +const client = axios.create({ + baseURL: import.meta.env.VITE_API_BASE_URL || '/api', + withCredentials: true, + headers: { + 'Content-Type': 'application/json', + }, +}) + +// Request interceptor +client.interceptors.request.use( + (config) => { + const uid = localStorage.getItem('uid') + if (uid) { + config.headers['New-Api-User'] = uid + } + return config + }, + (error) => { + return Promise.reject(error) + } +) + +// Response interceptor +client.interceptors.response.use( + (response) => { + return response + }, + (error) => { + if (error.response?.status === 401) { + localStorage.removeItem('uid') + localStorage.removeItem('user') + window.location.href = '/login' + } + return Promise.reject(error) + } +) + +export async function get(url: string, params?: Record): Promise { + const response = await client.get(url, { params }) + return response.data +} + +export async function post(url: string, data?: unknown): Promise { + const response = await client.post(url, data) + return response.data +} + +export async function put(url: string, data?: unknown): Promise { + const response = await client.put(url, data) + return response.data +} + +export async function del(url: string): Promise { + const response = await client.delete(url) + return response.data +} + +export default client diff --git a/web/daisy/src/api/deployment.ts b/web/daisy/src/api/deployment.ts new file mode 100644 index 000000000..49fcab891 --- /dev/null +++ b/web/daisy/src/api/deployment.ts @@ -0,0 +1,44 @@ +import { get, post, put, del } from './client' +import type { PaginatedResponse } from '@/types/api' + +export interface Deployment { + id: number + name: string + status: string + hardware: string + location: string + created_at: number + updated_at: number +} + +export function getDeployments(page = 1, size = 10, search = '') { + return get>('/deployments/', { + page, + page_size: size, + keyword: search, + }) +} + +export function searchDeployments(params: Record = {}) { + return get>('/deployments/search', params) +} + +export function createDeployment(data: Partial) { + return post('/deployments/', data) +} + +export function updateDeployment(data: Partial) { + return put(`/deployments/${data.id}`, data) +} + +export function deleteDeployment(id: number) { + return del<{ success: boolean }>(`/deployments/${id}`) +} + +export function getDeploymentLogs(id: number) { + return get<{ logs: string[] }>(`/deployments/${id}/logs`) +} + +export function getDeploymentContainers(id: number) { + return get<{ containers: Record[] }>(`/deployments/${id}/containers`) +} diff --git a/web/daisy/src/api/doc.ts b/web/daisy/src/api/doc.ts new file mode 100644 index 000000000..f9ea84371 --- /dev/null +++ b/web/daisy/src/api/doc.ts @@ -0,0 +1,43 @@ +import { get, post, put, del } from './client' +import type { Doc, DocCategory, DocVersion } from '@/types/doc' +import type { PaginatedResponse } from '@/types/api' + +export function getCategories() { + return get('/docs/categories') +} + +export function createCategory(data: Partial) { + return post('/docs/categories', data) +} + +export function updateCategory(id: number, data: Partial) { + return put(`/docs/categories/${id}`, data) +} + +export function deleteCategory(id: number) { + return del<{ success: boolean }>(`/docs/categories/${id}`) +} + +export function getDocs(params?: { category?: string; search?: string; page?: number; page_size?: number }) { + return get>('/docs/', params) +} + +export function getDoc(slug: string) { + return get(`/docs/${slug}`) +} + +export function createDoc(data: Partial) { + return post('/docs/', data) +} + +export function updateDoc(id: number, data: Partial) { + return put(`/docs/${id}`, data) +} + +export function deleteDoc(id: number) { + return del<{ success: boolean }>(`/docs/${id}`) +} + +export function getDocVersions(id: number) { + return get(`/docs/${id}/versions`) +} diff --git a/web/daisy/src/api/log.ts b/web/daisy/src/api/log.ts new file mode 100644 index 000000000..669eb5aad --- /dev/null +++ b/web/daisy/src/api/log.ts @@ -0,0 +1,47 @@ +import { get } from './client' +import type { Log } from '@/types/log' +import type { PaginatedResponse } from '@/types/api' + +export interface LogSearchParams { + [key: string]: unknown + page?: number + page_size?: number + keyword?: string + start_time?: number + end_time?: number + model_name?: string + token_name?: string + type?: number +} + +export interface LogStat { + quota: number + count: number + token_used: number +} + +export interface LogStatData { + days: string[] + quota_data: number[] + count_data: number[] +} + +export function getSelfLogs(params: LogSearchParams = {}) { + return get>('/log/self/', params) +} + +export function searchSelfLogs(params: LogSearchParams = {}) { + return get>('/log/self/search', params) +} + +export function getSelfLogStat() { + return get('/log/self/stat') +} + +export function getMidjourneyLogs(params: { page?: number; page_size?: number } = {}) { + return get>>('/mj/self', params) +} + +export function getTaskLogs(params: { page?: number; page_size?: number } = {}) { + return get>>('/task/self', params) +} diff --git a/web/daisy/src/api/model.ts b/web/daisy/src/api/model.ts new file mode 100644 index 000000000..c7934d32c --- /dev/null +++ b/web/daisy/src/api/model.ts @@ -0,0 +1,45 @@ +import { get, post, put, del } from './client' +import type { PaginatedResponse } from '@/types/api' + +export interface ModelMeta { + id: number + model_id: string + owner: string + enabled: boolean + input_price: number + output_price: number + description: string + created_at: number +} + +export function getModels(page = 1, size = 10, search = '') { + return get>('/models/', { + page, + page_size: size, + keyword: search, + }) +} + +export function searchModels(params: Record = {}) { + return get>('/models/search', params) +} + +export function createModel(data: Partial) { + return post('/models/', data) +} + +export function updateModel(data: Partial) { + return put(`/models/${data.id}`, data) +} + +export function deleteModel(id: number) { + return del<{ success: boolean }>(`/models/${id}`) +} + +export function syncModelsFromUpstream() { + return post<{ success: boolean; count: number }>('/models/sync') +} + +export function getMissingModels() { + return get<{ models: string[] }>('/models/missing') +} diff --git a/web/daisy/src/api/option.ts b/web/daisy/src/api/option.ts new file mode 100644 index 000000000..aaff06e81 --- /dev/null +++ b/web/daisy/src/api/option.ts @@ -0,0 +1,10 @@ +import { get, put } from './client' +import type { OptionGroup } from '@/types/option' + +export function getOptions() { + return get('/option/') +} + +export function updateOption(data: OptionGroup) { + return put<{ success: boolean; message: string }>('/option/', data) +} diff --git a/web/daisy/src/api/public.ts b/web/daisy/src/api/public.ts new file mode 100644 index 000000000..1e72776fe --- /dev/null +++ b/web/daisy/src/api/public.ts @@ -0,0 +1,52 @@ +import { get } from '@/api/client' + +export interface PricingModel { + model_name: string + model_owner: string + input_price: number + output_price: number + context_length: number + channel_type: number + group: string +} + +export interface PricingResponse { + success: boolean + message: string + data: PricingModel[] +} + +export interface AboutResponse { + success: boolean + message: string + data: { + version: string + commit_hash: string + build_time: string + license: string + repository: string + based_on: string + } +} + +export interface ContentResponse { + success: boolean + message: string + data: string +} + +export async function getPricing() { + return get('/pricing') +} + +export async function getAbout() { + return get('/about') +} + +export async function getUserAgreement() { + return get('/user-agreement') +} + +export async function getPrivacyPolicy() { + return get('/privacy-policy') +} diff --git a/web/daisy/src/api/redemption.ts b/web/daisy/src/api/redemption.ts new file mode 100644 index 000000000..872235977 --- /dev/null +++ b/web/daisy/src/api/redemption.ts @@ -0,0 +1,41 @@ +import { get, post, put, del } from './client' +import type { PaginatedResponse } from '@/types/api' + +export interface Redemption { + id: number + name: string + key: string + quota: number + used_count: number + status: number + created_time: number + redeemed_time: number +} + +export function getRedemptions(page = 1, size = 10, search = '') { + return get>('/redemption/', { + page, + page_size: size, + keyword: search, + }) +} + +export function searchRedemptions(params: Record = {}) { + return get>('/redemption/search', params) +} + +export function createRedemption(data: Partial) { + return post('/redemption/', data) +} + +export function updateRedemption(data: Partial) { + return put(`/redemption/${data.id}`, data) +} + +export function deleteRedemption(id: number) { + return del<{ success: boolean }>(`/redemption/${id}`) +} + +export function batchDeleteInvalidRedemptions() { + return post<{ success: boolean; count: number }>('/redemption/batch_delete_invalid') +} diff --git a/web/daisy/src/api/subscription.ts b/web/daisy/src/api/subscription.ts new file mode 100644 index 000000000..14bfbd115 --- /dev/null +++ b/web/daisy/src/api/subscription.ts @@ -0,0 +1,34 @@ +import { get, post } from './client' +import type { SubscriptionPlan, SubscriptionOrder } from '@/types/subscription' + +export function getPlans() { + return get('/subscription/plans') +} + +export function getSelfSubscription() { + return get('/subscription/self') +} + +export function updatePreference(preference: string) { + return post<{ success: boolean }>('/subscription/preference', { preference }) +} + +export function balancePay(planId: number) { + return post<{ success: boolean; message: string }>('/subscription/pay/balance', { plan_id: planId }) +} + +export function epayPay(planId: number, method: string) { + return post<{ url: string }>('/subscription/pay/epay', { plan_id: planId, method }) +} + +export function stripePay(planId: number) { + return post<{ url: string }>('/subscription/pay/stripe', { plan_id: planId }) +} + +export function creemPay(planId: number) { + return post<{ url: string }>('/subscription/pay/creem', { plan_id: planId }) +} + +export function waffoPancakePay(planId: number) { + return post<{ url: string }>('/subscription/pay/waffo-pancake', { plan_id: planId }) +} diff --git a/web/daisy/src/api/token.ts b/web/daisy/src/api/token.ts new file mode 100644 index 000000000..ee2e4147c --- /dev/null +++ b/web/daisy/src/api/token.ts @@ -0,0 +1,35 @@ +import { get, post, put, del } from './client' +import type { Token } from '@/types/token' +import type { PaginatedResponse } from '@/types/api' + +export function getTokens(page = 1, size = 10, search = '') { + return get>('/token/', { + page, + page_size: size, + keyword: search, + }) +} + +export function getToken(id: number) { + return get(`/token/${id}`) +} + +export function createToken(data: Partial) { + return post('/token/', data) +} + +export function updateToken(data: Partial) { + return put(`/token/${data.id}`, data) +} + +export function deleteToken(id: number) { + return del<{ success: boolean }>(`/token/${id}`) +} + +export function batchDelete(ids: number[]) { + return del<{ success: boolean }>('/token/batch', ) +} + +export function getTokenKey(id: number) { + return get<{ key: string }>(`/token/${id}/key`) +} diff --git a/web/daisy/src/api/user.ts b/web/daisy/src/api/user.ts new file mode 100644 index 000000000..bae9d9351 --- /dev/null +++ b/web/daisy/src/api/user.ts @@ -0,0 +1,38 @@ +import { get, put, del, post } from './client' +import type { User } from '@/types/user' + +export function getSelf() { + return get('/user/self') +} + +export function updateSelf(data: Partial & { password?: string; old_password?: string }) { + return put<{ success: boolean; message: string }>('/user/self', data) +} + +export function deleteSelf() { + return del<{ success: boolean; message: string }>('/user/self') +} + +export function get2FAStatus() { + return get<{ enabled: boolean }>('/user/2fa/status') +} + +export function setup2FA() { + return get<{ secret: string; url: string; qr_code: string }>('/user/2fa/setup') +} + +export function enable2FA(code: string) { + return post<{ success: boolean; message: string }>('/user/2fa/enable', { code }) +} + +export function disable2FA(code: string) { + return post<{ success: boolean; message: string }>('/user/2fa/disable', { code }) +} + +export function regenerateBackupCodes() { + return post<{ codes: string[] }>('/user/2fa/backup-codes/regenerate') +} + +export function generateAccessToken() { + return post<{ token: string }>('/user/token') +} diff --git a/web/daisy/src/api/vendor.ts b/web/daisy/src/api/vendor.ts new file mode 100644 index 000000000..2061604d6 --- /dev/null +++ b/web/daisy/src/api/vendor.ts @@ -0,0 +1,33 @@ +import { get, post, put, del } from './client' +import type { PaginatedResponse } from '@/types/api' + +export interface Vendor { + id: number + name: string + description: string + created_at: number +} + +export function getVendors(page = 1, size = 10, search = '') { + return get>('/vendors/', { + page, + page_size: size, + keyword: search, + }) +} + +export function searchVendors(params: Record = {}) { + return get>('/vendors/search', params) +} + +export function createVendor(data: Partial) { + return post('/vendors/', data) +} + +export function updateVendor(data: Partial) { + return put(`/vendors/${data.id}`, data) +} + +export function deleteVendor(id: number) { + return del<{ success: boolean }>(`/vendors/${id}`) +} diff --git a/web/daisy/src/api/wallet.ts b/web/daisy/src/api/wallet.ts new file mode 100644 index 000000000..cf3aff768 --- /dev/null +++ b/web/daisy/src/api/wallet.ts @@ -0,0 +1,52 @@ +import { get, post } from './client' + +export interface TopUpInfo { + epay_enabled: boolean + stripe_enabled: boolean + creem_enabled: boolean + waffo_enabled: boolean + checkin_enabled: boolean + min_amount: number + discount: number + discount_msg: string +} + +export function getTopUpInfo() { + return get('/user/topup/info') +} + +export function redeemCode(code: string) { + return post<{ success: boolean; message: string }>('/user/topup', { key: code }) +} + +export function epayPay(amount: number, method: string) { + return post<{ url: string }>('/user/topup/epay', { amount, method }) +} + +export function stripePay(amount: number) { + return post<{ url: string }>('/user/topup/stripe', { amount }) +} + +export function creemPay(amount: number) { + return post<{ url: string }>('/user/topup/creem', { amount }) +} + +export function waffoPay(amount: number) { + return post<{ url: string }>('/user/topup/waffo', { amount }) +} + +export function waffoPancakePay(amount: number) { + return post<{ url: string }>('/user/topup/waffo-pancake', { amount }) +} + +export function checkIn() { + return post<{ success: boolean; message: string; quota: number }>('/user/checkin') +} + +export function getCheckInStatus() { + return get<{ checked_in: boolean; quota: number }>('/user/checkin/status') +} + +export function transferAffQuota(quota: number) { + return post<{ success: boolean; message: string }>('/user/aff_quota', { quota }) +} diff --git a/web/daisy/src/assets/react.svg b/web/daisy/src/assets/react.svg new file mode 100644 index 000000000..6c87de9bb --- /dev/null +++ b/web/daisy/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/daisy/src/components/common/ConfirmDialog.tsx b/web/daisy/src/components/common/ConfirmDialog.tsx new file mode 100644 index 000000000..c5bc905f4 --- /dev/null +++ b/web/daisy/src/components/common/ConfirmDialog.tsx @@ -0,0 +1,49 @@ +import { useTranslation } from 'react-i18next' + +interface ConfirmDialogProps { + open: boolean + title?: string + message: string + confirmLabel?: string + cancelLabel?: string + variant?: 'error' | 'warning' | 'info' + onConfirm: () => void + onCancel: () => void +} + +export default function ConfirmDialog({ + open, + title, + message, + confirmLabel, + cancelLabel, + variant = 'error', + onConfirm, + onCancel, +}: ConfirmDialogProps) { + const { t } = useTranslation() + + if (!open) return null + + const btnClass = variant === 'error' ? 'btn-error' : variant === 'warning' ? 'btn-warning' : 'btn-primary' + + return ( + +
+

{title || t('common.confirm')}

+

{message}

+
+ + +
+
+
+ +
+
+ ) +} diff --git a/web/daisy/src/components/common/DataTable.tsx b/web/daisy/src/components/common/DataTable.tsx new file mode 100644 index 000000000..766cf2609 --- /dev/null +++ b/web/daisy/src/components/common/DataTable.tsx @@ -0,0 +1,180 @@ +import { useState } from 'react' +import { useTranslation } from 'react-i18next' +import { ChevronUp, ChevronDown, ChevronsUpDown } from 'lucide-react' +import { cn } from '@/lib/utils' +import LoadingSpinner from './LoadingSpinner' + +export interface Column { + key: string + header: React.ReactNode + render?: (row: T) => React.ReactNode + sortable?: boolean + width?: string + align?: 'left' | 'center' | 'right' +} + +interface DataTableProps { + columns: Column[] + data: T[] + loading?: boolean + emptyText?: string + total?: number + page?: number + pageSize?: number + onPageChange?: (page: number) => void + onPageSizeChange?: (size: number) => void + onSort?: (key: string, order: 'asc' | 'desc') => void + rowKey?: (row: T) => string | number + className?: string +} + +export default function DataTable>({ + columns, + data, + loading = false, + emptyText, + total = 0, + page = 1, + pageSize = 10, + onPageChange, + onPageSizeChange, + onSort, + rowKey, + className, +}: DataTableProps) { + const { t } = useTranslation() + const [sortKey, setSortKey] = useState('') + const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc') + + const totalPages = Math.ceil(total / pageSize) + + const handleSort = (key: string) => { + const newOrder = sortKey === key && sortOrder === 'asc' ? 'desc' : 'asc' + setSortKey(key) + setSortOrder(newOrder) + onSort?.(key, newOrder) + } + + const getSortIcon = (key: string) => { + if (sortKey !== key) return + return sortOrder === 'asc' ? : + } + + return ( +
+ + + + {columns.map((col) => ( + + ))} + + + + {loading ? ( + + + + ) : data.length === 0 ? ( + + + + ) : ( + data.map((row, index) => ( + + {columns.map((col) => ( + + ))} + + )) + )} + +
col.sortable && handleSort(col.key)} + > + + {col.header} + {col.sortable && getSortIcon(col.key)} + +
+ +
+ {emptyText || t('common.noData')} +
+ {col.render ? col.render(row) : (row[col.key] as React.ReactNode) ?? '-'} +
+ + {/* Pagination */} + {total > 0 && ( +
+
+ {t('common.total')} {total} {t('common.items')} +
+
+ +
+ + {Array.from({ length: Math.min(5, totalPages) }, (_, i) => { + let pageNum: number + if (totalPages <= 5) { + pageNum = i + 1 + } else if (page <= 3) { + pageNum = i + 1 + } else if (page >= totalPages - 2) { + pageNum = totalPages - 4 + i + } else { + pageNum = page - 2 + i + } + return ( + + ) + })} + +
+
+
+ )} +
+ ) +} diff --git a/web/daisy/src/components/common/LoadingSpinner.tsx b/web/daisy/src/components/common/LoadingSpinner.tsx new file mode 100644 index 000000000..5f0b2ac02 --- /dev/null +++ b/web/daisy/src/components/common/LoadingSpinner.tsx @@ -0,0 +1,22 @@ +import { cn } from '@/lib/utils' + +interface LoadingSpinnerProps { + size?: 'sm' | 'md' | 'lg' + className?: string + text?: string +} + +const sizeClasses = { + sm: 'loading-sm', + md: 'loading-md', + lg: 'loading-lg', +} + +export default function LoadingSpinner({ size = 'md', className, text }: LoadingSpinnerProps) { + return ( +
+ + {text && {text}} +
+ ) +} diff --git a/web/daisy/src/components/common/PageHeader.tsx b/web/daisy/src/components/common/PageHeader.tsx new file mode 100644 index 000000000..b50dca527 --- /dev/null +++ b/web/daisy/src/components/common/PageHeader.tsx @@ -0,0 +1,20 @@ +import { cn } from '@/lib/utils' + +interface PageHeaderProps { + title: string + description?: string + actions?: React.ReactNode + className?: string +} + +export default function PageHeader({ title, description, actions, className }: PageHeaderProps) { + return ( +
+
+

{title}

+ {description &&

{description}

} +
+ {actions &&
{actions}
} +
+ ) +} diff --git a/web/daisy/src/components/common/QuotaDisplay.tsx b/web/daisy/src/components/common/QuotaDisplay.tsx new file mode 100644 index 000000000..94cb0cc09 --- /dev/null +++ b/web/daisy/src/components/common/QuotaDisplay.tsx @@ -0,0 +1,25 @@ +import { renderQuota } from '@/lib/quota' +import { cn } from '@/lib/utils' + +interface QuotaDisplayProps { + quota: number + displayInCurrency?: boolean + className?: string + showUnit?: boolean +} + +export default function QuotaDisplay({ + quota, + displayInCurrency = true, + className, + showUnit = false, +}: QuotaDisplayProps) { + const formatted = renderQuota(quota, displayInCurrency) + + return ( + + {formatted} + {showUnit && !displayInCurrency && quota} + + ) +} diff --git a/web/daisy/src/components/common/SearchInput.tsx b/web/daisy/src/components/common/SearchInput.tsx new file mode 100644 index 000000000..b206eea72 --- /dev/null +++ b/web/daisy/src/components/common/SearchInput.tsx @@ -0,0 +1,32 @@ +import { Search } from 'lucide-react' +import { useTranslation } from 'react-i18next' +import { cn } from '@/lib/utils' + +interface SearchInputProps { + value: string + onChange: (value: string) => void + placeholder?: string + className?: string +} + +export default function SearchInput({ + value, + onChange, + placeholder, + className, +}: SearchInputProps) { + const { t } = useTranslation() + + return ( + + ) +} diff --git a/web/daisy/src/components/common/StatusBadge.tsx b/web/daisy/src/components/common/StatusBadge.tsx new file mode 100644 index 000000000..8cb1af2d0 --- /dev/null +++ b/web/daisy/src/components/common/StatusBadge.tsx @@ -0,0 +1,36 @@ +import { cn } from '@/lib/utils' + +type BadgeVariant = 'success' | 'warning' | 'error' | 'neutral' | 'info' + +interface StatusBadgeProps { + variant: BadgeVariant + label: string + className?: string + size?: 'xs' | 'sm' | 'md' | 'lg' +} + +const variantClasses: Record = { + success: 'badge-success', + warning: 'badge-warning', + error: 'badge-error', + neutral: 'badge-ghost', + info: 'badge-info', +} + +export default function StatusBadge({ variant, label, className, size = 'sm' }: StatusBadgeProps) { + return ( + + {label} + + ) +} diff --git a/web/daisy/src/components/layout/AppLayout.tsx b/web/daisy/src/components/layout/AppLayout.tsx new file mode 100644 index 000000000..c898322e9 --- /dev/null +++ b/web/daisy/src/components/layout/AppLayout.tsx @@ -0,0 +1,34 @@ +import { Outlet } from 'react-router-dom' +import Navbar from './Navbar' +import Sidebar from './Sidebar' +import { useUIStore } from '@/stores/ui' + +export default function AppLayout() { + const { sidebarOpen, setSidebarOpen, sidebarCollapsed } = useUIStore() + + return ( +
+
+ setSidebarOpen(e.target.checked)} + /> + +
+ +
+ +
+
+ +
+
+
+
+ ) +} diff --git a/web/daisy/src/components/layout/Navbar.tsx b/web/daisy/src/components/layout/Navbar.tsx new file mode 100644 index 000000000..6d93ec40a --- /dev/null +++ b/web/daisy/src/components/layout/Navbar.tsx @@ -0,0 +1,96 @@ +import { useTranslation } from 'react-i18next' +import { useNavigate } from 'react-router-dom' +import { Sun, Moon, Bell, Search, LogOut, User, Settings } from 'lucide-react' +import { useUIStore } from '@/stores/ui' +import { useAuthStore } from '@/stores/auth' +import { usePermission } from '@/hooks/usePermission' + +export default function Navbar() { + const { t } = useTranslation() + const navigate = useNavigate() + const { theme, toggleTheme } = useUIStore() + const { user } = useAuthStore() + const { isAdmin, isRoot } = usePermission() + + const handleLogout = async () => { + await useAuthStore.getState().logout() + navigate('/login') + } + + return ( +
+
+ +
+ +
+ ModelsToken +
+ +
+ {/* Search */} +
+ +
+ + {/* Theme toggle */} + + + {/* Notifications */} + + + {/* User menu */} +
+
+
+ + {user?.display_name?.[0] || user?.username?.[0] || 'U'} + +
+
+ +
+
+
+ ) +} diff --git a/web/daisy/src/components/layout/Sidebar.tsx b/web/daisy/src/components/layout/Sidebar.tsx new file mode 100644 index 000000000..0838f51db --- /dev/null +++ b/web/daisy/src/components/layout/Sidebar.tsx @@ -0,0 +1,176 @@ +import { useLocation } from 'react-router-dom' +import { useTranslation } from 'react-i18next' +import { + LayoutDashboard, + Key, + Wallet, + CreditCard, + ScrollText, + Image, + ListTodo, + User, + Terminal, + BookOpen, + Settings, + Server, + Users, + Gift, + Cpu, + Truck, + Layers, +} from 'lucide-react' +import { usePermission } from '@/hooks/usePermission' +import { cn } from '@/lib/utils' +import { useUIStore } from '@/stores/ui' + +interface NavItem { + label: string + path: string + icon: React.ReactNode + minRole?: number +} + +export default function Sidebar() { + const { t } = useTranslation() + const location = useLocation() + const { isUser, isAdmin, isRoot } = usePermission() + const { setSidebarOpen, sidebarCollapsed } = useUIStore() + + const userNavItems: NavItem[] = [ + { label: t('nav.dashboard'), path: '/dashboard', icon: }, + { label: t('nav.tokens'), path: '/tokens', icon: }, + { label: t('nav.wallet'), path: '/wallet', icon: }, + { label: t('nav.subscriptions'), path: '/subscriptions', icon: }, + { label: t('nav.logs'), path: '/logs', icon: }, + { label: t('nav.midjourney'), path: '/logs/midjourney', icon: }, + { label: t('nav.tasks'), path: '/logs/tasks', icon: }, + { label: t('nav.profile'), path: '/profile', icon: }, + { label: t('nav.playground'), path: '/playground', icon: }, + { label: t('nav.docs'), path: '/docs', icon: }, + ] + + const adminNavItems: NavItem[] = [ + { label: t('nav.channels'), path: '/admin/channels', icon: , minRole: 10 }, + { label: t('nav.users'), path: '/admin/users', icon: , minRole: 10 }, + { label: t('nav.redemptions'), path: '/admin/redemptions', icon: , minRole: 10 }, + { label: t('nav.models'), path: '/admin/models', icon: , minRole: 10 }, + { label: t('nav.vendors'), path: '/admin/vendors', icon: , minRole: 10 }, + { label: t('nav.deployments'), path: '/admin/deployments', icon: , minRole: 10 }, + { label: t('nav.subscriptions'), path: '/admin/subscriptions', icon: , minRole: 10 }, + ] + + const rootNavItems: NavItem[] = [ + { label: t('nav.settings'), path: '/settings/site', icon: , minRole: 100 }, + ] + + const isActive = (path: string) => { + if (path === '/logs') return location.pathname === '/logs' + return location.pathname.startsWith(path) + } + + const handleNavClick = () => { + setSidebarOpen(false) + } + + const filterByRole = (items: NavItem[]) => + items.filter((item) => { + if (!item.minRole) return true + if (item.minRole <= 1) return isUser + if (item.minRole <= 10) return isAdmin + return isRoot + }) + + return ( + + ) +} diff --git a/web/daisy/src/hooks/useAuth.ts b/web/daisy/src/hooks/useAuth.ts new file mode 100644 index 000000000..9f016f4a7 --- /dev/null +++ b/web/daisy/src/hooks/useAuth.ts @@ -0,0 +1,19 @@ +import { useAuthStore } from '@/stores/auth' +import type { User } from '@/types/user' + +export function useAuth() { + const { user, isAuthenticated, isAdmin, isRoot, login, logout, register, fetchUser, setUser } = + useAuthStore() + + return { + user: user as User | null, + isAuthenticated, + isAdmin, + isRoot, + login, + logout, + register, + fetchUser, + setUser, + } +} diff --git a/web/daisy/src/hooks/usePermission.ts b/web/daisy/src/hooks/usePermission.ts new file mode 100644 index 000000000..17a642efe --- /dev/null +++ b/web/daisy/src/hooks/usePermission.ts @@ -0,0 +1,16 @@ +import { useAuthStore } from '@/stores/auth' +import { ROLE_USER, ROLE_ADMIN, ROLE_ROOT } from '@/lib/constants' + +export function usePermission() { + const { user, isAuthenticated, isAdmin, isRoot } = useAuthStore() + + const role = user?.role ?? 0 + + return { + isAuthenticated, + isUser: role >= ROLE_USER, + isAdmin: role >= ROLE_ADMIN, + isRoot: role >= ROLE_ROOT, + role, + } +} diff --git a/web/daisy/src/hooks/useQuota.ts b/web/daisy/src/hooks/useQuota.ts new file mode 100644 index 000000000..fc4d55b35 --- /dev/null +++ b/web/daisy/src/hooks/useQuota.ts @@ -0,0 +1,11 @@ +import { renderQuota, quotaToCurrency, currencyToQuota } from '@/lib/quota' +import { QUOTA_PER_UNIT } from '@/lib/constants' + +export function useQuota() { + return { + renderQuota, + quotaToCurrency, + currencyToQuota, + quotaPerUnit: QUOTA_PER_UNIT, + } +} diff --git a/web/daisy/src/hooks/useSettings.ts b/web/daisy/src/hooks/useSettings.ts new file mode 100644 index 000000000..7751c561a --- /dev/null +++ b/web/daisy/src/hooks/useSettings.ts @@ -0,0 +1,60 @@ +import { useState, useEffect, useCallback } from 'react' +import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' +import toast from 'react-hot-toast' +import { useTranslation } from 'react-i18next' +import { getOptions, updateOption } from '@/api/option' +import type { OptionGroup } from '@/types/option' + +export function useSettings() { + const { t } = useTranslation() + const queryClient = useQueryClient() + const [original, setOriginal] = useState({}) + + const { data, isLoading } = useQuery({ + queryKey: ['options'], + queryFn: getOptions, + }) + + useEffect(() => { + if (data) { + setOriginal(data) + } + }, [data]) + + const saveMut = useMutation({ + mutationFn: updateOption, + onSuccess: () => { + toast.success(t('common.saveSuccess')) + queryClient.invalidateQueries({ queryKey: ['options'] }) + }, + onError: () => { + toast.error(t('common.operationFailed')) + }, + }) + + const save = useCallback( + (changed: Record) => { + // Only send changed keys + const diff: Record = {} + for (const key of Object.keys(changed)) { + if (changed[key] !== original[key]) { + diff[key] = changed[key] + } + } + if (Object.keys(diff).length === 0) { + toast(t('settings.noChanges'), { icon: 'ℹ️' }) + return + } + saveMut.mutate(diff) + }, + [original, saveMut, t] + ) + + return { + options: data ?? {}, + original, + isLoading, + save, + isSaving: saveMut.isPending, + } +} diff --git a/web/daisy/src/i18n/index.ts b/web/daisy/src/i18n/index.ts new file mode 100644 index 000000000..551a7d7f7 --- /dev/null +++ b/web/daisy/src/i18n/index.ts @@ -0,0 +1,27 @@ +import i18n from 'i18next' +import { initReactI18next } from 'react-i18next' +import LanguageDetector from 'i18next-browser-languagedetector' +import en from './locales/en.json' +import zh from './locales/zh.json' + +i18n + .use(LanguageDetector) + .use(initReactI18next) + .init({ + resources: { + en: { translation: en }, + zh: { translation: zh }, + }, + fallbackLng: 'zh', + lng: 'zh', + interpolation: { + escapeValue: false, + }, + detection: { + order: ['localStorage', 'navigator'], + lookupLocalStorage: 'i18nextLng', + caches: ['localStorage'], + }, + }) + +export default i18n diff --git a/web/daisy/src/i18n/locales/en.json b/web/daisy/src/i18n/locales/en.json new file mode 100644 index 000000000..8649cb339 --- /dev/null +++ b/web/daisy/src/i18n/locales/en.json @@ -0,0 +1,625 @@ +{ + "common": { + "appName": "ModelsToken", + "loading": "Loading...", + "save": "Save", + "cancel": "Cancel", + "confirm": "Confirm", + "delete": "Delete", + "edit": "Edit", + "create": "Create", + "search": "Search", + "filter": "Filter", + "refresh": "Refresh", + "reset": "Reset", + "submit": "Submit", + "back": "Back", + "next": "Next", + "previous": "Previous", + "close": "Close", + "export": "Export", + "import": "Import", + "download": "Download", + "upload": "Upload", + "copy": "Copy", + "copied": "Copied!", + "more": "More", + "actions": "Actions", + "status": "Status", + "enabled": "Enabled", + "disabled": "Disabled", + "yes": "Yes", + "no": "No", + "all": "All", + "none": "None", + "success": "Success", + "error": "Error", + "warning": "Warning", + "info": "Info", + "noData": "No data", + "total": "Total", + "items": "items", + "rowsPerPage": "Rows per page", + "page": "Page", + "of": "of", + "sortBy": "Sort by", + "ascending": "Ascending", + "descending": "Descending", + "selected": "Selected", + "bulkActions": "Bulk Actions", + "deleteConfirm": "Are you sure you want to delete?", + "deleteSuccess": "Deleted successfully", + "saveSuccess": "Saved successfully", + "operationSuccess": "Operation successful", + "operationFailed": "Operation failed", + "networkError": "Network error", + "unauthorized": "Unauthorized", + "forbidden": "Forbidden", + "notFound": "Not found", + "serverError": "Server error", + "timeout": "Request timeout", + "leaveEmpty": "Leave empty", + "select": "Select", + "used": "Used", + "createdAt": "Created At", + "sortOrder": "Sort Order" + }, + "nav": { + "dashboard": "Dashboard", + "tokens": "Tokens", + "channels": "Channels", + "users": "Users", + "logs": "Logs", + "wallet": "Wallet", + "subscriptions": "Subscriptions", + "redemptions": "Redemptions", + "models": "Models", + "vendors": "Vendors", + "deployments": "Deployments", + "playground": "Playground", + "docs": "Documentation", + "profile": "Profile", + "settings": "Settings", + "logout": "Logout", + "login": "Login", + "register": "Register", + "about": "About", + "pricing": "Pricing", + "midjourney": "Midjourney", + "tasks": "Tasks" + }, + "auth": { + "loginTitle": "Sign In", + "registerTitle": "Sign Up", + "username": "Username", + "password": "Password", + "confirmPassword": "Confirm Password", + "email": "Email", + "forgotPassword": "Forgot Password?", + "resetPassword": "Reset Password", + "noAccount": "Don't have an account?", + "hasAccount": "Already have an account?", + "signUp": "Sign Up", + "signIn": "Sign In", + "affCode": "Invitation Code", + "verificationCode": "Verification Code", + "sendCode": "Send Code", + "loginSuccess": "Login successful", + "registerSuccess": "Registration successful", + "logoutSuccess": "Logged out successfully", + "passwordMismatch": "Passwords do not match", + "invalidCredentials": "Invalid username or password", + "rememberMe": "Remember me", + "orContinueWith": "Or continue with", + "invalidEmail": "Invalid email format", + "passwordTooShort": "Password must be at least 8 characters", + "resetEmailSent": "Reset email sent", + "resetEmailSentDesc": "A password reset link has been sent to your email", + "forgotPasswordDesc": "Enter your email address and we'll send you a reset link", + "sendResetEmail": "Send Reset Email", + "invalidResetToken": "Invalid reset token", + "resetPasswordSuccess": "Password reset successfully" + }, + "user": { + "id": "ID", + "username": "Username", + "displayName": "Display Name", + "email": "Email", + "role": "Role", + "group": "Group", + "quota": "Quota", + "usedQuota": "Used Quota", + "requestCount": "Request Count", + "status": "Status", + "createdAt": "Created At", + "lastLoginAt": "Last Login", + "affCode": "Invitation Code", + "affCount": "Invitation Count", + "affQuota": "Invitation Quota", + "remark": "Remark", + "roleUser": "User", + "roleAdmin": "Admin", + "roleRoot": "Root" + }, + "token": { + "name": "Token Name", + "key": "Key", + "status": "Status", + "quota": "Quota", + "usedQuota": "Used Quota", + "remainQuota": "Remaining Quota", + "unlimitedQuota": "Unlimited", + "expiredTime": "Expiration", + "createdTime": "Created", + "accessedTime": "Last Accessed", + "modelLimits": "Model Limits", + "modelLimitsEnabled": "Model Limits Enabled", + "allowIps": "Allowed IPs", + "neverExpire": "Never Expire", + "statusEnabled": "Enabled", + "statusDisabled": "Disabled", + "statusExpired": "Expired", + "statusExhausted": "Exhausted", + "createToken": "Create Token", + "copyKey": "Copy Key", + "regenerateKey": "Regenerate Key" + }, + "channel": { + "name": "Channel Name", + "type": "Channel Type", + "status": "Status", + "priority": "Priority", + "weight": "Weight", + "models": "Models", + "group": "Group", + "baseUrl": "Base URL", + "key": "Key", + "testModel": "Test Model", + "responseTime": "Response Time", + "balance": "Balance", + "usedQuota": "Used Quota", + "createdTime": "Created", + "testTime": "Last Test", + "autoBan": "Auto Ban", + "tag": "Tag", + "statusEnabled": "Enabled", + "statusDisabled": "Disabled", + "statusAutoDisabled": "Auto Disabled", + "testChannel": "Test Channel", + "updateBalance": "Update Balance", + "batchTest": "Batch Test", + "fetchModels": "Fetch Models", + "modelMapping": "Model Mapping" + }, + "redemption": { + "name": "Name", + "key": "Redemption Key", + "quota": "Quota", + "usedCount": "Used Count", + "count": "Count", + "batchDeleteInvalid": "Delete Invalid Codes" + }, + "model": { + "modelId": "Model ID", + "owner": "Owner", + "inputPrice": "Input Price", + "outputPrice": "Output Price", + "syncUpstream": "Sync Upstream", + "missingModels": "Missing Models" + }, + "vendor": { + "name": "Name", + "description": "Description" + }, + "deployment": { + "name": "Name", + "hardware": "Hardware", + "location": "Location", + "statusRunning": "Running", + "statusStopped": "Stopped", + "statusError": "Error", + "viewLogs": "View Logs", + "viewContainers": "View Containers" + }, + "log": { + "type": "Type", + "time": "Time", + "user": "User", + "token": "Token", + "model": "Model", + "quota": "Quota", + "promptTokens": "Prompt Tokens", + "completionTokens": "Completion Tokens", + "channel": "Channel", + "duration": "Duration", + "isStream": "Stream", + "group": "Group", + "ip": "IP", + "requestId": "Request ID", + "typeTopup": "Top Up", + "typeConsume": "Consume", + "typeManage": "Manage", + "typeSystem": "System", + "typeError": "Error", + "typeRefund": "Refund", + "totalQuota": "Total Quota Used", + "totalRequests": "Total Requests" + }, + "subscription": { + "title": "Subscription", + "plan": "Plan", + "price": "Price", + "duration": "Duration", + "status": "Status", + "quota": "Quota", + "resetPeriod": "Reset Period", + "purchaseTime": "Purchase Time", + "expireTime": "Expire Time", + "active": "Active", + "expired": "Expired", + "cancelled": "Cancelled", + "durationDay": "Day", + "durationMonth": "Month", + "durationYear": "Year", + "resetNever": "Never", + "resetDaily": "Daily", + "resetWeekly": "Weekly", + "resetMonthly": "Monthly", + "currentPlan": "Current Plan", + "availablePlans": "Available Plans", + "balancePay": "Pay with Balance", + "orderHistory": "Order History", + "bindSubscription": "Bind Subscription", + "userSubscriptions": "User Subscriptions", + "sortOrder": "Sort Order" + }, + "dashboard": { + "quotaTrend": "Quota Usage Trend", + "apiInfo": "API Information", + "serverAddress": "Server Address", + "affCode": "Affiliate Code", + "announcements": "Announcements", + "quickActions": "Quick Actions" + }, + "wallet": { + "title": "Wallet", + "balance": "Balance", + "topUp": "Top Up", + "history": "History", + "redeemCode": "Redeem Code", + "transfer": "Transfer", + "amount": "Amount", + "paymentMethod": "Payment Method", + "transactionId": "Transaction ID", + "onlinePay": "Online Payment", + "checkIn": "Check In", + "checkedInToday": "Checked in today", + "notCheckedIn": "Not checked in today", + "affiliate": "Affiliate", + "transferAmount": "Transfer Amount" + }, + "settings": { + "site": "Site Settings", + "auth": "Authentication", + "billing": "Billing", + "content": "Content", + "models": "Models", + "operations": "Operations", + "security": "Security", + "docs": "Documentation", + "general": "General", + "systemName": "System Name", + "logo": "Logo", + "logoUrl": "Logo URL", + "footer": "Footer HTML", + "theme": "Theme", + "language": "Language", + "noChanges": "No changes", + "basicInfo": "Basic Info", + "contentInfo": "Content", + "legal": "Legal", + "navigation": "Navigation", + "serverAddress": "Server Address", + "notice": "System Notice", + "about": "About", + "homePageContent": "Home Page Content", + "userAgreement": "User Agreement", + "privacyPolicy": "Privacy Policy", + "headerNavModules": "Header Nav Modules", + "sidebarModules": "Sidebar Modules", + "passwordAndReg": "Password & Registration", + "passwordLogin": "Allow Password Login", + "passwordRegister": "Allow Password Registration", + "emailVerification": "Email Verification", + "emailDomainWhitelist": "Email Domain Whitelist", + "emailAlias": "Allow Email Alias", + "minTrustLevel": "Min Trust Level", + "wechatOAuth": "WeChat OAuth", + "quotaConfig": "Quota Config", + "quotaForNewUser": "Quota for New User", + "preConsumedQuota": "Pre-consumed Quota", + "quotaForInviter": "Quota for Inviter", + "quotaForInvitee": "Quota for Invitee", + "freeModelPreConsumed": "Free Model Pre-consumed", + "links": "Links", + "topUpLink": "Top Up Link", + "docLink": "Doc Link", + "currencyConfig": "Currency Config", + "quotaUnit": "Quota Unit", + "quotaExchangeRate": "Exchange Rate", + "currencyDisplay": "Currency Display", + "modelRatio": "Model Ratio", + "modelRatioDesc": "Model ratio config (JSON format)", + "groupRatio": "Group Ratio", + "groupRatioDesc": "Group ratio config (JSON format)", + "epayAddress": "Pay Address", + "epayId": "Merchant ID", + "epayKey": "Merchant Key", + "otherPayment": "Other Payment", + "checkIn": "Check-in", + "checkInEnabled": "Enable Check-in", + "checkInMinQuota": "Min Check-in Quota", + "checkInMaxQuota": "Max Check-in Quota", + "consoleConfig": "Console Config", + "consoleAPIInfoPanel": "API Info Panel", + "noticeAndFAQ": "Notice & FAQ", + "noticeConfig": "Notice Config", + "faqConfig": "FAQ Config", + "uptimeKuma": "Uptime Kuma", + "uptimeKumaMonitorGroups": "Monitor Groups", + "featureToggle": "Feature Toggle", + "chatEnabled": "Enable Chat", + "drawingEnabled": "Enable Drawing", + "midjourneyConfig": "Midjourney Config", + "globalModelConfig": "Global Model Config", + "globalPassthrough": "Global Passthrough", + "thinkingModelBlacklist": "Thinking Model Blacklist", + "chatToResponsesStrategy": "Chat to Responses Strategy", + "pingInterval": "Ping Interval", + "geminiSafety": "Safety Setting", + "geminiVersion": "Version", + "geminiImageModel": "Image Model", + "geminiThinkingAdapter": "Thinking Adapter", + "geminiFunctionCalling": "Function Calling", + "claudeModelHeader": "Model Header", + "claudeDefaultMaxTokens": "Default Max Tokens", + "claudeThinkingAdapter": "Thinking Adapter", + "grokViolationDeduction": "Violation Deduction", + "opsGeneral": "General Operations", + "retryCount": "Retry Count", + "defaultCollapseSidebar": "Default Collapse Sidebar", + "demoMode": "Demo Mode", + "selfUseMode": "Self-use Mode", + "channelAutoMgmt": "Channel Auto Management", + "channelAutoDisable": "Auto Disable Channel", + "channelAutoEnable": "Auto Enable Channel", + "channelDisableThreshold": "Disable Threshold", + "channelDisableKeywords": "Disable Keywords", + "channelDisableStatusCodes": "Disable Status Codes", + "autoRetryStatusCodes": "Auto Retry Status Codes", + "autoTestChannels": "Auto Test Channels", + "smtpConfig": "SMTP Config", + "smtpServer": "SMTP Server", + "smtpPort": "Port", + "smtpAccount": "Account", + "smtpToken": "Token/Password", + "smtpFrom": "From", + "workerConfig": "Worker Config", + "workerURL": "Worker URL", + "workerKey": "Worker Key", + "loggingAndCache": "Logging & Cache", + "logConsume": "Log Consumption", + "diskCacheConfig": "Disk Cache Config", + "performanceMonitorConfig": "Performance Monitor Config", + "rateLimit": "Rate Limit", + "modelRequestRateLimit": "Model Request Rate Limit", + "sensitiveWordCheck": "Sensitive Word Check", + "sensitiveWordCheckEnabled": "Enable Sensitive Word Check", + "sensitiveWordCheckOnPrompt": "Check on Prompt", + "sensitiveWordCheckOnOutput": "Check on Output", + "networkProtection": "Network Protection", + "ssrfProtection": "SSRF Protection", + "privateIPFilter": "Private IP Filter", + "domainIPFilter": "Domain/IP Filter", + "domainFilterMode": "Domain Filter Mode", + "ipFilterMode": "IP Filter Mode", + "whitelist": "Whitelist", + "blacklist": "Blacklist", + "domainFilterList": "Domain Filter List", + "ipFilterList": "IP Filter List", + "portWhitelist": "Port Whitelist", + "portWhitelistDesc": "Allowed ports, comma separated", + "docCategoryMgmt": "Doc Category Management", + "docCategoryConfig": "Category Config", + "docVisibility": "Doc Visibility", + "docDefaultVisibility": "Default Visibility for New Docs", + "docPublic": "Public", + "docPrivate": "Private", + "docUnlisted": "Unlisted", + "docPlaceholder": "Placeholder", + "docPlaceholderContent": "Placeholder Content", + "frontendTheme": "Frontend Theme", + "themeDefault": "Default (New Frontend)", + "themeClassic": "Classic (Legacy Frontend)", + "themeDaisy": "Daisy (DaisyUI Frontend)" + }, + "quota": { + "unit": "Quota", + "unlimited": "Unlimited", + "insufficient": "Insufficient quota", + "display": "Display" + }, + "public": { + "heroSubtitle": "All-in-one AI API management platform, aggregating multiple providers with unified API access", + "getStarted": "Get Started", + "viewPricing": "View Pricing", + "featuresTitle": "Core Features", + "quickStartTitle": "Quick Start", + "allRightsReserved": "All rights reserved", + "feature": { + "apiGateway": "API Gateway", + "apiGatewayDesc": "Unified API entry point, compatible with OpenAI format, seamless switching", + "multiChannel": "Multi-Channel", + "multiChannelDesc": "Support 40+ AI providers with intelligent load balancing and failover", + "keyManagement": "Key Management", + "keyManagementDesc": "Flexible API key management with model limits and quota control", + "usageBilling": "Usage Billing", + "usageBillingDesc": "Precise token usage tracking and flexible billing plans", + "subscription": "Subscription", + "subscriptionDesc": "Multiple subscription plans to meet different scale requirements", + "documentation": "Documentation", + "documentationDesc": "Complete API documentation and guides for quick onboarding" + }, + "pricing": { + "title": "Model Pricing", + "searchPlaceholder": "Search model name...", + "modelName": "Model Name", + "inputPrice": "Input Price", + "outputPrice": "Output Price", + "cachePrice": "Cache Price", + "contextLength": "Context Length", + "provider": "Provider", + "group": "Group", + "perToken": "/ 1K Token", + "noPricingData": "No pricing data available" + }, + "about": { + "title": "About", + "version": "Version", + "commitHash": "Commit Hash", + "buildTime": "Build Time", + "license": "License", + "repository": "Repository", + "basedOn": "Based On" + }, + "setup": { + "title": "Initial Setup", + "step": "Step", + "adminAccount": "Admin Account", + "systemConfig": "System Configuration", + "adminUsername": "Admin Username", + "adminPassword": "Admin Password", + "confirmAdminPassword": "Confirm Admin Password", + "systemName": "System Name", + "serverAddress": "Server Address", + "setupComplete": "Setup Complete", + "setupCompleteDesc": "System initialization complete, redirecting to login page", + "initializing": "Initializing system..." + }, + "oauth": { + "callback": "OAuth Callback", + "processing": "Processing login...", + "success": "Login successful, redirecting...", + "error": "OAuth login failed", + "invalidProvider": "Invalid OAuth provider", + "backToLogin": "Back to Login" + }, + "notFound": { + "title": "Page Not Found", + "description": "The page you are looking for does not exist", + "backHome": "Back to Home" + }, + "userAgreement": { + "title": "User Agreement" + }, + "privacyPolicy": { + "title": "Privacy Policy" + } + }, + "time": { + "justNow": "Just now", + "minutesAgo": "{{count}} minutes ago", + "hoursAgo": "{{count}} hours ago", + "daysAgo": "{{count}} days ago", + "weeksAgo": "{{count}} weeks ago", + "monthsAgo": "{{count}} months ago", + "yearsAgo": "{{count}} years ago", + "never": "Never", + "permanent": "Permanent" + }, + "profile": { + "profileInfo": "Profile Info", + "security": "Security", + "oauthBindings": "OAuth Bindings", + "changePassword": "Change Password", + "oldPassword": "Current Password", + "newPassword": "New Password", + "passwordTooShort": "Password must be at least 8 characters", + "twoFactor": "Two-Factor Auth", + "twoFactorEnabled": "Two-factor authentication enabled", + "twoFactorDisabled": "Two-factor authentication not enabled", + "setup2FA": "Set Up 2FA", + "enable2FA": "Enable 2FA", + "disable2FA": "Disable 2FA", + "qrCodeGenerated": "QR code generated", + "scanQRCode": "Scan the QR code with your authenticator app", + "accessToken": "Access Token", + "generateToken": "Generate Access Token", + "deleteAccount": "Delete Account", + "deleteAccountWarning": "Account data cannot be recovered after deletion. Please proceed with caution!", + "accountDeleted": "Account deleted", + "linked": "Linked", + "notLinked": "Not Linked" + }, + "doc": { + "title": "Documentation", + "description": "Browse and manage documents", + "categories": "Categories", + "allDocs": "All Documents", + "createDoc": "Create Document", + "editDoc": "Edit Document", + "manageCategories": "Manage Categories", + "addCategory": "Add Category", + "categoryName": "Category Name", + "categoryLabel": "Category Label", + "parentCategory": "Parent Category", + "searchPlaceholder": "Search documents...", + "slug": "Slug", + "category": "Category", + "visibility": "Visibility", + "visibilityPublic": "Public", + "visibilityAuth": "Auth Required", + "visibilityAdmin": "Admin Only", + "published": "Published", + "content": "Content", + "contentPlaceholder": "Enter Markdown content here...", + "edit": "Edit", + "preview": "Preview", + "tableOfContents": "Table of Contents" + }, + "playground": { + "title": "API Playground", + "description": "Test API calls online", + "apiKey": "API Key", + "selectApiKey": "Select API Key", + "model": "Model", + "modelPlaceholder": "Enter or select a model", + "systemPrompt": "System Prompt", + "systemPromptPlaceholder": "Enter system prompt...", + "userMessage": "User Message", + "userMessagePlaceholder": "Enter message content...", + "parameters": "Parameters", + "send": "Send", + "stop": "Stop", + "response": "Response", + "rawJson": "Raw JSON", + "noResponse": "Response will appear here after sending a request", + "promptTokens": "Prompt Tokens", + "completionTokens": "Completion Tokens", + "totalTokens": "Total Tokens", + "codeExamples": "Code Examples", + "fillRequired": "Please fill in model and message", + "selectApiKeyFirst": "Please select an API key first" + }, + "mj": { + "progress": "Progress", + "image": "Image", + "viewImage": "View Image", + "failReason": "Fail Reason" + }, + "task": { + "progress": "Progress", + "failReason": "Fail Reason", + "finishTime": "Finish Time" + } +} diff --git a/web/daisy/src/i18n/locales/zh.json b/web/daisy/src/i18n/locales/zh.json new file mode 100644 index 000000000..4aac0d9c0 --- /dev/null +++ b/web/daisy/src/i18n/locales/zh.json @@ -0,0 +1,625 @@ +{ + "common": { + "appName": "ModelsToken", + "loading": "加载中...", + "save": "保存", + "cancel": "取消", + "confirm": "确认", + "delete": "删除", + "edit": "编辑", + "create": "创建", + "search": "搜索", + "filter": "筛选", + "refresh": "刷新", + "reset": "重置", + "submit": "提交", + "back": "返回", + "next": "下一步", + "previous": "上一步", + "close": "关闭", + "export": "导出", + "import": "导入", + "download": "下载", + "upload": "上传", + "copy": "复制", + "copied": "已复制!", + "more": "更多", + "actions": "操作", + "status": "状态", + "enabled": "已启用", + "disabled": "已禁用", + "yes": "是", + "no": "否", + "all": "全部", + "none": "无", + "success": "成功", + "error": "错误", + "warning": "警告", + "info": "提示", + "noData": "暂无数据", + "total": "共", + "items": "条", + "rowsPerPage": "每页条数", + "page": "页", + "of": "/", + "sortBy": "排序", + "ascending": "升序", + "descending": "降序", + "selected": "已选择", + "bulkActions": "批量操作", + "deleteConfirm": "确定要删除吗?", + "deleteSuccess": "删除成功", + "saveSuccess": "保存成功", + "operationSuccess": "操作成功", + "operationFailed": "操作失败", + "networkError": "网络错误", + "unauthorized": "未授权", + "forbidden": "无权限", + "notFound": "未找到", + "serverError": "服务器错误", + "timeout": "请求超时", + "leaveEmpty": "留空", + "select": "请选择", + "used": "已使用", + "createdAt": "创建时间", + "sortOrder": "排序" + }, + "nav": { + "dashboard": "仪表盘", + "tokens": "令牌", + "channels": "渠道", + "users": "用户", + "logs": "日志", + "wallet": "钱包", + "subscriptions": "订阅", + "redemptions": "兑换码", + "models": "模型", + "vendors": "供应商", + "deployments": "部署", + "playground": "Playground", + "docs": "文档", + "profile": "个人中心", + "settings": "系统设置", + "logout": "退出登录", + "login": "登录", + "register": "注册", + "about": "关于", + "pricing": "定价", + "midjourney": "Midjourney", + "tasks": "任务" + }, + "auth": { + "loginTitle": "登录", + "registerTitle": "注册", + "username": "用户名", + "password": "密码", + "confirmPassword": "确认密码", + "email": "邮箱", + "forgotPassword": "忘记密码?", + "resetPassword": "重置密码", + "noAccount": "没有账号?", + "hasAccount": "已有账号?", + "signUp": "注册", + "signIn": "登录", + "affCode": "邀请码", + "verificationCode": "验证码", + "sendCode": "发送验证码", + "loginSuccess": "登录成功", + "registerSuccess": "注册成功", + "logoutSuccess": "已退出登录", + "passwordMismatch": "两次密码不一致", + "invalidCredentials": "用户名或密码错误", + "rememberMe": "记住我", + "orContinueWith": "或通过以下方式登录", + "invalidEmail": "邮箱格式不正确", + "passwordTooShort": "密码至少8个字符", + "resetEmailSent": "重置邮件已发送", + "resetEmailSentDesc": "重置密码的邮件已发送到您的邮箱,请查收", + "forgotPasswordDesc": "请输入您的邮箱地址,我们将发送重置密码的链接", + "sendResetEmail": "发送重置邮件", + "invalidResetToken": "无效的重置令牌", + "resetPasswordSuccess": "密码重置成功" + }, + "user": { + "id": "ID", + "username": "用户名", + "displayName": "显示名称", + "email": "邮箱", + "role": "角色", + "group": "分组", + "quota": "额度", + "usedQuota": "已用额度", + "requestCount": "请求次数", + "status": "状态", + "createdAt": "创建时间", + "lastLoginAt": "最后登录", + "affCode": "邀请码", + "affCount": "邀请人数", + "affQuota": "邀请额度", + "remark": "备注", + "roleUser": "普通用户", + "roleAdmin": "管理员", + "roleRoot": "超级管理员" + }, + "token": { + "name": "令牌名称", + "key": "密钥", + "status": "状态", + "quota": "额度", + "usedQuota": "已用额度", + "remainQuota": "剩余额度", + "unlimitedQuota": "无限额度", + "expiredTime": "过期时间", + "createdTime": "创建时间", + "accessedTime": "访问时间", + "modelLimits": "模型限制", + "modelLimitsEnabled": "启用模型限制", + "allowIps": "允许IP", + "neverExpire": "永不过期", + "statusEnabled": "已启用", + "statusDisabled": "已禁用", + "statusExpired": "已过期", + "statusExhausted": "已耗尽", + "createToken": "创建令牌", + "copyKey": "复制密钥", + "regenerateKey": "重新生成密钥" + }, + "channel": { + "name": "渠道名称", + "type": "渠道类型", + "status": "状态", + "priority": "优先级", + "weight": "权重", + "models": "模型", + "group": "分组", + "baseUrl": "基础URL", + "key": "密钥", + "testModel": "测试模型", + "responseTime": "响应时间", + "balance": "余额", + "usedQuota": "已用额度", + "createdTime": "创建时间", + "testTime": "测试时间", + "autoBan": "自动禁用", + "tag": "标签", + "statusEnabled": "已启用", + "statusDisabled": "已禁用", + "statusAutoDisabled": "自动禁用", + "testChannel": "测试渠道", + "updateBalance": "更新余额", + "batchTest": "批量测试", + "fetchModels": "获取模型", + "modelMapping": "模型映射" + }, + "redemption": { + "name": "名称", + "key": "兑换码", + "quota": "额度", + "usedCount": "已使用次数", + "count": "生成数量", + "batchDeleteInvalid": "清理无效兑换码" + }, + "model": { + "modelId": "模型ID", + "owner": "所有者", + "inputPrice": "输入价格", + "outputPrice": "输出价格", + "syncUpstream": "上游同步", + "missingModels": "缺失模型" + }, + "vendor": { + "name": "名称", + "description": "描述" + }, + "deployment": { + "name": "名称", + "hardware": "硬件", + "location": "位置", + "statusRunning": "运行中", + "statusStopped": "已停止", + "statusError": "错误", + "viewLogs": "查看日志", + "viewContainers": "查看容器" + }, + "log": { + "type": "类型", + "time": "时间", + "user": "用户", + "token": "令牌", + "model": "模型", + "quota": "额度", + "promptTokens": "提示Token", + "completionTokens": "完成Token", + "channel": "渠道", + "duration": "耗时", + "isStream": "流式", + "group": "分组", + "ip": "IP", + "requestId": "请求ID", + "typeTopup": "充值", + "typeConsume": "消费", + "typeManage": "管理", + "typeSystem": "系统", + "typeError": "错误", + "typeRefund": "退款", + "totalQuota": "总消费额度", + "totalRequests": "总请求数" + }, + "subscription": { + "title": "订阅", + "plan": "套餐", + "price": "价格", + "duration": "时长", + "status": "状态", + "quota": "额度", + "resetPeriod": "重置周期", + "purchaseTime": "购买时间", + "expireTime": "到期时间", + "active": "生效中", + "expired": "已过期", + "cancelled": "已取消", + "durationDay": "天", + "durationMonth": "月", + "durationYear": "年", + "resetNever": "不重置", + "resetDaily": "每天", + "resetWeekly": "每周", + "resetMonthly": "每月", + "currentPlan": "当前套餐", + "availablePlans": "可选套餐", + "balancePay": "余额支付", + "orderHistory": "订单记录", + "bindSubscription": "绑定订阅", + "userSubscriptions": "用户订阅", + "sortOrder": "排序" + }, + "dashboard": { + "quotaTrend": "额度使用趋势", + "apiInfo": "API 信息", + "serverAddress": "服务器地址", + "affCode": "邀请码", + "announcements": "系统公告", + "quickActions": "快捷操作" + }, + "wallet": { + "title": "钱包", + "balance": "余额", + "topUp": "充值", + "history": "充值记录", + "redeemCode": "兑换码充值", + "transfer": "额度转移", + "amount": "金额", + "paymentMethod": "支付方式", + "transactionId": "交易号", + "onlinePay": "在线支付", + "checkIn": "签到", + "checkedInToday": "今日已签到", + "notCheckedIn": "今日未签到", + "affiliate": "推广返利", + "transferAmount": "转移额度" + }, + "settings": { + "site": "站点设置", + "auth": "认证设置", + "billing": "计费设置", + "content": "内容设置", + "models": "模型设置", + "operations": "运营设置", + "security": "安全设置", + "docs": "文档设置", + "general": "通用", + "systemName": "系统名称", + "logo": "Logo", + "logoUrl": "Logo URL", + "footer": "页脚 HTML", + "theme": "主题", + "language": "语言", + "noChanges": "没有变更", + "basicInfo": "基本信息", + "contentInfo": "内容信息", + "legal": "法律条款", + "navigation": "导航配置", + "serverAddress": "服务器地址", + "notice": "系统公告", + "about": "关于", + "homePageContent": "首页内容", + "userAgreement": "用户协议", + "privacyPolicy": "隐私政策", + "headerNavModules": "顶部导航模块", + "sidebarModules": "侧边栏模块", + "passwordAndReg": "密码与注册", + "passwordLogin": "允许密码登录", + "passwordRegister": "允许密码注册", + "emailVerification": "邮箱验证", + "emailDomainWhitelist": "邮箱域名白名单", + "emailAlias": "允许邮箱别名", + "minTrustLevel": "最低信任等级", + "wechatOAuth": "微信 OAuth", + "quotaConfig": "额度配置", + "quotaForNewUser": "新用户额度", + "preConsumedQuota": "预扣额度", + "quotaForInviter": "邀请者额度", + "quotaForInvitee": "被邀请者额度", + "freeModelPreConsumed": "免费模型预扣额度", + "links": "链接配置", + "topUpLink": "充值链接", + "docLink": "文档链接", + "currencyConfig": "货币配置", + "quotaUnit": "额度单位", + "quotaExchangeRate": "汇率", + "currencyDisplay": "货币显示", + "modelRatio": "模型倍率", + "modelRatioDesc": "模型倍率配置(JSON 格式)", + "groupRatio": "分组倍率", + "groupRatioDesc": "分组倍率配置(JSON 格式)", + "epayAddress": "支付地址", + "epayId": "商户 ID", + "epayKey": "商户密钥", + "otherPayment": "其他支付", + "checkIn": "签到配置", + "checkInEnabled": "启用签到", + "checkInMinQuota": "签到最小额度", + "checkInMaxQuota": "签到最大额度", + "consoleConfig": "控制台配置", + "consoleAPIInfoPanel": "API 信息面板", + "noticeAndFAQ": "公告与 FAQ", + "noticeConfig": "公告配置", + "faqConfig": "FAQ 配置", + "uptimeKuma": "Uptime Kuma", + "uptimeKumaMonitorGroups": "监控分组", + "featureToggle": "功能开关", + "chatEnabled": "启用聊天", + "drawingEnabled": "启用绘图", + "midjourneyConfig": "Midjourney 配置", + "globalModelConfig": "全局模型配置", + "globalPassthrough": "全局透传模式", + "thinkingModelBlacklist": "思考模型黑名单", + "chatToResponsesStrategy": "Chat 转 Responses 策略", + "pingInterval": "Ping 间隔", + "geminiSafety": "安全设置", + "geminiVersion": "版本", + "geminiImageModel": "图片模型", + "geminiThinkingAdapter": "思考适配器", + "geminiFunctionCalling": "函数调用", + "claudeModelHeader": "模型请求头", + "claudeDefaultMaxTokens": "默认 Max Tokens", + "claudeThinkingAdapter": "思考适配器", + "grokViolationDeduction": "违规扣费", + "opsGeneral": "通用运营配置", + "retryCount": "重试次数", + "defaultCollapseSidebar": "默认折叠侧边栏", + "demoMode": "演示模式", + "selfUseMode": "自用模式", + "channelAutoMgmt": "渠道自动管理", + "channelAutoDisable": "自动禁用渠道", + "channelAutoEnable": "自动启用渠道", + "channelDisableThreshold": "禁用阈值", + "channelDisableKeywords": "禁用关键词", + "channelDisableStatusCodes": "禁用状态码", + "autoRetryStatusCodes": "自动重试状态码", + "autoTestChannels": "自动测试渠道", + "smtpConfig": "SMTP 配置", + "smtpServer": "SMTP 服务器", + "smtpPort": "端口", + "smtpAccount": "账号", + "smtpToken": "令牌/密码", + "smtpFrom": "发件人", + "workerConfig": "Worker 配置", + "workerURL": "Worker URL", + "workerKey": "Worker Key", + "loggingAndCache": "日志与缓存", + "logConsume": "记录消费日志", + "diskCacheConfig": "磁盘缓存配置", + "performanceMonitorConfig": "性能监控配置", + "rateLimit": "速率限制", + "modelRequestRateLimit": "模型请求速率限制", + "sensitiveWordCheck": "敏感词检测", + "sensitiveWordCheckEnabled": "启用敏感词检测", + "sensitiveWordCheckOnPrompt": "检测提示词", + "sensitiveWordCheckOnOutput": "检测输出", + "networkProtection": "网络防护", + "ssrfProtection": "SSRF 防护", + "privateIPFilter": "私有 IP 过滤", + "domainIPFilter": "域名/IP 过滤", + "domainFilterMode": "域名过滤模式", + "ipFilterMode": "IP 过滤模式", + "whitelist": "白名单", + "blacklist": "黑名单", + "domainFilterList": "域名过滤列表", + "ipFilterList": "IP 过滤列表", + "portWhitelist": "端口白名单", + "portWhitelistDesc": "允许的端口列表,逗号分隔", + "docCategoryMgmt": "文档分类管理", + "docCategoryConfig": "分类配置", + "docVisibility": "文档可见性", + "docDefaultVisibility": "新文档默认可见性", + "docPublic": "公开", + "docPrivate": "私有", + "docUnlisted": "未列出", + "docPlaceholder": "占位内容", + "docPlaceholderContent": "占位内容配置", + "frontendTheme": "前端主题", + "themeDefault": "Default(新版前端)", + "themeClassic": "Classic(经典前端)", + "themeDaisy": "Daisy(DaisyUI 前端)" + }, + "quota": { + "unit": "额度", + "unlimited": "无限", + "insufficient": "额度不足", + "display": "显示" + }, + "public": { + "heroSubtitle": "一站式 AI API 管理平台,聚合多家供应商,统一接口调用", + "getStarted": "立即开始", + "viewPricing": "查看定价", + "featuresTitle": "核心功能", + "quickStartTitle": "快速开始", + "allRightsReserved": "保留所有权利", + "feature": { + "apiGateway": "API 网关", + "apiGatewayDesc": "统一 API 入口,兼容 OpenAI 接口格式,无缝切换", + "multiChannel": "多渠道聚合", + "multiChannelDesc": "支持 40+ AI 供应商,智能负载均衡与故障转移", + "keyManagement": "密钥管理", + "keyManagementDesc": "灵活的 API 密钥管理,支持模型限制与额度控制", + "usageBilling": "用量计费", + "usageBillingDesc": "精确的 Token 用量统计与灵活的计费方案", + "subscription": "订阅套餐", + "subscriptionDesc": "多种订阅方案,满足不同规模的使用需求", + "documentation": "接口文档", + "documentationDesc": "完整的 API 文档与使用指南,快速上手" + }, + "pricing": { + "title": "模型定价", + "searchPlaceholder": "搜索模型名称...", + "modelName": "模型名称", + "inputPrice": "输入价格", + "outputPrice": "输出价格", + "cachePrice": "缓存价格", + "contextLength": "上下文长度", + "provider": "供应商", + "group": "分组", + "perToken": "/ 1K Token", + "noPricingData": "暂无定价数据" + }, + "about": { + "title": "关于", + "version": "版本", + "commitHash": "提交哈希", + "buildTime": "构建时间", + "license": "许可证", + "repository": "代码仓库", + "basedOn": "基于" + }, + "setup": { + "title": "初始设置", + "step": "步骤", + "adminAccount": "管理员账号", + "systemConfig": "系统配置", + "adminUsername": "管理员用户名", + "adminPassword": "管理员密码", + "confirmAdminPassword": "确认管理员密码", + "systemName": "系统名称", + "serverAddress": "服务器地址", + "setupComplete": "设置完成", + "setupCompleteDesc": "系统初始化完成,即将跳转到登录页面", + "initializing": "正在初始化系统..." + }, + "oauth": { + "callback": "OAuth 回调", + "processing": "正在处理登录...", + "success": "登录成功,正在跳转...", + "error": "OAuth 登录失败", + "invalidProvider": "无效的 OAuth 提供商", + "backToLogin": "返回登录" + }, + "notFound": { + "title": "页面未找到", + "description": "您访问的页面不存在", + "backHome": "返回首页" + }, + "userAgreement": { + "title": "用户协议" + }, + "privacyPolicy": { + "title": "隐私政策" + } + }, + "time": { + "justNow": "刚刚", + "minutesAgo": "{{count}} 分钟前", + "hoursAgo": "{{count}} 小时前", + "daysAgo": "{{count}} 天前", + "weeksAgo": "{{count}} 周前", + "monthsAgo": "{{count}} 月前", + "yearsAgo": "{{count}} 年前", + "never": "永不过期", + "permanent": "永久" + }, + "profile": { + "profileInfo": "个人信息", + "security": "安全设置", + "oauthBindings": "第三方绑定", + "changePassword": "修改密码", + "oldPassword": "当前密码", + "newPassword": "新密码", + "passwordTooShort": "密码至少8个字符", + "twoFactor": "两步验证", + "twoFactorEnabled": "两步验证已启用", + "twoFactorDisabled": "两步验证未启用", + "setup2FA": "设置两步验证", + "enable2FA": "启用两步验证", + "disable2FA": "关闭两步验证", + "qrCodeGenerated": "二维码已生成", + "scanQRCode": "请使用验证器应用扫描二维码", + "accessToken": "访问令牌", + "generateToken": "生成访问令牌", + "deleteAccount": "注销账户", + "deleteAccountWarning": "注销后账户数据将无法恢复,请谨慎操作!", + "accountDeleted": "账户已注销", + "linked": "已绑定", + "notLinked": "未绑定" + }, + "doc": { + "title": "文档中心", + "description": "浏览和管理文档", + "categories": "分类", + "allDocs": "全部文档", + "createDoc": "创建文档", + "editDoc": "编辑文档", + "manageCategories": "管理分类", + "addCategory": "添加分类", + "categoryName": "分类名称", + "categoryLabel": "分类显示名", + "parentCategory": "父分类", + "searchPlaceholder": "搜索文档...", + "slug": "Slug", + "category": "分类", + "visibility": "可见性", + "visibilityPublic": "公开", + "visibilityAuth": "登录可见", + "visibilityAdmin": "管理员可见", + "published": "已发布", + "content": "内容", + "contentPlaceholder": "在此输入 Markdown 内容...", + "edit": "编辑", + "preview": "预览", + "tableOfContents": "目录" + }, + "playground": { + "title": "API Playground", + "description": "在线测试 API 调用", + "apiKey": "API 密钥", + "selectApiKey": "选择 API 密钥", + "model": "模型", + "modelPlaceholder": "输入或选择模型", + "systemPrompt": "系统提示词", + "systemPromptPlaceholder": "输入系统提示词...", + "userMessage": "用户消息", + "userMessagePlaceholder": "输入消息内容...", + "parameters": "参数设置", + "send": "发送", + "stop": "停止", + "response": "响应", + "rawJson": "原始 JSON", + "noResponse": "发送请求后响应将显示在此", + "promptTokens": "提示 Token", + "completionTokens": "完成 Token", + "totalTokens": "总 Token", + "codeExamples": "代码示例", + "fillRequired": "请填写模型和消息", + "selectApiKeyFirst": "请先选择 API 密钥" + }, + "mj": { + "progress": "进度", + "image": "图片", + "viewImage": "查看图片", + "failReason": "失败原因" + }, + "task": { + "progress": "进度", + "failReason": "失败原因", + "finishTime": "完成时间" + } +} diff --git a/web/daisy/src/index.css b/web/daisy/src/index.css new file mode 100644 index 000000000..638d4c52f --- /dev/null +++ b/web/daisy/src/index.css @@ -0,0 +1,19 @@ +@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;600;700&display=swap'); +@import "tailwindcss"; +@plugin "daisyui" { + themes: business --default, dark --prefersdark; +} + +:root { + font-family: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; + line-height: 1.5; + font-weight: 400; + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.font-mono { + font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; +} diff --git a/web/daisy/src/lib/channel-types.ts b/web/daisy/src/lib/channel-types.ts new file mode 100644 index 000000000..08611ec33 --- /dev/null +++ b/web/daisy/src/lib/channel-types.ts @@ -0,0 +1,178 @@ +// Channel type definitions matching backend constant/channel.go + +export const ChannelType = { + Unknown: 0, + OpenAI: 1, + Midjourney: 2, + Azure: 3, + Ollama: 4, + MidjourneyPlus: 5, + OpenAIMax: 6, + OhMyGPT: 7, + Custom: 8, + AILS: 9, + AIProxy: 10, + PaLM: 11, + API2GPT: 12, + AIGC2D: 13, + Anthropic: 14, + Baidu: 15, + Zhipu: 16, + Ali: 17, + Xunfei: 18, + '360': 19, + OpenRouter: 20, + AIProxyLibrary: 21, + FastGPT: 22, + Tencent: 23, + Gemini: 24, + Moonshot: 25, + ZhipuV4: 26, + Perplexity: 27, + LingYiWanWu: 31, + Aws: 33, + Cohere: 34, + MiniMax: 35, + SunoAPI: 36, + Dify: 37, + Jina: 38, + Cloudflare: 39, + SiliconFlow: 40, + VertexAi: 41, + Mistral: 42, + DeepSeek: 43, + MokaAI: 44, + VolcEngine: 45, + BaiduV2: 46, + Xinference: 47, + Xai: 48, + Coze: 49, + Kling: 50, + Jimeng: 51, + Vidu: 52, + Submodel: 53, + DoubaoVideo: 54, + Sora: 55, + Replicate: 56, + Codex: 57, +} as const + +export type ChannelTypeValue = (typeof ChannelType)[keyof typeof ChannelType] + +export const channelTypeNames: Record = { + [ChannelType.Unknown]: 'Unknown', + [ChannelType.OpenAI]: 'OpenAI', + [ChannelType.Midjourney]: 'Midjourney', + [ChannelType.Azure]: 'Azure', + [ChannelType.Ollama]: 'Ollama', + [ChannelType.MidjourneyPlus]: 'MidjourneyPlus', + [ChannelType.OpenAIMax]: 'OpenAIMax', + [ChannelType.OhMyGPT]: 'OhMyGPT', + [ChannelType.Custom]: 'Custom', + [ChannelType.AILS]: 'AILS', + [ChannelType.AIProxy]: 'AIProxy', + [ChannelType.PaLM]: 'PaLM', + [ChannelType.API2GPT]: 'API2GPT', + [ChannelType.AIGC2D]: 'AIGC2D', + [ChannelType.Anthropic]: 'Anthropic', + [ChannelType.Baidu]: 'Baidu', + [ChannelType.Zhipu]: 'Zhipu', + [ChannelType.Ali]: 'Ali', + [ChannelType.Xunfei]: 'Xunfei', + [ChannelType['360']]: '360', + [ChannelType.OpenRouter]: 'OpenRouter', + [ChannelType.AIProxyLibrary]: 'AIProxyLibrary', + [ChannelType.FastGPT]: 'FastGPT', + [ChannelType.Tencent]: 'Tencent', + [ChannelType.Gemini]: 'Gemini', + [ChannelType.Moonshot]: 'Moonshot', + [ChannelType.ZhipuV4]: 'ZhipuV4', + [ChannelType.Perplexity]: 'Perplexity', + [ChannelType.LingYiWanWu]: 'LingYiWanWu', + [ChannelType.Aws]: 'AWS', + [ChannelType.Cohere]: 'Cohere', + [ChannelType.MiniMax]: 'MiniMax', + [ChannelType.SunoAPI]: 'SunoAPI', + [ChannelType.Dify]: 'Dify', + [ChannelType.Jina]: 'Jina', + [ChannelType.Cloudflare]: 'Cloudflare', + [ChannelType.SiliconFlow]: 'SiliconFlow', + [ChannelType.VertexAi]: 'VertexAI', + [ChannelType.Mistral]: 'Mistral', + [ChannelType.DeepSeek]: 'DeepSeek', + [ChannelType.MokaAI]: 'MokaAI', + [ChannelType.VolcEngine]: 'VolcEngine', + [ChannelType.BaiduV2]: 'BaiduV2', + [ChannelType.Xinference]: 'Xinference', + [ChannelType.Xai]: 'xAI', + [ChannelType.Coze]: 'Coze', + [ChannelType.Kling]: 'Kling', + [ChannelType.Jimeng]: 'Jimeng', + [ChannelType.Vidu]: 'Vidu', + [ChannelType.Submodel]: 'Submodel', + [ChannelType.DoubaoVideo]: 'DoubaoVideo', + [ChannelType.Sora]: 'Sora', + [ChannelType.Replicate]: 'Replicate', + [ChannelType.Codex]: 'Codex', +} + +export function getChannelTypeName(type: number): string { + return channelTypeNames[type] || 'Unknown' +} + +export const channelBaseURLs: Record = { + [ChannelType.Unknown]: '', + [ChannelType.OpenAI]: 'https://api.openai.com', + [ChannelType.Midjourney]: 'https://oa.api2d.net', + [ChannelType.Azure]: '', + [ChannelType.Ollama]: 'http://localhost:11434', + [ChannelType.MidjourneyPlus]: 'https://api.openai-sb.com', + [ChannelType.OpenAIMax]: 'https://api.openaimax.com', + [ChannelType.OhMyGPT]: 'https://api.ohmygpt.com', + [ChannelType.Custom]: '', + [ChannelType.AILS]: 'https://api.caipacity.com', + [ChannelType.AIProxy]: 'https://api.aiproxy.io', + [ChannelType.PaLM]: '', + [ChannelType.API2GPT]: 'https://api.api2gpt.com', + [ChannelType.AIGC2D]: 'https://api.aigc2d.com', + [ChannelType.Anthropic]: 'https://api.anthropic.com', + [ChannelType.Baidu]: 'https://aip.baidubce.com', + [ChannelType.Zhipu]: 'https://open.bigmodel.cn', + [ChannelType.Ali]: 'https://dashscope.aliyuncs.com', + [ChannelType.Xunfei]: '', + [ChannelType['360']]: 'https://api.360.cn', + [ChannelType.OpenRouter]: 'https://openrouter.ai/api', + [ChannelType.AIProxyLibrary]: 'https://api.aiproxy.io', + [ChannelType.FastGPT]: 'https://fastgpt.run/api/openapi', + [ChannelType.Tencent]: 'https://hunyuan.tencentcloudapi.com', + [ChannelType.Gemini]: 'https://generativelanguage.googleapis.com', + [ChannelType.Moonshot]: 'https://api.moonshot.cn', + [ChannelType.ZhipuV4]: 'https://open.bigmodel.cn', + [ChannelType.Perplexity]: 'https://api.perplexity.ai', + [ChannelType.LingYiWanWu]: 'https://api.lingyiwanwu.com', + [ChannelType.Aws]: '', + [ChannelType.Cohere]: 'https://api.cohere.ai', + [ChannelType.MiniMax]: 'https://api.minimax.chat', + [ChannelType.SunoAPI]: '', + [ChannelType.Dify]: 'https://api.dify.ai', + [ChannelType.Jina]: 'https://api.jina.ai', + [ChannelType.Cloudflare]: 'https://api.cloudflare.com', + [ChannelType.SiliconFlow]: 'https://api.siliconflow.cn', + [ChannelType.VertexAi]: '', + [ChannelType.Mistral]: 'https://api.mistral.ai', + [ChannelType.DeepSeek]: 'https://api.deepseek.com', + [ChannelType.MokaAI]: 'https://api.moka.ai', + [ChannelType.VolcEngine]: 'https://ark.cn-beijing.volces.com', + [ChannelType.BaiduV2]: 'https://qianfan.baidubce.com', + [ChannelType.Xinference]: '', + [ChannelType.Xai]: 'https://api.x.ai', + [ChannelType.Coze]: 'https://api.coze.cn', + [ChannelType.Kling]: 'https://api.klingai.com', + [ChannelType.Jimeng]: 'https://visual.volcengineapi.com', + [ChannelType.Vidu]: 'https://api.vidu.cn', + [ChannelType.Submodel]: 'https://llm.submodel.ai', + [ChannelType.DoubaoVideo]: 'https://ark.cn-beijing.volces.com', + [ChannelType.Sora]: 'https://api.openai.com', + [ChannelType.Replicate]: 'https://api.replicate.com', + [ChannelType.Codex]: 'https://chatgpt.com', +} diff --git a/web/daisy/src/lib/constants.ts b/web/daisy/src/lib/constants.ts new file mode 100644 index 000000000..86753b9b7 --- /dev/null +++ b/web/daisy/src/lib/constants.ts @@ -0,0 +1,96 @@ +// Role constants matching backend common/constants.go +export const ROLE_GUEST = 0 +export const ROLE_USER = 1 +export const ROLE_ADMIN = 10 +export const ROLE_ROOT = 100 + +// User status +export const USER_STATUS_ENABLED = 1 +export const USER_STATUS_DISABLED = 2 + +// Token status +export const TOKEN_STATUS_ENABLED = 1 +export const TOKEN_STATUS_DISABLED = 2 +export const TOKEN_STATUS_EXPIRED = 3 +export const TOKEN_STATUS_EXHAUSTED = 4 + +// Channel status +export const CHANNEL_STATUS_UNKNOWN = 0 +export const CHANNEL_STATUS_ENABLED = 1 +export const CHANNEL_STATUS_MANUALLY_DISABLED = 2 +export const CHANNEL_STATUS_AUTO_DISABLED = 3 + +// Redemption code status +export const REDEMPTION_STATUS_ENABLED = 1 +export const REDEMPTION_STATUS_DISABLED = 2 +export const REDEMPTION_STATUS_USED = 3 + +// Log types +export const LOG_TYPE_UNKNOWN = 0 +export const LOG_TYPE_TOPUP = 1 +export const LOG_TYPE_CONSUME = 2 +export const LOG_TYPE_MANAGE = 3 +export const LOG_TYPE_SYSTEM = 4 +export const LOG_TYPE_ERROR = 5 +export const LOG_TYPE_REFUND = 6 + +// Channel type names map (matching backend constant/channel.go) +export const CHANNEL_TYPE_NAMES: Record = { + 0: 'Unknown', + 1: 'OpenAI', + 2: 'Midjourney', + 3: 'Azure', + 4: 'Ollama', + 5: 'MidjourneyPlus', + 6: 'OpenAIMax', + 7: 'OhMyGPT', + 8: 'Custom', + 9: 'AILS', + 10: 'AIProxy', + 11: 'PaLM', + 12: 'API2GPT', + 13: 'AIGC2D', + 14: 'Anthropic', + 15: 'Baidu', + 16: 'Zhipu', + 17: 'Ali', + 18: 'Xunfei', + 19: '360', + 20: 'OpenRouter', + 21: 'AIProxyLibrary', + 22: 'FastGPT', + 23: 'Tencent', + 24: 'Gemini', + 25: 'Moonshot', + 26: 'ZhipuV4', + 27: 'Perplexity', + 31: 'LingYiWanWu', + 33: 'AWS', + 34: 'Cohere', + 35: 'MiniMax', + 36: 'SunoAPI', + 37: 'Dify', + 38: 'Jina', + 39: 'Cloudflare', + 40: 'SiliconFlow', + 41: 'VertexAI', + 42: 'Mistral', + 43: 'DeepSeek', + 44: 'MokaAI', + 45: 'VolcEngine', + 46: 'BaiduV2', + 47: 'Xinference', + 48: 'xAI', + 49: 'Coze', + 50: 'Kling', + 51: 'Jimeng', + 52: 'Vidu', + 53: 'Submodel', + 54: 'DoubaoVideo', + 55: 'Sora', + 56: 'Replicate', + 57: 'Codex', +} + +// Quota unit: 500000 per dollar (matching backend QuotaPerUnit) +export const QUOTA_PER_UNIT = 500000 diff --git a/web/daisy/src/lib/quota.ts b/web/daisy/src/lib/quota.ts new file mode 100644 index 000000000..19730cb3f --- /dev/null +++ b/web/daisy/src/lib/quota.ts @@ -0,0 +1,24 @@ +// Quota per unit: 500000 = $1.00 (matching backend QuotaPerUnit) +export const quotaPerUnit = 500000 + +export function renderQuota(quota: number, displayInCurrency = true): string { + if (quota <= 0) return displayInCurrency ? '$0.00' : '0' + if (!displayInCurrency) return quota.toLocaleString() + const value = quota / quotaPerUnit + if (value >= 1) { + return '$' + value.toFixed(2) + } + // For very small amounts, show more precision + if (value >= 0.01) { + return '$' + value.toFixed(4) + } + return '$' + value.toFixed(6) +} + +export function quotaToCurrency(quota: number): number { + return quota / quotaPerUnit +} + +export function currencyToQuota(currency: number): number { + return Math.round(currency * quotaPerUnit) +} diff --git a/web/daisy/src/lib/utils.ts b/web/daisy/src/lib/utils.ts new file mode 100644 index 000000000..a4a16c21e --- /dev/null +++ b/web/daisy/src/lib/utils.ts @@ -0,0 +1,48 @@ +import { clsx, type ClassValue } from 'clsx' +import { twMerge } from 'tailwind-merge' + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} + +export function formatQuota(quota: number, displayInCurrency = true): string { + if (quota <= 0) return '$0.00' + if (!displayInCurrency) return quota.toLocaleString() + return '$' + (quota / 500000).toFixed(2) +} + +export function formatDate(timestamp: number | string | null | undefined): string { + if (!timestamp) return '-' + const date = new Date(typeof timestamp === 'number' ? timestamp * 1000 : timestamp) + if (isNaN(date.getTime())) return '-' + return date.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + }) +} + +export async function copyToClipboard(text: string): Promise { + try { + await navigator.clipboard.writeText(text) + return true + } catch { + const textarea = document.createElement('textarea') + textarea.value = text + textarea.style.position = 'fixed' + textarea.style.opacity = '0' + document.body.appendChild(textarea) + textarea.select() + try { + document.execCommand('copy') + return true + } catch { + return false + } finally { + document.body.removeChild(textarea) + } + } +} diff --git a/web/daisy/src/main.tsx b/web/daisy/src/main.tsx new file mode 100644 index 000000000..4e2c09fb4 --- /dev/null +++ b/web/daisy/src/main.tsx @@ -0,0 +1,27 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import { BrowserRouter } from 'react-router-dom' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import App from './App' +import './i18n' +import './index.css' + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: 1, + refetchOnWindowFocus: false, + staleTime: 5 * 60 * 1000, + }, + }, +}) + +createRoot(document.getElementById('root')!).render( + + + + + + + , +) diff --git a/web/daisy/src/pages/NotFound.tsx b/web/daisy/src/pages/NotFound.tsx new file mode 100644 index 000000000..834885f89 --- /dev/null +++ b/web/daisy/src/pages/NotFound.tsx @@ -0,0 +1,21 @@ +import { Link } from 'react-router-dom' +import { useTranslation } from 'react-i18next' +import { Home, FileQuestion } from 'lucide-react' + +export default function NotFound() { + const { t } = useTranslation() + + return ( +
+
+ +

{t('public.notFound.title')}

+

{t('public.notFound.description')}

+ + + {t('public.notFound.backHome')} + +
+
+ ) +} diff --git a/web/daisy/src/pages/admin/ChannelForm.tsx b/web/daisy/src/pages/admin/ChannelForm.tsx new file mode 100644 index 000000000..28505e53d --- /dev/null +++ b/web/daisy/src/pages/admin/ChannelForm.tsx @@ -0,0 +1,163 @@ +import { useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useMutation } from '@tanstack/react-query' +import toast from 'react-hot-toast' +import { Zap } from 'lucide-react' +import { createChannel, updateChannel, testChannel } from '@/api/channel' +import type { Channel } from '@/types/channel' +import { channelTypeNames, channelBaseURLs } from '@/lib/channel-types' + +interface ChannelFormProps { + channel: Channel | null + onClose: () => void + onSuccess: () => void +} + +const openAIBaseURLs = [ + { label: 'Official', value: 'https://api.openai.com' }, + { label: 'Azure', value: '' }, + { label: 'Custom', value: '' }, +] + +export default function ChannelForm({ channel, onClose, onSuccess }: ChannelFormProps) { + const { t } = useTranslation() + const isEdit = !!channel + const [testing, setTesting] = useState(false) + + const [form, setForm] = useState({ + type: channel?.type ?? 1, + name: channel?.name ?? '', + base_url: channel?.base_url ?? '', + key: channel?.key ?? '', + models: channel?.models ?? '', + model_mapping: channel?.model_mapping ?? '', + group: channel?.group ?? 'default', + priority: channel?.priority ?? 0, + weight: channel?.weight ?? 1, + tag: channel?.tag ?? '', + }) + + const saveMut = useMutation({ + mutationFn: (data: Partial) => isEdit ? updateChannel({ ...data, id: channel!.id }) : createChannel(data), + onSuccess: () => { + toast.success(t('common.saveSuccess')) + onSuccess() + }, + onError: () => toast.error(t('common.operationFailed')), + }) + + const handleTest = async () => { + setTesting(true) + try { + if (channel?.id) { + const res = await testChannel(channel.id) + toast.success(res.message || t('common.success')) + } + } catch { + toast.error(t('common.operationFailed')) + } finally { + setTesting(false) + } + } + + const handleTypeChange = (type: number) => { + setForm((prev) => ({ + ...prev, + type, + base_url: prev.base_url || channelBaseURLs[type] || '', + })) + } + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + saveMut.mutate(form as unknown as Partial) + } + + const typeOptions = Object.entries(channelTypeNames).filter(([k]) => Number(k) > 0) + + return ( + +
+

{isEdit ? t('common.edit') : t('common.create')} {t('nav.channels')}

+
+
+
+ + +
+
+ + setForm({ ...form, name: e.target.value })} required /> +
+
+ +
+ + {form.type === 1 && ( +
+ {openAIBaseURLs.map((opt) => ( + + ))} +
+ )} + setForm({ ...form, base_url: e.target.value })} /> +
+ +
+ +