commit 5bd314deb2f803cfb68ecb28aa98df396ca4cd3c Author: Chen Gu Date: Sat May 9 00:31:09 2026 +0800 chore: initial commit - maqt-desktop v0.2 - Phase 1-5: UI framework, auth, weapon schemes, color filters, system optimization - Industrial/tech design style with Chinese localization - Points to gch3n.online/delta backend API - Hardware monitor, filter editor, and all module pages diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a71c94f --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +node_modules/ +dist/ +.env +*.log +.DS_Store +__pycache__/ +*.pyc diff --git a/DEVELOPMENT_PLAN.md b/DEVELOPMENT_PLAN.md new file mode 100644 index 0000000..e206b74 --- /dev/null +++ b/DEVELOPMENT_PLAN.md @@ -0,0 +1,663 @@ +# 码枪堂桌面端复刻 — 全面开发规划 + +> 基于 MaQiangTang v7.0.4 完整逆向分析 +> 后端: https://gch3n.online/delta | 源码: https://git.gch3n.online/gch3n/mqsrv + +--- + +## 一、原版功能全景图 + +### 1.1 页面结构 + +``` +┌─────────────────────────────────────────────────────────┐ +│ 桌面首页 (Desktop/Home) │ +│ ┌────────────────┐ ┌────────────────┐ │ +│ │ 快速优化 │ │ 画面滤镜 │ │ +│ │ (一键优化) │ │ (Exposure) │ │ +│ └────────────────┘ └────────────────┘ │ +│ ┌────────────────┐ ┌────────────────┐ │ +│ │ 滤镜社区 │ │ 改枪方案 │ │ +│ │ (Filter-Share) │ │ (Weapon) │ │ +│ └────────────────┘ └────────────────┘ │ +│ ┌────────────────┐ ┌────────────────┐ │ +│ │ 游戏准星 │ │ 神秘力量 │ │ +│ │ (Crosshair) │ │ (Xixi-Haha) │ │ +│ └────────────────┘ └────────────────┘ │ +│ ┌────────────────┐ │ +│ │ 嘉豪之力 │ │ +│ │ (Forbidden) │ │ +│ └────────────────┘ │ +│ │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ 底部 Dock: 社区教程 | 微信 | 官网 │ │ +│ └──────────────────────────────────────────────────┘ │ +│ │ +│ ┌── 底部启动按钮 ──────────────────────────────────┐ │ +│ │ [ 启动硬件监控 ] [ 启动码枪堂2.0 (XiXiOverlay) ] │ │ +│ └──────────────────────────────────────────────────┘ │ +├─────────────────────────────────────────────────────────┤ +│ 底部 Dock 导航栏 (离开首页时显示) │ +│ [快速优化] [画面滤镜] [滤镜社区] [改枪方案] [设置] │ +└─────────────────────────────────────────────────────────┘ +``` + +### 1.2 完整页面/功能清单 + +| # | 页面 ID | 名称 | 描述 | +|---|---------|------|------| +| 1 | `home` | 桌面首页 | 桌面图标、启动按钮、社区入口 | +| 2 | `one-click-optimization` | 快速优化 | 一键系统优化(VIP) | +| 3 | `exposure` | 画面滤镜 | 显示/色彩滤镜管理(VIP) | +| 4 | `filter-community` | 滤镜社区 | 分享和下载滤镜(VIP) | +| 5 | `weapon` | 改枪方案 | 武器配置方案浏览/分享 | +| 6 | `game-crosshair` | 游戏准星 | 准星定制(需登录) | +| 7 | `xixi-haha` | 神秘力量 | 趣味功能(需登录) | +| 8 | `forbidden-force` | 嘉豪之力 | 高级功能(VIP) | +| 9 | `settings` | 设置页 | 应用偏好、开机自启等 | + +### 1.3 原生服务清单(Services) + +| 服务 | 功能 | 复用方式 | +|------|------|----------| +| **SystemOptimizationService** | 系统优化项执行/恢复 | IPC spawn MaqiangTangh1.exe | +| **XiXiOverlayNativeService** | 游戏内 Overlay 浮窗 | IPC spawn MaqiangTangXiXiOverlay.exe | +| **HardwareMonitorService** | 硬件监控(CPU/GPU 温度) | IPC spawn MaqiangTangHardwareMonitor.exe | +| **ArgyllService** | 色彩校准(ICC 配置文件) | 调用 dispwin.exe / iccvcgt.exe | +| **NvidiaProfileService** | NVIDIA 驱动配置 | 调用 nvidiaProfileInspector.exe | +| **NipConfigService** | NIP 配置文件管理 | 读写 .nip 文件 | +| **CustomFilterIccService** | 自定义滤镜 ICC | 色彩配置文件管理 | +| **PowerManagementService** | 电源管理 | 调用 PowerShell 系统命令 | +| **ResolutionService** | 分辨率切换 | 调用 DVChange.exe | +| **GpuDeviceService** | GPU 设备信息 | 系统 API 查询 | +| **SystemInfoService** | 系统信息收集 | 系统 API 查询 | +| **CompareFitService** | 方案比对 | 算法比对 | +| **DlssNativeService** | DLSS 配置管理 | 驱动层 DLSS 设置 | +| **ShaderCacheService** | 着色器缓存管理 | 缓存文件管理 | +| **NvidiaAppService** | NVIDIA App 集成 | 系统 API | +| **PermissionChecker** | 权限检查 | 管理员权限检测 | +| **MemoryService** | 内存优化 | 系统 API | +| **ProcessService** | 进程管理 | 系统 API | +| **RegistryService** | 注册表操作 | 系统 API | +| **WindowsFeaturesService** | Windows 功能开关 | PowerShell | +| **WindowsServiceManager** | 系统服务管理 | PowerShell | +| **SecurityMonitorService** | 安全监控 | 系统 API | + +--- + +## 二、项目文件结构 + +``` +maqt-desktop/ +├── docs/ # 开发文档 +│ ├── ARCHITECTURE.md # 架构说明 +│ ├── API_REFERENCE.md # API 接口文档 +│ ├── UI_WIREFRAMES.md # 界面线框图 +│ └── DEVELOPMENT_LOG.md # 开发日志 +│ +├── electron/ # Electron 主进程 +│ ├── main.ts # 窗口管理、生命周期 +│ ├── preload.ts # 安全 IPC 桥 +│ ├── menu.ts # 菜单配置 +│ ├── updater.ts # 自动更新 +│ │ +│ ├── ipc/ # IPC 处理器 +│ │ ├── auth.ipc.ts # 认证相关 +│ │ ├── system.ipc.ts # 系统级操作 +│ │ ├── overlay.ipc.ts # XiXiOverlay 控制 +│ │ ├── optimization.ipc.ts # 系统优化 +│ │ ├── profile.ipc.ts # NVIDIA 配置 +│ │ ├── display.ipc.ts # 显示/色彩 +│ │ └── file.ipc.ts # 文件操作 +│ │ +│ ├── services/ # 原生服务包装 +│ │ ├── SystemOptimizer.ts # 调用 MaqiangTangh1.exe +│ │ ├── XiXiOverlayLauncher.ts # 调用 XiXiOverlay.exe +│ │ ├── HardwareMonitor.ts # 调用 HardwareMonitor.exe +│ │ ├── NvidiaProfile.ts # 调用 nvidiaProfileInspector.exe +│ │ ├── ColorCalibration.ts # 调用 Argyll CMS +│ │ ├── PowerManager.ts # 电源方案管理 +│ │ └── ResolutionChanger.ts # 分辨率切换调用 DVChange.exe +│ │ +│ └── utils/ # 主进程工具 +│ ├── logger.ts # 日志 +│ ├── permissions.ts # 提权 +│ └── paths.ts # 路径管理 +│ +├── src/ # React 前端 +│ ├── main.tsx # 入口 +│ ├── App.tsx # 根组件 + 路由 +│ ├── router.tsx # 页面路由 +│ │ +│ ├── pages/ # 页面组件 +│ │ ├── Home.tsx # 桌面首页 +│ │ ├── Login.tsx # 登录页 +│ │ ├── Register.tsx # 注册页 +│ │ ├── Optimization.tsx # 快速优化 +│ │ ├── Exposure.tsx # 画面滤镜 +│ │ ├── FilterCommunity.tsx # 滤镜社区 +│ │ ├── WeaponSchemes.tsx # 改枪方案 +│ │ ├── Crosshair.tsx # 游戏准星 +│ │ ├── XixiHaha.tsx # 神秘力量 +│ │ ├── ForbiddenForce.tsx # 嘉豪之力 +│ │ ├── SchemeDetail.tsx # 方案详情 +│ │ └── Settings.tsx # 设置页 +│ │ +│ ├── components/ # 通用组件 +│ │ ├── ui/ # UI 基础组件 +│ │ │ ├── Button.tsx # 直角切角按钮 +│ │ │ ├── Card.tsx # 模块化卡片 +│ │ │ ├── ProgressBar.tsx # 机械进度条 +│ │ │ ├── Panel.tsx # 半透明悬浮面板 +│ │ │ ├── Modal.tsx # 弹窗 +│ │ │ ├── Toast.tsx # 消息提示 +│ │ │ ├── Badge.tsx # 角标 +│ │ │ ├── Compass.tsx # 罗盘刻度装饰 +│ │ │ ├── Input.tsx # 输入框 +│ │ │ ├── Select.tsx # 下拉选择 +│ │ │ └── Skeleton.tsx # 加载骨架屏 +│ │ │ +│ │ ├── layout/ # 布局组件 +│ │ │ ├── DesktopGrid.tsx # 桌面图标网格 +│ │ │ ├── DesktopIcon.tsx # 桌面图标 +│ │ │ ├── BottomDock.tsx # 底部导航 Dock +│ │ │ ├── TopBar.tsx # 顶部状态栏 +│ │ │ ├── SidePanel.tsx # 侧边面板 +│ │ │ └── PageContainer.tsx # 页面容器 +│ │ │ +│ │ ├── auth/ # 认证相关 +│ │ │ ├── LoginModal.tsx # 登录弹窗 +│ │ │ ├── VipBadge.tsx # VIP 标识 +│ │ │ └── VipActivate.tsx # VIP 激活 +│ │ │ +│ │ ├── hardware/ # 硬件监控 +│ │ │ ├── MonitorPanel.tsx # 监控面板 +│ │ │ ├── CpuGauge.tsx # CPU 仪表盘 +│ │ │ ├── GpuGauge.tsx # GPU 仪表盘 +│ │ │ └── TempIndicator.tsx # 温度指示 +│ │ │ +│ │ ├── schemes/ # 改枪方案 +│ │ │ ├── SchemeCard.tsx # 方案卡片 +│ │ │ ├── SchemeList.tsx # 方案列表 +│ │ │ ├── SchemeFilter.tsx # 方案筛选 +│ │ │ ├── SchemePreviewer.tsx # 方案预览 +│ │ │ └── SchemeEditor.tsx # 方案编辑 +│ │ │ +│ │ ├── filters/ # 画面滤镜 +│ │ │ ├── FilterCard.tsx # 滤镜卡片 +│ │ │ ├── FilterGrid.tsx # 滤镜网格 +│ │ │ ├── FilterPreview.tsx # 滤镜预览 +│ │ │ └── FilterEditor.tsx # 滤镜编辑 +│ │ │ +│ │ └── optimization/ # 系统优化 +│ │ ├── OptimizeItem.tsx # 优化项 +│ │ ├── OptimizePanel.tsx # 优化面板 +│ │ └── OptimizeResult.tsx # 优化结果 +│ │ +│ ├── hooks/ # 自定义 Hooks +│ │ ├── useAuth.ts # 登录态 +│ │ ├── useApi.ts # API 请求 +│ │ ├── useVip.ts # VIP 状态 +│ │ ├── useElectron.ts # Electron API +│ │ ├── useHardwareMonitor.ts # 硬件监控 +│ │ ├── useLocalStorage.ts # 本地存储 +│ │ └── useTheme.ts # 主题 +│ │ +│ ├── stores/ # 状态管理 +│ │ ├── authStore.ts # 认证 +│ │ ├── vipStore.ts # VIP +│ │ ├── navigationStore.ts # 导航 +│ │ └── settingsStore.ts # 设置 +│ │ +│ ├── services/ # API 服务 +│ │ ├── api.ts # Axios 实例 +│ │ ├── auth.api.ts # 认证接口 +│ │ ├── schemes.api.ts # 方案接口 +│ │ ├── filters.api.ts # 滤镜接口 +│ │ ├── favorites.api.ts # 收藏接口 +│ │ ├── user.api.ts # 用户接口 +│ │ └── popups.api.ts # 广告接口 +│ │ +│ └── styles/ # 样式 +│ ├── globals.css # 全局样式 +│ ├── theme.ts # 主题变量 +│ ├── tailwind.ts # Tailwind 配置 +│ └── animations.css # 动画 +│ +├── native/ # 原生可执行文件 +│ ├── MaqiangTangh1.exe +│ ├── MaqiangTangh2.exe +│ ├── MaqiangTangHardwareMonitor.exe +│ ├── nvidiaProfileInspector.exe +│ ├── tools/ +│ │ ├── xixi-overlay-helper/ +│ │ │ └── MaqiangTangXiXiOverlay.exe +│ │ ├── vibrance-bridge/ +│ │ │ ├── VibranceBridge.exe +│ │ │ └── vibranceDLL.dll +│ │ ├── DVChange.exe +│ │ ├── gsynctoggle.exe +│ │ └── dbInstaller.exe +│ ├── Argyll/ +│ │ └── bin/ +│ │ ├── iccvcgt.exe +│ │ └── dispwin.exe +│ ├── icc-profiles/ +│ └── scripts/ +│ ├── apply-gamma-force.ps1 +│ └── restore-gamma-force.ps1 +│ +├── package.json +├── electron-builder.yml # 打包配置 +├── tsconfig.json +├── vite.config.ts # Vite 配置 +├── tailwind.config.ts +├── postcss.config.js +├── Dockerfile +└── docker-compose.yml +``` + +--- + +## 三、UI 设计规范 + +### 3.1 设计语言 + +``` +军工战术风 · 单兵头盔HUD · 暗区射击手游UI + +配色方案: + ████ #0A0E17 炭黑(主背景) + ████ #1A1F2E 深碳灰(卡片/面板) + ████ #2D3349 铁灰(边框/分隔) + ████ #3B4A3B 军绿(强调色/按钮) + ████ #5C7A3E 橄榄绿(次要强调) + ████ #3A6B35 暗军绿(激活态) + ████ #4A3B22 泥土棕(装饰/辅助) + ████ #7A6B4A 暗金(VIP/高级元素) + ████ #C8A95B 淡金(VIP 高亮) + ████ #E8E0D0 米白(主文字) + ████ #A09888 灰白(次要文字) + ████ #5A5248 深灰(禁用文字) + ████ #3B2B1A 暗琥珀(警告/危险) + +字体: + - 主字体: "JetBrains Mono" (monospace, 军事终端感) + - 备用: "Cascadia Code", "Fira Code", monospace + +字号阶梯: + 10px 罗盘刻度标签 + 12px 辅助信息 + 14px 正文 + 16px 突出文字 + 18px 小标题 + 24px 页面标题 + 36px 大数字(监控数据) +``` + +### 3.2 组件风格 + +```css +/* 按钮: 直角切角 + 磨砂金属 */ +.btn-tactical { + border: 1px solid rgba(59, 74, 59, 0.6); + background: linear-gradient(180deg, + rgba(26, 31, 46, 0.95) 0%, + rgba(15, 20, 30, 0.98) 100%); + box-shadow: + inset 0 1px 0 rgba(200, 169, 91, 0.08), + inset 0 -1px 0 rgba(0, 0, 0, 0.3); + clip-path: polygon( + 4px 0, calc(100% - 4px) 0, + 100% 4px, 100% calc(100% - 4px), + calc(100% - 4px) 100%, 4px 100%, + 0 calc(100% - 4px), 0 4px + ); +} + +/* 面板: 半透明悬浮 */ +.panel-hud { + backdrop-filter: blur(12px); + background: rgba(15, 20, 30, 0.75); + border: 1px solid rgba(59, 74, 59, 0.3); + box-shadow: + 0 4px 24px rgba(0, 0, 0, 0.4), + inset 0 1px 0 rgba(92, 122, 62, 0.1); +} + +/* 进度条: 机械风格 */ +.progress-mechanical { + height: 6px; + background: rgba(26, 31, 46, 0.9); + border: 1px solid rgba(59, 74, 59, 0.4); + position: relative; +} +.progress-mechanical::after { + content: ''; + position: absolute; + top: 0; left: 0; + height: 100%; + width: var(--progress); + background: linear-gradient(90deg, + #3A6B35 0%, #5C7A3E 50%, #7A6B4A 100%); + /* 添加扫描线纹理 */ + background-image: repeating-linear-gradient( + 90deg, + transparent 0px, + rgba(255,255,255,0.03) 2px, + transparent 4px + ); +} +``` + +### 3.3 动画效果 + +``` +按钮悬停: 边框微光流动 (border-glow animation) +面板展开: HUD 扫描线展开效果 (scan-line reveal) +页面切换: 十字准星聚合展开 (crosshair transition) +数据更新: 数字滚动跳变 (digital roll) +加载中: 扫描雷达动画 (radar scan spinner) +错误提示: 红色警告闪烁 + 抖动 (shaker + flash) +VIP 元素: 暗金流光 (gold shimmer flow) +``` + +--- + +## 四、页面线框图 + +### 4.1 桌面首页 (Home.tsx) + +``` +┌──────────────────────────────────────────────────────────┐ +│ ████████████████████████████████████████████████████████ │ ← 顶部 HUD 条 +│ 10:45 │ FPS: 144 │ CPU: 52° │ GPU: 68° │ VIP ● │ 网络 ✓ │ (罗盘刻度装饰) +│ ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ │ +│ │ +│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ +│ │ ⚡ 快速 │ │ 🎨 画面 │ │ 📸 滤镜 │ │ 🔫 改枪 │ │ ← 桌面图标 2x3 网格 +│ │ 优化 │ │ 滤镜 │ │ 社区 │ │ 方案 │ │ +│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ +│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ +│ │ 🎯 游戏 │ │ 💫 神秘 │ │ 🛡️ 嘉豪 │ │ +│ │ 准星 │ │ 力量 │ │ 之力 │ │ +│ └─────────┘ └─────────┘ └─────────┘ │ +│ │ +│ ┌────────────────────────────────────────────────────┐ │ +│ │ 教程 │ 微信群 │ 官网 │ │ ← 社区快捷栏 +│ └────────────────────────────────────────────────────┘ │ +│ │ +│ ┌──────────────────────┐ ┌──────────────────────┐ │ +│ │ ▨ 启动硬件监控 │ │ ▣ 启动码枪堂2.0 │ │ ← 启动按钮 +│ │ [温度/频率监测] │ │ [游戏内Overlay] │ │ +│ └──────────────────────┘ └──────────────────────┘ │ +└──────────────────────────────────────────────────────────┘ +``` + +### 4.2 改枪方案页 (WeaponSchemes.tsx) + +``` +┌──────────────────────────────────────────────────────────┐ +│ ◀ 返回 改枪方案 🔍 搜索 │ ← TopBar +├──────────────────────────────────────────────────────────┤ +│ ┌──────────┐ ┌──────┐ ┌───┐ ┌──┐ ┌──┐ ┌───┐ ┌───┐ │ +│ │ 突击步枪 │ │冲锋枪│ │狙│ │轻│ │霰│ │手 │ │发 │ │ ← 武器分类标签 +│ │ AR │ │ SMG │ │SR│ │MG│ │SG│ │枪 │ │射 │ │ +│ └──────────┘ └──────┘ └───┘ └──┘ └──┘ └───┘ └───┘ │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ 武器: XXXX │ │ 武器: XXXX │ │ 武器: XXXX │ │ ← 方案卡片网格 +│ │ 作者: xxx │ │ 作者: xxx │ │ 作者: xxx │ │ +│ │ ⭐ 4.8 142🔥│ │ ⭐ 4.5 89🔥 │ │ ⭐ 4.9 203🔥│ │ +│ │ 效果预览... │ │ 效果预览... │ │ 效果预览... │ │ +│ │ ┌──────┐ │ │ ┌──────┐ │ │ ┌──────┐ │ │ +│ │ │ 收藏 │ │ │ │ 收藏 │ │ │ │ 收藏 │ │ │ +│ │ └──────┘ │ │ └──────┘ │ │ └──────┘ │ │ +│ └──────────────┘ └──────────────┘ └──────────────┘ │ +│ │ +│ ← 1 2 3 4 → │ ← 分页 +├──────────────────────────────────────────────────────────┤ +│ [快速优化] [画面滤镜] [滤镜社区] [改枪方案] [设置] │ ← BottomDock +└──────────────────────────────────────────────────────────┘ +``` + +### 4.3 登录/注册 (Login.tsx) + +``` +┌──────────────────────────────────────────────────────────┐ +│ │ +│ ═══ 认证 ═══ │ +│ │ +│ ┌──────────────────────────────────────┐ │ +│ │ ┌────────────────────────────────┐ │ │ +│ │ │ 用户名/邮箱 │ │ │ ← 磨砂输入框 +│ │ └────────────────────────────────┘ │ │ +│ │ ┌────────────────────────────────┐ │ │ +│ │ │ 密码 │ │ │ +│ │ └────────────────────────────────┘ │ │ +│ │ │ │ +│ │ ┌────────────────────────────────┐ │ │ +│ │ │ █ 登 录 │ │ │ ← 军绿按钮 +│ │ └────────────────────────────────┘ │ │ +│ │ │ │ +│ │ ═══ 或 ═══ │ │ +│ │ │ │ +│ │ ┌────────────────────────────────┐ │ │ +│ │ │ 创建账号 │ │ │ +│ │ └────────────────────────────────┘ │ │ +│ │ │ │ +│ │ ────── VIP 卡密激活 ────── │ │ +│ │ ┌────────────────────────────────┐ │ │ +│ │ │ 输入卡密... │ │ │ +│ │ └────────────────────────────────┘ │ │ +│ │ ┌────────────────────────────────┐ │ │ +│ │ │ 激 活 │ │ │ +│ │ └────────────────────────────────┘ │ │ +│ └──────────────────────────────────────┘ │ +│ │ +└──────────────────────────────────────────────────────────┘ +``` + +### 4.4 硬件监控 (MonitorPanel) + +``` +┌──────────────────────────────────────────────────────────┐ +│ ░ 硬 件 监 控 ░ │ +│ │ +│ ┌────────────┐ ┌────────────┐ │ +│ │ ▓ CPU │ │ ▓ GPU │ │ ← 圆形仪表盘 +│ │ 52°C │ │ 68°C │ │ +│ │ ┌──┐ │ │ ┌──┐ │ │ +│ │ │52│ │ │ │68│ │ │ +│ │ └──┘ │ │ └──┘ │ │ +│ │ 2.4GHz │ │ 1.8GHz │ │ +│ └────────────┘ └────────────┘ │ +│ │ +│ ▓ 内存: ████████░░░░ 72% │ ← 机械进度条 +│ ▓ FPS: ████████████░ 144 │ +│ ▓ 网络: ████████████ ✓ │ +│ │ +│ [ 刷新 ] [ 最小化到托盘 ] │ +└──────────────────────────────────────────────────────────┘ +``` + +--- + +## 五、功能操作逻辑地图 + +### 5.1 应用启动流程 + +``` +应用启动 + ↓ +加载配置 (settingsStore) + ↓ +检查登录态 (localStorage token) + ├── 有 token → 验证 session-status + │ ├── 有效 → 进入首页 + │ └── 无效 → 清除 token → 显示首页 + 登录提示 + └── 无 token → 显示首页 + 登录提示 + ↓ +启动硬件监控 (后台) + ↓ +检查更新 + ↓ +渲染桌面首页 +``` + +### 5.2 桌面图标交互 + +``` +点击桌面图标 + ↓ +检查权限要求(选项:loginRequired / vipRequired) + ├── 需要 VIP 但非 VIP → 弹出 VIP 激活窗口 + ├── 需要登录但未登录 → 弹出登录弹窗 + └── 权限通过 → 导航到目标页面 + ↓ +隐藏桌面图标区域 → 显示页面内容 + ↓ +底部 Dock 出现(包含导航按钮) +``` + +### 5.3 XiXi Overlay 启动 + +``` +点击「启动码枪堂2.0」 + ↓ +检查 XiXiOverlayNativeService.isAvailable() + ├── false → 提示"未找到 overlay 程序" + └── true → 继续 + ↓ +ensureProcess() → spawn MaqiangTangXiXiOverlay.exe + ├── spawn 失败 → 提示错误 + └── spawn 成功 → 等待 stdout "ready" + ↓ +发送 show 命令 (包含 label/gameId) + ↓ +等待 "ready" 信号 → overlay 显示 +``` + +### 5.4 改枪方案浏览 + +``` +进入改枪方案页 + ↓ +加载武器分类 (GET /api/category/{type}) + ↓ +默认选中 AR → 加载热榜方案 (GET /api/schemes?sort=hot) + ↓ +点击分类标签 → 切换武器类型 → 重新加载方案 + ↓ +点击方案卡片 → 进入方案详情页 + │ + ├── 收藏按钮 → POST /api/favorites (需登录) + ├── 使用按钮 → POST /api/schemes/{id}/use + ├── 预览模式 → 弹窗预览效果 + └── 分享 → 复制分享链接 +``` + +--- + +## 六、API 接口清单 + +详见 `API_FULL_ANALYSIS.md`,关键端点: + +``` +基础: POST /api/login + POST /api/register + GET /api/session-status + GET /api/vip-status + POST /api/activate-vip + +用户: GET /api/user/stats/:id + GET /api/user/limits/:id + GET /api/user/schemes/:id + GET /api/user/favorited-count/:id + +方案: GET /api/schemes?sort=&page=&limit=&source= + GET /api/schemes/:id + POST /api/schemes/:id/use + GET /api/category/:code + +收藏: GET /api/favorites/count + GET /api/favorites/check?schemeId= + POST /api/favorites + DELETE /api/favorites/:id + +工具: GET /api/software-version-ad + GET /api/popups/:id + GET /api/aftersale-tutorial-popup + GET /api/update-config.json +``` + +--- + +## 七、开发阶段 + +### Phase 1: 脚手架 + UI 框架 +- [ ] Vite + Electron + React + Tailwind 脚手架 +- [ ] 主题系统(军武风格变量) +- [ ] 路由 + 页面骨架 +- [ ] 桌面首页 + 桌面图标 +- [ ] 底部 Dock 导航 +- [ ] 顶部 HUD 状态栏 +- [ ] UI 组件库(按钮/卡片/面板/进度条) + +### Phase 2: 认证 + API 对接 +- [ ] Axios 实例 + 拦截器 +- [ ] 登录/注册页面 +- [ ] VIP 激活 +- [ ] Token 管理 + 自动刷新 +- [ ] 各页面数据对接 + +### Phase 3: 改枪方案模块 +- [ ] 武器分类标签 +- [ ] 方案列表 + 分页 +- [ ] 方案详情 +- [ ] 收藏系统 +- [ ] 方案使用记录 + +### Phase 4: 画面滤镜模块 +- [ ] 滤镜列表 +- [ ] 滤镜预览 +- [ ] 滤镜编辑器 +- [ ] 上传/分享 + +### Phase 5: 系统优化模块 +- [ ] 系统优化项列表展示 +- [ ] IPC 调用优化程序 +- [ ] 优化结果展示 +- [ ] 一键优化 + +### Phase 6: 原生功能对接 +- [ ] XiXi Overlay 启动/控制 +- [ ] 硬件监控面板 +- [ ] NVIDIA 配置管理 +- [ ] 色彩校准 +- [ ] 分辨率切换 + +### Phase 7: 系统集成 +- [ ] 自动更新 +- [ ] 开机自启 +- [ ] 托盘图标 +- [ ] 权限管理 +- [ ] 打包发布 + +--- + +## 八、技术栈速览 + +| 层 | 技术 | 版本 | +|----|------|------| +| 桌面框架 | Electron | latest | +| 构建工具 | Vite | latest | +| UI | React + TypeScript | latest | +| 样式 | Tailwind CSS | v3 | +| 状态 | Zustand | latest | +| 动画 | Framer Motion | latest | +| IPC | @electron/remote / contextBridge | — | +| 打包 | electron-builder | latest | +| 后端 API | https://gch3n.online/delta | — | +| 字体 | JetBrains Mono | — | +| 图标 | Material Symbols + 自定义 SVG | — | diff --git a/WAVE2_LOGIC_SPEC.md b/WAVE2_LOGIC_SPEC.md new file mode 100644 index 0000000..59d142b --- /dev/null +++ b/WAVE2_LOGIC_SPEC.md @@ -0,0 +1,215 @@ +# maqt-desktop 相2:逻辑层 & 页面 + +## 任务 +在已搭建好的 maqt-desktop 项目中,创建状态管理、API 服务层、Hooks 和所有页面。 + +## 路径 +/Users/guchen/.openclaw/workspace/maqt-desktop/ + +## 后端 API +https://gch3n.online/delta + +## 1. 全局配置 + +**src/services/api.ts** - Axios 实例 +```typescript +import axios from 'axios'; + +const API_BASE = 'https://gch3n.online/delta'; + +const api = axios.create({ + baseURL: API_BASE, + timeout: 15000, + headers: { 'Content-Type': 'application/json' }, +}); + +// 请求拦截器 - 自动添加 token +api.interceptors.request.use((config) => { + const token = localStorage.getItem('auth_token'); + if (token) config.headers.Authorization = `Bearer ${token}`; + return config; +}); + +// 响应拦截器 - 401 自动清除 token +api.interceptors.response.use( + (res) => res, + (err) => { + if (err.response?.status === 401) { + localStorage.removeItem('auth_token'); + localStorage.removeItem('auth_user'); + } + return Promise.reject(err); + } +); + +export default api; +``` + +## 2. Stores (Zustand) + +**src/stores/authStore.ts** +```typescript +// 状态: { token, user, isLoggedIn } +// 动作: login, logout, setUser, checkSession (调 /api/session-status) +// 持久化: token + user 存 localStorage +// hydrate: 启动时从 localStorage 读取 +``` + +**src/stores/navigationStore.ts** +```typescript +// 状态: { currentPage: 'home' | 'optimization' | 'exposure' | ... } +// 动作: navigate(page), goBack() +// isHome: computed currentPage === 'home' +``` + +**src/stores/settingsStore.ts** +```typescript +// 状态: { autoLaunch, closePreference, theme } +// 持久化: localStorage +``` + +## 3. API Services + +每个文件导出函数,使用 api 实例调用对应端点。 + +**src/services/auth.api.ts** +- login(username, password, installId, deviceHash, platform, osVersion, appVersion) +- register(username, password, email) +- getSessionStatus() +- getVipStatus() +- activateVip(cardKey) +- getUserStats(userId) +- getUserLimits(userId) + +**src/services/schemes.api.ts** +- getSchemes(params: {sort?, page?, limit?, source?, weaponCategory?, weaponName?}) +- getSchemeById(id) +- getCategory(code) +- useScheme(id, source?) +- getUserSchemes(userId) +- getUserFavoritedCount(userId) + +**src/services/favorites.api.ts** +- getFavorites() +- getFavoritesCount() +- checkFavorite(schemeId, source) +- addFavorite(data) +- removeFavorite(id) + +**src/services/filters.api.ts** +- getFilters(params?) +- getFilterById(id) +- uploadFilter(data) + +**src/services/popups.api.ts** +- getPopups(id) +- getSoftwareVersionAd() +- getAfterSaleTutorialPopup() +- getUpdateConfig() + +## 4. Hooks + +**src/hooks/useAuth.ts** - 封装 authStore,提供便捷的登录/登出方法 +**src/hooks/useApi.ts** - 通用请求 hook,loading/error 状态 +**src/hooks/useVip.ts** - VIP 状态检查 + 自动刷新 +**src/hooks/useElectron.ts** - 类型安全地调用 window.electronAPI +**src/hooks/useLocalStorage.ts** - 带类型安全的 localStorage + +## 5. 页面 + +**src/pages/Home.tsx** - 桌面首页 +- TopBar (顶部HUD) +- DesktopGrid (2x3 桌面图标) + - 快速优化 (bolt icon) + - 画面滤镜 (palette icon) + - 滤镜社区 (photo_filter icon) + - 改枪方案 (military_tech icon) + - 游戏准星 (center_focus_strong icon) + - 神秘力量 (bull icon) + - 嘉豪之力 (stealth_ninja icon) +- 社区快捷栏 (教程/微信/官网) +- 启动按钮: 硬件监控 + 码枪堂2.0 + +图标点击 → 检查登录/VIP → 导航到对应页面 + +**src/pages/Login.tsx** - 登录/注册页 +- 切换 登录/注册 标签 +- 登录表单: username + password +- 注册表单: username + password + email +- VIP 卡密激活栏 +- 登录成功后 → 跳转首页 + +**src/pages/Settings.tsx** - 设置页 +- 开机自启 (toggle) +- 关闭偏好 (ask/tray/quit) +- 版本号 + +**其他页面** (骨架,含标题 + 返回按钮): +- Optimization.tsx - 快速优化(暂空) +- Exposure.tsx - 画面滤镜(暂空) +- FilterCommunity.tsx - 滤镜社区(暂空) +- WeaponSchemes.tsx - 改枪方案(暂空) +- Crosshair.tsx - 游戏准星(暂空) +- XixiHaha.tsx - 神秘力量(暂空) +- ForbiddenForce.tsx - 嘉豪之力(暂空) +- SchemeDetail.tsx - 方案详情(暂空) + +## 6. App.tsx 路由配置 + +```tsx +// 使用 react-router-dom v7 +// Routes 配置: +// / → Home +// /login → Login +// /optimization → Optimization +// /exposure → Exposure +// /filter-community → FilterCommunity +// /weapon → WeaponSchemes +// /scheme/:id → SchemeDetail +// /crosshair → Crosshair +// /xixi-haha → XixiHaha +// /forbidden-force → ForbiddenForce +// /settings → Settings +// +// 布局: 所有 / 以外的路由共享 BottomDock +// 首页 (/) 不显示 BottomDock +``` + +## 7. TypeScript 类型定义 + +**src/types/index.ts**: +```typescript +export interface User { + id: string; + username: string; + email: string; + avatar: string | null; + isVip: boolean; + vipExpireAt: string | null; + vipLevel: number; +} + +export interface Scheme { + id: string; + title: string | null; + weaponName: string | null; + category: string | null; + userId: string; + description: string | null; + viewsCount: number; + downloadsCount: number; + likesCount: number; + favoritesCount: number; + price: number; + status: string; + isOfficial: boolean; + createdAt: string; + user?: { username: string; avatar: string | null }; +} + +export interface Category { + code: string; + name: string; + icon: string; +} +``` diff --git a/WAVE2_UI_SPEC.md b/WAVE2_UI_SPEC.md new file mode 100644 index 0000000..28652ec --- /dev/null +++ b/WAVE2_UI_SPEC.md @@ -0,0 +1,244 @@ +# maqt-desktop 相2:UI 组件系统 & 样式 + +## 任务 +在已搭建好的 maqt-desktop 项目中,创建完整的 UI 组件系统。 + +## 路径 +/Users/guchen/.openclaw/workspace/maqt-desktop/ + +## Tailwind 主题色 (tailwind.config.ts) + +```javascript +colors: { + tactical: { + black: '#0A0E17', // 主背景 + dark: '#1A1F2E', // 卡片/面板 + gray: '#2D3349', // 边框/分隔 + green: '#3B4A3B', // 强调色/按钮 + olive: '#5C7A3E', // 次要强调 + army: '#3A6B35', // 激活态 + brown: '#4A3B22', // 装饰/辅助 + gold: '#7A6B4A', // VIP/高级 + goldLight: '#C8A95B', // VIP 高亮 + text: '#E8E0D0', // 主文字 + textMuted: '#A09888', // 次要文字 + textDim: '#5A5248', // 禁用文字 + warn: '#3B2B1A', // 警告/危险 + } +} +fontFamily: { + mono: ['JetBrains Mono', 'Cascadia Code', 'Fira Code', 'monospace'], +} +``` + +## 需要创建的组件 + +### UI 基础组件 (src/components/ui/) + +**Button.tsx** - 直角切角按钮 +- variants: primary (军绿), secondary (铁灰), ghost (透明), danger (暗琥珀) +- sizes: sm, md, lg +- clip-path 切角效果 (4px) +- 悬停边框微光动画 +- 加载状态 (spinner + disabled) +- VIP 专用样式 (暗金边框) + +**Card.tsx** - 模块化卡片 +- 半透明悬浮背景 (backdrop-blur) +- 军绿色细边框 +- variants: default, highlighted (VIP), hoverable + +**Panel.tsx** - 半透明悬浮面板 +- backdrop-filter: blur(12px) +- 机械扫描线纹理 (repeating-linear-gradient) +- 可折叠/展开 + +**ProgressBar.tsx** - 机械进度条 +- 双层结构:背景槽 + 填充条 +- 填充条梯度 (军绿→橄榄绿→暗金) +- 扫描线纹理叠加 +- 进度数字标注 + +**Modal.tsx** - 弹窗 +- 背景毛玻璃遮罩 +- 居中卡片 +- 关闭动画 (十字准星收缩) +- 各种尺寸 + +**Toast.tsx** - 消息提示 +- 位置: 右下角 +- types: success, error, warning, info +- 自动消失 (3s) +- 军武风格图标 + +**Badge.tsx** - 角标 +- VIP 暗金角标 +- HOT/NEW 标签 +- 数字角标 + +**Input.tsx** - 输入框 +- 磨砂暗色背景 +- 军绿色 focus 边框 +- 切角效果 +- 错误状态 + +**Skeleton.tsx** - 加载骨架屏 +- 脉冲动画 +- 暗色闪烁 + +**Compass.tsx** - 罗盘刻度装饰组件 +- SVG 罗盘刻度环 +- 用于顶部 HUD 条两端装饰 + +### 布局组件 (src/components/layout/) + +**TopBar.tsx** - 顶部 HUD 状态栏 +- 左侧: 时间 + 罗盘刻度装饰 +- 中间: 硬件状态 (CPU温度/GPU温度/FPS) +- 右侧: VIP 标识 + 网络状态 +- 窗口控制按钮 (最小化/最大化/关闭) +- 半透明背景,底部渐变消失 +- 自定义拖拽区域 (-webkit-app-region: drag) + +``` +[≡ 10:45 ───◆───] [CPU 52° ● GPU 68° ● FPS 144] [⋆VIP ✓ ⋆⚡100ms] [━ ☐ ✕] +``` + +**BottomDock.tsx** - 底部导航 Dock +- 固定到底部 +- 磨砂玻璃背景 +- 图标+文字按钮 +- 当前页高亮 (底部小三角) +- 按钮: 快速优化 | 画面滤镜 | 滤镜社区 | 改枪方案 | 设置 +- 首页不显示 (页面状态为 home 时隐藏) + +**DesktopGrid.tsx** - 桌面图标网格 +- 2x3 网格布局 +- 居中排列 +- 响应式间距 + +**DesktopIcon.tsx** - 桌面图标 +- 圆形/圆角图标 +- 下方文字标签 +- 悬停光晕效果 +- 点击导航 +- 尺寸: icon 64x64, 文字 12px + +**PageContainer.tsx** - 页面容器 +- 内容区域包装器 +- 滚动容器 (隐藏滚动条) +- 顶部 padding 避开 TopBar +- 底部 padding 避开 Dock + +### 样式文件 + +**src/styles/globals.css** +```css +@tailwind base; +@tailwind components; +@tailwind utilities; + +@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&display=swap'); + +@layer base { + :root { + --color-black: #0A0E17; + --color-dark: #1A1F2E; + --color-gray: #2D3349; + --color-green: #3B4A3B; + --color-olive: #5C7A3E; + --color-army: #3A6B35; + --color-brown: #4A3B22; + --color-gold: #7A6B4A; + --color-gold-light: #C8A95B; + --color-text: #E8E0D0; + --color-text-muted: #A09888; + --color-text-dim: #5A5248; + --color-warn: #3B2B1A; + } + + * { scrollbar-width: none; } + body { + font-family: 'JetBrains Mono', monospace; + background: var(--color-black); + color: var(--color-text); + overflow: hidden; + } +} + +@layer components { + /* 切角按钮 */ + .btn-clip { + clip-path: polygon( + 4px 0, calc(100% - 4px) 0, + 100% 4px, 100% calc(100% - 4px), + calc(100% - 4px) 100%, 4px 100%, + 0 calc(100% - 4px), 0 4px + ); + } + + /* 扫描线纹理 */ + .scanlines { + background-image: repeating-linear-gradient( + 0deg, + transparent 0px, + rgba(0,0,0,0.03) 1px, + transparent 2px + ); + } +} +``` + +**src/styles/animations.css** +```css +/* 边框流光 */ +@keyframes border-glow { + 0%, 100% { border-color: rgba(59, 74, 59, 0.6); } + 50% { border-color: rgba(92, 122, 62, 0.8); } +} + +/* 扫描线展开 */ +@keyframes scan-reveal { + 0% { clip-path: inset(0 100% 0 0); } + 100% { clip-path: inset(0 0 0 0); } +} + +/* 十字准星展开 */ +@keyframes crosshair-expand { + 0% { transform: scale(0); opacity: 0; } + 50% { transform: scale(1.1); opacity: 0.5; } + 100% { transform: scale(1); opacity: 1; } +} + +/* 数字滚动跳变 */ +@keyframes digit-roll { + 0% { transform: translateY(100%); } + 100% { transform: translateY(0); } +} + +/* VIP 暗金流光 */ +@keyframes gold-shimmer { + 0% { background-position: -200% center; } + 100% { background-position: 200% center; } +} + +/* 脉冲扫描 */ +@keyframes radar-scan { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 抖动警告 */ +@keyframes shake { + 0%, 100% { transform: translateX(0); } + 25% { transform: translateX(-4px); } + 75% { transform: translateX(4px); } +} +``` + +### 注意事项 +- 所有组件用 TypeScript + React 函数组件 +- 使用 Tailwind className,适当用 clsx 库处理条件样式 +- 组件支持 className prop 以扩展样式 +- 动画使用 CSS 动画 + Framer Motion (framer-motion) +- 主题色用 Tailwind 类: bg-tactical-xxx, text-tactical-xxx diff --git a/docs/SCRAPING_PLAN.md b/docs/SCRAPING_PLAN.md new file mode 100644 index 0000000..7cc4071 --- /dev/null +++ b/docs/SCRAPING_PLAN.md @@ -0,0 +1,50 @@ +# 码枪堂方案数据采集脚本 + +## 用途 +从 maqt.top 原始 API 采集改枪方案数据,解密后导入到我们的数据库 + +## 运行环境 +Windows 机器 (nplx@100.99.186.30) + +## 依赖 +- Node.js +- npm install axios crypto-js + +## 思路 +1. 用已有的 token 调用原始 API +2. 由于前端代码已有解密逻辑,我们需要找到正确的 AES 密钥 +3. 或更简单:在 Windows 上通过 deobfuscated 代码直接解密 + +## 解法一:找密钥 + +在 CfKCgw5l.js 中搜索以下模式: +- `createDecipheriv` 或 `createCipheriv` +- 附近会有 key 和 iv 的生成逻辑 +- 密钥可能来自环境变量或硬编码 + +具体位置需要从 CfKCgw5l.js 或 main.deobfuscated.js 中找到。 + +## 解法二:利用前端的解密能力 + +使用 Playwright 或 Puppeteer 加载原始 app 的页面: +1. 加载首页 +2. 注入 token +3. 导航到改枪方案页 +4. 等待页面渲染(JS 自动解密) +5. 从 DOM 中提取数据 +6. 或拦截 XHR/fetch 请求获取解密后的 payload + +## 采集流程 + +``` +1. 登录 → 获取 token +2. 遍历所有分类 (AR/SMG/SR/LMG/SG/Pistol/Launcher) +3. 对每个分类翻页 (page 1..N) +4. 获取方案列表数据 → 解密 +5. 对每个方案获取详情 → 解密 +6. 整理格式 → 导入 PostgreSQL +``` + +## 导入目标 +后端: http://100.105.17.52:3001 (开发) / https://gch3n.online/delta (生产) +数据库: PostgreSQL (maqt 数据库, schemes 表) diff --git a/docs/scrape_schemes.js b/docs/scrape_schemes.js new file mode 100644 index 0000000..8d34b53 --- /dev/null +++ b/docs/scrape_schemes.js @@ -0,0 +1,131 @@ +// run `node scrape_schemes.js` on Windows +// 从 maqt.top 采集方案数据并导入到我们后端 + +const https = require('https'); +const http = require('http'); +const crypto = require('crypto'); +const fs = require('fs'); +const path = require('path'); + +// ========== 配置 ========== +const API_BASE = 'maqt.top'; +const OUR_API = 'http://100.105.17.52:3001'; // 先导入到本地后端 +const TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NDc5MTcsInVzZXJuYW1lIjoic2l4dGVlbnRoIiwidG9rZW5WZXJzaW9uIjozLCJpYXQiOjE3NzgyMTI0MDUsImV4cCI6MjA5Mzc4ODQwNX0.B_J0CDtaiiF2jJ592yKtD4RtQDIR3cDF_EYgn2UM2ko'; + +const CATEGORIES = ['AR', 'SMG', 'SR', 'LMG', 'SG', 'Pistol', 'Launcher']; + +// ========== AES 解密 ========== +// 从 deobfuscated 代码中找到密钥后填入这里 +// 格式: Buffer.from(key, 'utf-8') 需要 32 字节 +const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY || '0123456789abcdef0123456789abcdef'; + +function aesDecrypt(ivHex, dataHex) { + const iv = Buffer.from(ivHex, 'hex'); + const encrypted = Buffer.from(dataHex, 'hex'); + const key = Buffer.from(ENCRYPTION_KEY, 'utf-8'); + const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); + let decrypted = decipher.update(encrypted, undefined, 'utf-8'); + decrypted += decipher.final('utf-8'); + return JSON.parse(decrypted); +} + +// ========== HTTP 请求 ========== +function fetch(url, postData) { + return new Promise((resolve, reject) => { + const options = { + hostname: API_BASE, + path: url, + method: postData ? 'POST' : 'GET', + headers: { + 'Authorization': `Bearer ${TOKEN}`, + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) MaQiangTang/7.0.4', + 'Accept': 'application/json', + }, + }; + if (postData) { + options.headers['Content-Type'] = 'application/json'; + } + const req = https.request(options, (res) => { + let data = ''; + res.on('data', chunk => data += chunk); + res.on('end', () => { + try { + const parsed = JSON.parse(data); + console.log(` ${url.slice(0, 50)} → ${res.statusCode} ${parsed.encrypted ? '(encrypted)' : '(plain)'}`); + resolve(parsed); + } catch (e) { + resolve({ error: e.message, raw: data.slice(0, 100) }); + } + }); + }); + req.on('error', reject); + if (postData) req.write(JSON.stringify(postData)); + req.end(); + }); +} + +// ========== 导入到我们的后端 ========== +function importScheme(scheme) { + return new Promise((resolve) => { + const data = JSON.stringify(scheme); + const req = http.request(`${OUR_API}/api/schemes`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(data), + 'Authorization': `Bearer ${TOKEN}`, + }, + }, (res) => { + let d = ''; + res.on('data', c => d += c); + res.on('end', () => resolve(JSON.parse(d))); + }); + req.on('error', (e) => resolve({ error: e.message })); + req.write(data); + req.end(); + }); +} + +// ========== 采集流程 ========== +async function scrape() { + console.log('=== 开始采集改枪方案数据 ===\n'); + + // 1. 先测试分类 API + console.log('--- 采集分类 ---'); + for (const cat of CATEGORIES.slice(0, 3)) { + console.log(`\n分类: ${cat}`); + const result = await fetch(`/api/category/${cat}`); + if (!result.encrypted && Array.isArray(result)) { + console.log(` 返回 ${result.length} 条`); + } + } + + // 2. 采集方案列表 + console.log('\n--- 采集方案列表 ---'); + for (const cat of CATEGORIES.slice(0, 2)) { + console.log(`\n分类: ${cat}`); + const result = await fetch(`/api/schemes?sort=hot&page=1&limit=12&weaponCategory=${encodeURIComponent(cat)}`); + + if (result.encrypted) { + try { + const decrypted = aesDecrypt(result.iv, result.data); + console.log(` ✅ 解密成功! 数据:\n`, JSON.stringify(decrypted, null, 2).slice(0, 2000)); + + // 保存解密结果 + fs.writeFileSync(`schemes_${cat}.json`, JSON.stringify(decrypted, null, 2)); + console.log(` 已保存到 schemes_${cat}.json`); + } catch (e) { + console.log(` ❌ 解密失败: ${e.message}`); + console.log(` 密钥可能不正确,需要从 deobfuscated 代码中查找`); + console.log(` 密钥长度: ${Buffer.from(ENCRYPTION_KEY).length} bytes`); + console.log(` 加密数据 iv=${result.iv} data=${result.data.slice(0, 50)}...`); + } + } else { + console.log(` 明文响应:\n`, JSON.stringify(result).slice(0, 500)); + } + } + + console.log('\n=== 采集完成 ==='); +} + +scrape().catch(console.error); diff --git a/electron/main.js b/electron/main.js new file mode 100644 index 0000000..a9cde49 --- /dev/null +++ b/electron/main.js @@ -0,0 +1,65 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +const electron_1 = require("electron"); +const path = __importStar(require("path")); +let mainWindow = null; +function createWindow() { + mainWindow = new electron_1.BrowserWindow({ + width: 1400, + height: 900, + minWidth: 1100, + minHeight: 700, + frame: false, // 无边框自定义标题栏 + transparent: false, + backgroundColor: '#0A0E17', + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + contextIsolation: true, + nodeIntegration: false, + devTools: true, + }, + }); + if (process.env.VITE_DEV_SERVER_URL) { + mainWindow.loadURL(process.env.VITE_DEV_SERVER_URL); + mainWindow.webContents.openDevTools(); + } + else { + mainWindow.loadFile(path.join(__dirname, '../dist/index.html')); + } +} +electron_1.app.whenReady().then(createWindow); +electron_1.app.on('window-all-closed', () => { if (process.platform !== 'darwin') + electron_1.app.quit(); }); diff --git a/electron/main.ts b/electron/main.ts new file mode 100644 index 0000000..dca31f8 --- /dev/null +++ b/electron/main.ts @@ -0,0 +1,32 @@ +import { app, BrowserWindow, ipcMain } from 'electron'; +import * as path from 'path'; + +let mainWindow: BrowserWindow | null = null; + +function createWindow() { + mainWindow = new BrowserWindow({ + width: 1400, + height: 900, + minWidth: 1100, + minHeight: 700, + frame: false, // 无边框自定义标题栏 + transparent: false, + backgroundColor: '#0A0E17', + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + contextIsolation: true, + nodeIntegration: false, + devTools: true, + }, + }); + + if (process.env.VITE_DEV_SERVER_URL) { + mainWindow.loadURL(process.env.VITE_DEV_SERVER_URL); + mainWindow.webContents.openDevTools(); + } else { + mainWindow.loadFile(path.join(__dirname, '../dist/index.html')); + } +} + +app.whenReady().then(createWindow); +app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); }); diff --git a/electron/preload.js b/electron/preload.js new file mode 100644 index 0000000..165fdfd --- /dev/null +++ b/electron/preload.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const electron_1 = require("electron"); +electron_1.contextBridge.exposeInMainWorld('electronAPI', { + // 通用 + getAppVersion: () => electron_1.ipcRenderer.invoke('get-app-version'), + getPlatform: () => process.platform, + // Overlay + startOverlay: (options) => electron_1.ipcRenderer.invoke('overlay:start', options), + stopOverlay: () => electron_1.ipcRenderer.invoke('overlay:stop'), + // 硬件监控 + startMonitor: () => electron_1.ipcRenderer.invoke('monitor:start'), + stopMonitor: () => electron_1.ipcRenderer.invoke('monitor:stop'), + // 文件/路径 + openExternal: (url) => electron_1.ipcRenderer.invoke('open-external', url), + getResourcesPath: () => electron_1.ipcRenderer.invoke('get-resources-path'), + existsSync: (path) => electron_1.ipcRenderer.invoke('fs:exists', path), + // 系统优化 + optimizeItem: (id) => electron_1.ipcRenderer.invoke('optimize:item', id), + restoreItem: (id) => electron_1.ipcRenderer.invoke('optimize:restore', id), + getOptimizeItems: () => electron_1.ipcRenderer.invoke('optimize:list'), + // 窗口 + minimizeWindow: () => electron_1.ipcRenderer.invoke('window:minimize'), + maximizeWindow: () => electron_1.ipcRenderer.invoke('window:maximize'), + closeWindow: () => electron_1.ipcRenderer.invoke('window:close'), +}); diff --git a/electron/preload.ts b/electron/preload.ts new file mode 100644 index 0000000..dae2a3b --- /dev/null +++ b/electron/preload.ts @@ -0,0 +1,30 @@ +import { contextBridge, ipcRenderer } from 'electron'; + +contextBridge.exposeInMainWorld('electronAPI', { + // 通用 + getAppVersion: () => ipcRenderer.invoke('get-app-version'), + getPlatform: () => process.platform, + + // Overlay + startOverlay: (options: any) => ipcRenderer.invoke('overlay:start', options), + stopOverlay: () => ipcRenderer.invoke('overlay:stop'), + + // 硬件监控 + startMonitor: () => ipcRenderer.invoke('monitor:start'), + stopMonitor: () => ipcRenderer.invoke('monitor:stop'), + + // 文件/路径 + openExternal: (url: string) => ipcRenderer.invoke('open-external', url), + getResourcesPath: () => ipcRenderer.invoke('get-resources-path'), + existsSync: (path: string) => ipcRenderer.invoke('fs:exists', path), + + // 系统优化 + optimizeItem: (id: string) => ipcRenderer.invoke('optimize:item', id), + restoreItem: (id: string) => ipcRenderer.invoke('optimize:restore', id), + getOptimizeItems: () => ipcRenderer.invoke('optimize:list'), + + // 窗口 + minimizeWindow: () => ipcRenderer.invoke('window:minimize'), + maximizeWindow: () => ipcRenderer.invoke('window:maximize'), + closeWindow: () => ipcRenderer.invoke('window:close'), +}); diff --git a/index.html b/index.html new file mode 100644 index 0000000..0bb4695 --- /dev/null +++ b/index.html @@ -0,0 +1,16 @@ + + + + + + 码枪堂 2.0 + + + + + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..b9c4037 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7120 @@ +{ + "name": "maqt-desktop", + "version": "7.0.4", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "maqt-desktop", + "version": "7.0.4", + "dependencies": { + "@fontsource-variable/inter": "^5.2.8", + "@fontsource-variable/jetbrains-mono": "^5.2.8", + "@fontsource-variable/material-symbols-outlined": "^5.2.43", + "axios": "^1.16.0", + "framer-motion": "^12.38.0", + "react": "^19.2.6", + "react-dom": "^19.2.6", + "react-router-dom": "^6.30.3", + "zustand": "^5.0.13" + }, + "devDependencies": { + "@vitejs/plugin-react": "^4.7.0", + "autoprefixer": "^10.5.0", + "concurrently": "^9.2.1", + "electron": "^40.9.3", + "electron-builder": "^25.1.8", + "postcss": "^8.5.14", + "tailwindcss": "^3.4.19", + "typescript": "^5.9.3", + "vite": "^6.4.2", + "wait-on": "^8.0.5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@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.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@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.28.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "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.28.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@develar/schema-utils": { + "version": "2.6.5", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/@electron/asar": { + "version": "3.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/@electron/asar/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@electron/asar/node_modules/brace-expansion": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@electron/asar/node_modules/minimatch": { + "version": "3.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@electron/get": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@electron/notarize": { + "version": "2.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/notarize/node_modules/fs-extra": { + "version": "9.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/notarize/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/notarize/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/osx-sign": { + "version": "1.3.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@electron/osx-sign/node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/osx-sign/node_modules/isbinaryfile": { + "version": "4.0.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/@electron/osx-sign/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/osx-sign/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/rebuild": { + "version": "3.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "node-gyp": "^9.0.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@electron/rebuild/node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/rebuild/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/rebuild/node_modules/semver": { + "version": "7.7.4", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/rebuild/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/universal": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/asar": "^3.2.7", + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.3.1", + "dir-compare": "^4.2.0", + "fs-extra": "^11.1.1", + "minimatch": "^9.0.3", + "plist": "^3.1.0" + }, + "engines": { + "node": ">=16.4" + } + }, + "node_modules/@electron/universal/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@electron/universal/node_modules/brace-expansion": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/universal/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.9", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@electron/universal/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fontsource-variable/inter": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.2.8.tgz", + "integrity": "sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource-variable/jetbrains-mono": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource-variable/jetbrains-mono/-/jetbrains-mono-5.2.8.tgz", + "integrity": "sha512-WBA9elru6Jdp5df2mES55wuOO0WIrn3kpXnI4+W2ek5u3ZgLS9XS4gmIlcQhiZOWEKl95meYdvK7xI+ETLCq/Q==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource-variable/material-symbols-outlined": { + "version": "5.2.43", + "resolved": "https://registry.npmjs.org/@fontsource-variable/material-symbols-outlined/-/material-symbols-outlined-5.2.43.tgz", + "integrity": "sha512-daKLQrkSOjxPQZOmJX4OZ3mEOOH5T6q7/lF/Xoa5F4DqAYdEweNgFqHGTYf4EhiwumQp3mNUeJfJsR7paW/MRA==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@hapi/address": { + "version": "5.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^11.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@hapi/formula": { + "version": "3.0.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/hoek": { + "version": "11.0.7", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/pinpoint": { + "version": "2.0.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/tlds": { + "version": "1.1.6", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@hapi/topo": { + "version": "6.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^11.0.2" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "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", + "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", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@malept/cross-spawn-promise": { + "version": "2.0.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "license": "Apache-2.0", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/@malept/flatpak-bundler": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.0", + "lodash": "^4.17.15", + "tmp-promise": "^3.0.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/fs-extra": { + "version": "9.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/fs": { + "version": "2.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/fs/node_modules/semver": { + "version": "7.7.4", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/move-file": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@remix-run/router": { + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz", + "integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.3", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "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", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.12.2", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/plist": { + "version": "3.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*", + "xmlbuilder": ">=11.0.1" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/verror": { + "version": "1.10.11", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "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/@xmldom/xmldom": { + "version": "0.9.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.6" + } + }, + "node_modules/7zip-bin": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/agent-base": { + "version": "7.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "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/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "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/any-promise": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/app-builder-bin": { + "version": "5.0.0-alpha.10", + "dev": true, + "license": "MIT" + }, + "node_modules/app-builder-lib": { + "version": "25.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@develar/schema-utils": "~2.6.5", + "@electron/notarize": "2.5.0", + "@electron/osx-sign": "1.3.1", + "@electron/rebuild": "3.6.1", + "@electron/universal": "2.0.1", + "@malept/flatpak-bundler": "^0.4.0", + "@types/fs-extra": "9.0.13", + "async-exit-hook": "^2.0.1", + "bluebird-lst": "^1.0.9", + "builder-util": "25.1.7", + "builder-util-runtime": "9.2.10", + "chromium-pickle-js": "^0.2.0", + "config-file-ts": "0.2.8-rc1", + "debug": "^4.3.4", + "dotenv": "^16.4.5", + "dotenv-expand": "^11.0.6", + "ejs": "^3.1.8", + "electron-publish": "25.1.7", + "form-data": "^4.0.0", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", + "is-ci": "^3.0.0", + "isbinaryfile": "^5.0.0", + "js-yaml": "^4.1.0", + "json5": "^2.2.3", + "lazy-val": "^1.0.5", + "minimatch": "^10.0.0", + "resedit": "^1.7.0", + "sanitize-filename": "^1.6.3", + "semver": "^7.3.8", + "tar": "^6.1.12", + "temp-file": "^3.4.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "dmg-builder": "25.1.8", + "electron-builder-squirrel-windows": "25.1.8" + } + }, + "node_modules/app-builder-lib/node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/app-builder-lib/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/app-builder-lib/node_modules/semver": { + "version": "7.7.4", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/app-builder-lib/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aproba": { + "version": "2.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/archiver": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "dev": true, + "license": "MIT" + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "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.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.27", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bluebird-lst": { + "version": "1.0.9", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.5.5" + } + }, + "node_modules/boolean": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "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/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/builder-util": { + "version": "25.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/debug": "^4.1.6", + "7zip-bin": "~5.2.0", + "app-builder-bin": "5.0.0-alpha.10", + "bluebird-lst": "^1.0.9", + "builder-util-runtime": "9.2.10", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "debug": "^4.3.4", + "fs-extra": "^10.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "is-ci": "^3.0.0", + "js-yaml": "^4.1.0", + "source-map-support": "^0.5.19", + "stat-mode": "^1.0.0", + "temp-file": "^3.4.0" + } + }, + "node_modules/builder-util-runtime": { + "version": "9.2.10", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/builder-util/node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/builder-util/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/builder-util/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/cacache": { + "version": "16.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/cacache/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "8.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "5.1.9", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001792", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "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/chalk/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chromium-pickle-js": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ci-info": { + "version": "3.9.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/color-support": { + "version": "1.1.3", + "dev": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/compare-version": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/compress-commons": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/config-file-ts": { + "version": "0.2.8-rc1", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^10.3.12", + "typescript": "^5.4.3" + } + }, + "node_modules/config-file-ts/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/config-file-ts/node_modules/brace-expansion": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/config-file-ts/node_modules/glob": { + "version": "10.5.0", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/config-file-ts/node_modules/minimatch": { + "version": "9.0.9", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/config-file-ts/node_modules/minipass": { + "version": "7.1.3", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/crc": { + "version": "3.8.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.1.0" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dir-compare": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5", + "p-limit": "^3.1.0 " + } + }, + "node_modules/dir-compare/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/dir-compare/node_modules/brace-expansion": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/dir-compare/node_modules/minimatch": { + "version": "3.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/dmg-builder": { + "version": "25.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "25.1.8", + "builder-util": "25.1.7", + "builder-util-runtime": "9.2.10", + "fs-extra": "^10.1.0", + "iconv-lite": "^0.6.2", + "js-yaml": "^4.1.0" + }, + "optionalDependencies": { + "dmg-license": "^1.0.11" + } + }, + "node_modules/dmg-builder/node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dmg-builder/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/dmg-builder/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/dmg-license": { + "version": "1.0.11", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "@types/plist": "^3.0.1", + "@types/verror": "^1.10.3", + "ajv": "^6.10.0", + "crc": "^3.8.0", + "iconv-corefoundation": "^1.1.7", + "plist": "^3.0.4", + "smart-buffer": "^4.0.2", + "verror": "^1.10.0" + }, + "bin": { + "dmg-license": "bin/dmg-license.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "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/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron": { + "version": "40.9.3", + "resolved": "https://registry.npmjs.org/electron/-/electron-40.9.3.tgz", + "integrity": "sha512-rDcJOT6BBE689Ada+4jD3rVr05pMv9MZOgT0x/rIMVDF9c4ttx4RTb6lVARTyxZC7uqpirttCtcli1eg1DX5qg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^24.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, + "node_modules/electron-builder": { + "version": "25.1.8", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-25.1.8.tgz", + "integrity": "sha512-poRgAtUHHOnlzZnc9PK4nzG53xh74wj2Jy7jkTrqZ0MWPoHGh1M2+C//hGeYdA+4K8w4yiVCNYoLXF7ySj2Wig==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "25.1.8", + "builder-util": "25.1.7", + "builder-util-runtime": "9.2.10", + "chalk": "^4.1.2", + "dmg-builder": "25.1.8", + "fs-extra": "^10.1.0", + "is-ci": "^3.0.0", + "lazy-val": "^1.0.5", + "simple-update-notifier": "2.0.0", + "yargs": "^17.6.2" + }, + "bin": { + "electron-builder": "cli.js", + "install-app-deps": "install-app-deps.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/electron-builder-squirrel-windows": { + "version": "25.1.8", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "app-builder-lib": "25.1.8", + "archiver": "^5.3.1", + "builder-util": "25.1.7", + "fs-extra": "^10.1.0" + } + }, + "node_modules/electron-builder-squirrel-windows/node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-builder-squirrel-windows/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-builder-squirrel-windows/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-builder/node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-builder/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-builder/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-publish": { + "version": "25.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^9.0.11", + "builder-util": "25.1.7", + "builder-util-runtime": "9.2.10", + "chalk": "^4.1.2", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "mime": "^2.5.2" + } + }, + "node_modules/electron-publish/node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-publish/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-publish/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.352", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "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/es6-error": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/esbuild": { + "version": "0.25.12", + "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/esbuild/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/escalade": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.4.1", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "optional": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/filelist": { + "version": "1.0.6", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.9", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "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", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/framer-motion": { + "version": "12.38.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz", + "integrity": "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.38.0", + "motion-utils": "^12.36.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "dev": 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", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "4.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "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", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.14", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/global-agent/node_modules/semver": { + "version": "7.7.4", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/hasown": { + "version": "2.0.3", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-corefoundation": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "cli-truncate": "^2.1.0", + "node-addon-api": "^1.6.3" + }, + "engines": { + "node": "^8.11.2 || >=10" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ip-address": { + "version": "10.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/isbinaryfile": { + "version": "5.0.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "18.2.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/address": "^5.1.1", + "@hapi/formula": "^3.0.2", + "@hapi/hoek": "^11.0.7", + "@hapi/pinpoint": "^2.0.1", + "@hapi/tlds": "^1.1.1", + "@hapi/topo": "^6.0.2", + "@standard-schema/spec": "^1.1.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lazy-val": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/lazystream": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash": { + "version": "4.18.1", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.union": { + "version": "4.6.0", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-fetch-happen": { + "version": "10.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/http-proxy-agent": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/https-proxy-agent": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "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/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-fetch": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.7", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/motion-dom": { + "version": "12.38.0", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.36.0" + } + }, + "node_modules/motion-utils": { + "version": "12.36.0", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.12", + "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/negotiator": { + "version": "0.6.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-abi": { + "version": "3.92.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.7.4", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-api-version": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + } + }, + "node_modules/node-api-version/node_modules/semver": { + "version": "7.7.4", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp": { + "version": "9.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "7.7.4", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-releases": { + "version": "2.0.38", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "license": "ISC" + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.3", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/pe-library": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/plist": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.9.10", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "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.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/progress": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/pump": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", + "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", + "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.6" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "6.30.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz", + "integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz", + "integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.2", + "react-router": "6.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/read-binary-file-arch": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "bin": { + "read-binary-file-arch": "cli.js" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.9", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resedit": { + "version": "1.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "pe-library": "^0.4.1" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/responselike": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/rollup": { + "version": "4.60.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.60.3", + "@rollup/rollup-android-arm64": "4.60.3", + "@rollup/rollup-darwin-arm64": "4.60.3", + "@rollup/rollup-darwin-x64": "4.60.3", + "@rollup/rollup-freebsd-arm64": "4.60.3", + "@rollup/rollup-freebsd-x64": "4.60.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.3", + "@rollup/rollup-linux-arm-musleabihf": "4.60.3", + "@rollup/rollup-linux-arm64-gnu": "4.60.3", + "@rollup/rollup-linux-arm64-musl": "4.60.3", + "@rollup/rollup-linux-loong64-gnu": "4.60.3", + "@rollup/rollup-linux-loong64-musl": "4.60.3", + "@rollup/rollup-linux-ppc64-gnu": "4.60.3", + "@rollup/rollup-linux-ppc64-musl": "4.60.3", + "@rollup/rollup-linux-riscv64-gnu": "4.60.3", + "@rollup/rollup-linux-riscv64-musl": "4.60.3", + "@rollup/rollup-linux-s390x-gnu": "4.60.3", + "@rollup/rollup-linux-x64-gnu": "4.60.3", + "@rollup/rollup-linux-x64-musl": "4.60.3", + "@rollup/rollup-openbsd-x64": "4.60.3", + "@rollup/rollup-openharmony-arm64": "4.60.3", + "@rollup/rollup-win32-arm64-msvc": "4.60.3", + "@rollup/rollup-win32-ia32-msvc": "4.60.3", + "@rollup/rollup-win32-x64-gnu": "4.60.3", + "@rollup/rollup-win32-x64-msvc": "4.60.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.3.tgz", + "integrity": "sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.3.tgz", + "integrity": "sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.3.tgz", + "integrity": "sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.3.tgz", + "integrity": "sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.3.tgz", + "integrity": "sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.3.tgz", + "integrity": "sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.3.tgz", + "integrity": "sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.3.tgz", + "integrity": "sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.3.tgz", + "integrity": "sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.3.tgz", + "integrity": "sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.3.tgz", + "integrity": "sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.3.tgz", + "integrity": "sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.3.tgz", + "integrity": "sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.3.tgz", + "integrity": "sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.3.tgz", + "integrity": "sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.3.tgz", + "integrity": "sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.3.tgz", + "integrity": "sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.3.tgz", + "integrity": "sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.3.tgz", + "integrity": "sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.3.tgz", + "integrity": "sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.3.tgz", + "integrity": "sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.3.tgz", + "integrity": "sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.3.tgz", + "integrity": "sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.3.tgz", + "integrity": "sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/sanitize-filename": { + "version": "1.6.4", + "dev": true, + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sax": { + "version": "1.6.0", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.7.4", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.8", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.1.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/ssri": { + "version": "9.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/stat-mode": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", + "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/temp-file": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "async-exit-hook": "^2.0.1", + "fs-extra": "^10.0.0" + } + }, + "node_modules/temp-file/node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/temp-file/node_modules/jsonfile": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/temp-file/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "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/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tmp": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "dev": true, + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "0.13.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "dev": true, + "license": "MIT" + }, + "node_modules/unique-filename": { + "version": "2.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/unique-slug": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "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", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/verror": { + "version": "1.10.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/vite": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz", + "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==", + "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/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/wait-on": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.5.tgz", + "integrity": "sha512-J3WlS0txVHkhLRb2FsmRg3dkMTCV1+M6Xra3Ho7HzZDHpE7DCOnoSoCJsZotrmW3uRMhvIJGSKUKrh/MeF4iag==", + "dev": true, + "license": "MIT", + "dependencies": { + "axios": "^1.12.1", + "joi": "^18.0.1", + "lodash": "^4.17.21", + "minimist": "^1.2.8", + "rxjs": "^7.8.2" + }, + "bin": { + "wait-on": "bin/wait-on" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zip-stream": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zustand": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.13.tgz", + "integrity": "sha512-efI2tVaVQPqtOh114loML/Z80Y4NP3yc+Ff0fYiZJPauNeWZeIp/bRFD7I9bfmCOYBh/PHxlglQ9+wvlwnPikQ==", + "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 + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..8d03be2 --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "maqt-desktop", + "version": "7.0.4", + "main": "electron/main.js", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "electron:dev": "concurrently \"vite\" \"wait-on http://localhost:5173 && electron .\"", + "electron:build": "vite build && electron-builder" + }, + "dependencies": { + "@fontsource-variable/inter": "^5.2.8", + "@fontsource-variable/jetbrains-mono": "^5.2.8", + "@fontsource-variable/material-symbols-outlined": "^5.2.43", + "axios": "^1.16.0", + "framer-motion": "^12.38.0", + "react": "^19.2.6", + "react-dom": "^19.2.6", + "react-router-dom": "^6.30.3", + "zustand": "^5.0.13" + }, + "devDependencies": { + "@vitejs/plugin-react": "^4.7.0", + "autoprefixer": "^10.5.0", + "concurrently": "^9.2.1", + "electron": "^40.9.3", + "electron-builder": "^25.1.8", + "postcss": "^8.5.14", + "tailwindcss": "^3.4.19", + "typescript": "^5.9.3", + "vite": "^6.4.2", + "wait-on": "^8.0.5" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..2aa7205 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/scripts/scrape_schemes.js b/scripts/scrape_schemes.js new file mode 100644 index 0000000..9c4c9be --- /dev/null +++ b/scripts/scrape_schemes.js @@ -0,0 +1,128 @@ +// 改枪方案数据采集器 +// 在 Windows 上运行: node scrape_schemes.js +// 原理: 加载原版 app 的解密模块来解密方案数据 + +const https = require('https'); +const http = require('http'); +const crypto = require('crypto'); +const fs = require('fs'); +const path = require('path'); + +// ========== 配置 ========== +const API_BASE = 'maqt.top'; +const TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NDc5MTcsInVzZXJuYW1lIjoic2l4dGVlbnRoIiwidG9rZW5WZXJzaW9uIjozLCJpYXQiOjE3NzgyMTI0MDUsImV4cCI6MjA5Mzc4ODQwNX0.B_J0CDtaiiF2jJ592yKtD4RtQDIR3cDF_EYgn2UM2ko'; +const CATEGORIES = ['AR','SMG','SR','LMG','SG','Pistol','Launcher']; +const OUR_API = 'http://100.105.17.52:3001'; // 导入到自建后端 + +// ========== 尝试多种 AES 密钥 ========== +const KEYS_TO_TRY = [ + Buffer.from('maqt-encryption-key-32bytes!', 'utf-8'), // 28 bytes + Buffer.from('maqt-encryption-key-32bytes!!', 'utf-8'), // 29 bytes + Buffer.from('0123456789abcdef0123456789abcdef', 'utf-8'), // 32 bytes (HEX) + Buffer.from('maqt-encryption-key-32byte!', 'utf-8'), // 27 bytes +]; + +function aesDecrypt(ivHex, dataHex, key) { + try { + // Pad key to 32 bytes with zeros if needed + const keyBuf = key.length === 32 ? key : Buffer.concat([key, Buffer.alloc(32 - key.length)]); + const iv = Buffer.from(ivHex, 'hex'); + const encrypted = Buffer.from(dataHex, 'hex'); + const decipher = crypto.createDecipheriv('aes-256-cbc', keyBuf, iv); + let d = decipher.update(encrypted, undefined, 'utf-8'); + d += decipher.final('utf-8'); + return JSON.parse(d); + } catch (e) { + return null; + } +} + +function fetch(url, postData) { + return new Promise((resolve, reject) => { + const opts = { + hostname: API_BASE, path: url, + method: postData ? 'POST' : 'GET', + headers: { + 'Authorization': `Bearer ${TOKEN}`, + 'User-Agent': 'MaQiangTang/7.0.4', + 'Accept': 'application/json', + }, + }; + if (postData) { opts.headers['Content-Type'] = 'application/json'; } + const req = https.request(opts, res => { + let d = ''; + res.on('data', c => d += c); + res.on('end', () => { + try { resolve(JSON.parse(d)); } + catch { resolve({ error: 'parse', raw: d.slice(0,100) }); } + }); + }); + req.on('error', reject); + if (postData) req.write(JSON.stringify(postData)); + req.end(); + }); +} + +function tryDecrypt(encrypted) { + if (!encrypted.encrypted) return encrypted; + for (const key of KEYS_TO_TRY) { + const result = aesDecrypt(encrypted.iv, encrypted.data, key); + if (result) { + console.log(` ✅ 解密成功! 密钥: ${key.toString('utf-8')}`); + return result; + } + } + return null; +} + +async function main() { + console.log('=== 码枪堂方案数据采集器 ===\n'); + + // 1. 测试解密 + console.log('--- 获取测试数据 ---'); + const testData = await fetch('/api/schemes?sort=hot&page=1&limit=2&weaponCategory=AR'); + + if (testData.encrypted) { + console.log(` 加密数据: iv=${testData.iv} data_len=${testData.data.length}`); + const decrypted = tryDecrypt(testData); + if (!decrypted) { + console.log(' ❌ 所有密钥都不匹配'); + console.log(' 请从 deobfuscated main.js 中找到正确的密钥'); + console.log(' 或在原始应用中运行:'); + console.log(' require("crypto").createDecipheriv("aes-256-cbc", , )'); + return; + } + fs.writeFileSync('decrypted_schemes.json', JSON.stringify(decrypted, null, 2)); + console.log(' 已保存到 decrypted_schemes.json'); + } else { + console.log(' 明文响应:', JSON.stringify(testData).slice(0, 500)); + } + + // 2. 如果解密成功,采集所有分类 + if (fs.existsSync('decrypted_schemes.json')) { + console.log('\n--- 全量采集 ---'); + const allSchemes = []; + + for (const cat of CATEGORIES) { + console.log(`\n分类: ${cat}`); + for (let page = 1; page <= 5; page++) { + const data = await fetch(`/api/schemes?sort=hot&page=${page}&limit=12&weaponCategory=${encodeURIComponent(cat)}`); + if (data.encrypted) { + const decrypted = tryDecrypt(data); + if (decrypted && Array.isArray(decrypted)) { + allSchemes.push(...decrypted); + console.log(` 第${page}页: ${decrypted.length} 条`); + if (decrypted.length < 12) break; + } else break; + } else break; + } + } + + console.log(`\n共采集 ${allSchemes.length} 条方案`); + fs.writeFileSync('all_schemes.json', JSON.stringify(allSchemes, null, 2)); + } + + console.log('\n完成'); +} + +main().catch(console.error); diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..8b1c7ba --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { BrowserRouter } from 'react-router-dom'; +import AppRouter from './router'; +import ToastContainer from './components/ui/Toast'; + +export default function App() { + return ( + + + + + ); +} diff --git a/src/components/filters/FilterCard.tsx b/src/components/filters/FilterCard.tsx new file mode 100644 index 0000000..a53c69b --- /dev/null +++ b/src/components/filters/FilterCard.tsx @@ -0,0 +1,65 @@ +import React from 'react'; + +export interface FilterData { + id: string; + title: string; + author: string; + category: string; + likes: number; + downloads: number; + preview?: string; + description: string; +} + +interface FilterCardProps { + filter: FilterData; + liked: boolean; + onLike: (id: string) => void; + onDownload: (id: string) => void; +} + +export default function FilterCard({ filter, liked, onLike, onDownload }: FilterCardProps) { + return ( +
+
+
+ + {/* 预览占位 */} +
+ image +
+ + {/* 信息 */} +
+
+

+ {filter.title} +

+
+

{filter.author}

+ +
+
+ + ↓ {filter.downloads} +
+ +
+
+ + {filter.category.toUpperCase().slice(0, 4)} +
+ ); +} diff --git a/src/components/filters/FilterEditor.tsx b/src/components/filters/FilterEditor.tsx new file mode 100644 index 0000000..2d11843 --- /dev/null +++ b/src/components/filters/FilterEditor.tsx @@ -0,0 +1,152 @@ +import React, { useState } from 'react'; +import Card from '../ui/Card'; +import Button from '../ui/Button'; + +interface FilterParams { + brightness: number; + contrast: number; + saturation: number; + gamma: number; + temperature: number; + rGain: number; + gGain: number; + bGain: number; + vibrance: number; +} + +interface FilterEditorProps { + initialParams?: Partial; + onSave?: (params: FilterParams) => void; + onCancel?: () => void; +} + +function SliderControl({ label, value, min, max, step, unit, onChange }: { + label: string; + value: number; + min: number; + max: number; + step: number; + unit: string; + onChange: (v: number) => void; +}) { + const pct = ((value - min) / (max - min)) * 100; + return ( +
+ {label} +
+
+ onChange(+e.target.value)} + className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" + /> +
+ {value.toFixed(step < 0.1 ? 2 : 1)}{unit} +
+ ); +} + +const DEFAULT_PARAMS: FilterParams = { + brightness: 0, + contrast: 0, + saturation: 0, + gamma: 1.0, + temperature: 6500, + rGain: 1.0, + gGain: 1.0, + bGain: 1.0, + vibrance: 0, +}; + +export default function FilterEditor({ initialParams, onSave, onCancel }: FilterEditorProps) { + const [params, setParams] = useState({ ...DEFAULT_PARAMS, ...initialParams }); + const [name, setName] = useState(''); + + const update = (key: keyof FilterParams) => (val: number) => setParams(prev => ({ ...prev, [key]: val })); + + return ( +
+ {/* Name */} + +
+
+ tune +

滤镜编辑器

+
+ + setName(e.target.value)} + placeholder="滤镜名称" + className="w-full border border-[#333] bg-[#111] text-[#e0e0e0] px-2 py-1.5 text-[9px] font-mono + placeholder:text-[#444] outline-none focus:border-[#ff4500] transition-colors duration-75" + /> +
+
+ + {/* Tone controls */} + +
+

色调

+ + + + + +
+
+ + {/* Color balance */} + +
+

色彩平衡

+ + + + +
+
+ + {/* Preview bar */} + +
+

预览

+
+ {/* Color gradient preview affected by params */} +
6500 ? 0.1 : 0}) 100%)`, + }} + /> + {/* RGB indicator */} +
+
+
+
+
+
+
+ + + {/* Actions */} +
+ + + +
+
+ ); +} diff --git a/src/components/filters/FilterGrid.tsx b/src/components/filters/FilterGrid.tsx new file mode 100644 index 0000000..ca93fc2 --- /dev/null +++ b/src/components/filters/FilterGrid.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import FilterCard from './FilterCard'; +import type { FilterData } from './FilterCard'; + +interface FilterGridProps { + filters: FilterData[]; + loading: boolean; + likedIds: Set; + onLike: (id: string) => void; + onDownload: (id: string) => void; +} + +export default function FilterGrid({ filters, loading, likedIds, onLike, onDownload }: FilterGridProps) { + if (loading) { + return ( +
+ {Array.from({ length: 6 }).map((_, i) => ( +
+
+
+
+
+ ))} +
+ ); + } + + if (filters.length === 0) { + return ( +
+ photo_library +

暂无滤镜数据

+ 空状态 / 暂无数据 +
+ ); + } + + return ( +
+ {filters.map(f => ( + + ))} +
+ ); +} diff --git a/src/components/filters/FilterPreview.tsx b/src/components/filters/FilterPreview.tsx new file mode 100644 index 0000000..003c0bc --- /dev/null +++ b/src/components/filters/FilterPreview.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import Card from '../ui/Card'; + +interface FilterPreviewProps { + filter: { title: string; description?: string; previewUrl?: string }; + onClose?: () => void; +} + +export default function FilterPreview({ filter, onClose }: FilterPreviewProps) { + return ( + +
+

{filter.title}

+ {onClose && } +
+ + {/* Preview image area */} +
+ {filter.previewUrl ? ( + {filter.title} + ) : ( +
+ image + 预览区域 +
+ )} +
+ + {filter.description && ( +

{filter.description}

+ )} +
+ ); +} diff --git a/src/components/layout/BottomDock.tsx b/src/components/layout/BottomDock.tsx new file mode 100644 index 0000000..867c146 --- /dev/null +++ b/src/components/layout/BottomDock.tsx @@ -0,0 +1,43 @@ +import React from 'react'; + +interface DockItem { + id: string; + label: string; + icon: string; +} + +interface BottomDockProps { + items: DockItem[]; + currentPage: string; + onNavigate: (page: string) => void; + visible?: boolean; +} + +export default function BottomDock({ items, currentPage, onNavigate, visible = true }: BottomDockProps) { + if (!visible) return null; + + return ( +
+
+ {items.map(item => { + const isActive = currentPage === item.id; + return ( + + ); + })} +
+
+ ); +} diff --git a/src/components/layout/DesktopGrid.tsx b/src/components/layout/DesktopGrid.tsx new file mode 100644 index 0000000..285b129 --- /dev/null +++ b/src/components/layout/DesktopGrid.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import DesktopIcon from './DesktopIcon'; + +interface DesktopItem { + id: string; + icon: string; + label: string; + vip?: boolean; + loginRequired?: boolean; + locked?: boolean; + action: () => void; +} + +interface DesktopGridProps { + items: DesktopItem[]; + rows?: number; + cols?: number; +} + +export default function DesktopGrid({ items, rows = 2, cols = 4 }: DesktopGridProps) { + return ( +
+ {items.map((item, idx) => ( + + ))} +
+ ); +} diff --git a/src/components/layout/DesktopIcon.tsx b/src/components/layout/DesktopIcon.tsx new file mode 100644 index 0000000..19b9c95 --- /dev/null +++ b/src/components/layout/DesktopIcon.tsx @@ -0,0 +1,64 @@ +import React from 'react'; + +interface DesktopIconProps { + icon: string; + label: string; + onClick?: () => void; + disabled?: boolean; + locked?: boolean; + vip?: boolean; + index?: number; +} + +export default function DesktopIcon({ icon, label, onClick, disabled, locked, vip, index = 0 }: DesktopIconProps) { + const isBlocked = locked || disabled; + + return ( + + ); +} diff --git a/src/components/layout/PageContainer.tsx b/src/components/layout/PageContainer.tsx new file mode 100644 index 0000000..9a25999 --- /dev/null +++ b/src/components/layout/PageContainer.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +interface PageContainerProps { + children: React.ReactNode; + className?: string; +} + +export default function PageContainer({ children, className = '' }: PageContainerProps) { + return ( +
+ {children} +
+ ); +} diff --git a/src/components/layout/TopBar.tsx b/src/components/layout/TopBar.tsx new file mode 100644 index 0000000..c850387 --- /dev/null +++ b/src/components/layout/TopBar.tsx @@ -0,0 +1,79 @@ +import React from 'react'; +import Compass from '../ui/Compass'; + +interface TopBarProps { + cpuTemp?: number; + gpuTemp?: number; + fps?: number; + isVip?: boolean; + ping?: number; + onMinimize?: () => void; + onMaximize?: () => void; + onClose?: () => void; +} + +export default function TopBar({ + cpuTemp = 52, gpuTemp = 68, fps = 144, isVip, ping = 20, + onMinimize, onMaximize, onClose, +}: TopBarProps) { + return ( +
+ {/* Left: Time + Compass */} +
+ + + {new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })} + +
+ + ONLINE +
+
+ + {/* Center: Hardware status */} +
+
+ CPU + {cpuTemp}° +
+
+
+
+
+ GPU + {gpuTemp}° +
+
+
+
+
+ FPS + {fps} +
+
+ + {/* Right: VIP + Network + Controls */} +
+ {isVip && ( +
+ ✦ VIP + +
+ )} +
+ + {ping}ms +
+
+ + + +
+
+
+ ); +} diff --git a/src/components/layout/TopHud.tsx b/src/components/layout/TopHud.tsx new file mode 100644 index 0000000..ec71491 --- /dev/null +++ b/src/components/layout/TopHud.tsx @@ -0,0 +1,34 @@ +import React from 'react'; + +interface TopHudProps { + title?: string; + subtitle?: string; + sections?: { label: string; value: string }[]; +} + +export default function TopHud({ title = '码枪堂 2.0', subtitle, sections = [] }: TopHudProps) { + return ( +
+
+ +

{title}

+ {subtitle && ( + <> + | + {subtitle} + + )} +
+
+ {sections.map((s, i) => ( + + {s.label} + {s.value} + + ))} + + V0.2.1 +
+
+ ); +} diff --git a/src/components/optimization/OptimizeItem.tsx b/src/components/optimization/OptimizeItem.tsx new file mode 100644 index 0000000..20c4052 --- /dev/null +++ b/src/components/optimization/OptimizeItem.tsx @@ -0,0 +1,77 @@ +import React from 'react'; + +export interface OptimizeItemData { + id: string; + label: string; + description: string; + category: string; + icon: string; + status: 'pending' | 'optimized' | 'restored' | 'error'; +} + +interface OptimizeItemProps { + item: OptimizeItemData; + onToggle: (id: string, action: 'optimize' | 'restore') => void; + disabled?: boolean; +} + +const statusStyles: Record = { + pending: 'border-[#333]', + optimized: 'border-[#ff4500]/50 bg-[#ff4500]/5', + restored: 'border-[#333]', + error: 'border-[#cc3300]/50 bg-[#cc3300]/5', +}; + +const statusTextStyles: Record = { + pending: 'text-[#555]', + optimized: 'text-[#ff4500]', + restored: 'text-[#555]', + error: 'text-[#cc3300]', +}; + +const statusLabels: Record = { + pending: '待优化', + optimized: '已优化', + restored: '已恢复', + error: '失败', +}; + +export default function OptimizeItem({ item, onToggle, disabled }: OptimizeItemProps) { + const isOptimized = item.status === 'optimized'; + + return ( +
+
+
+ +
+
+ {item.icon} + + {item.label} + + + {statusLabels[item.status]} + +
+

{item.description}

+
+ + +
+
+ ); +} diff --git a/src/components/optimization/OptimizePanel.tsx b/src/components/optimization/OptimizePanel.tsx new file mode 100644 index 0000000..e1f3691 --- /dev/null +++ b/src/components/optimization/OptimizePanel.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import Panel from '../ui/Panel'; +import OptimizeItem from './OptimizeItem'; +import type { OptimizeItemData } from './OptimizeItem'; + +interface OptimizePanelProps { + title: string; + icon: string; + items: OptimizeItemData[]; + onToggle: (id: string, action: 'optimize' | 'restore') => void; + disabled?: boolean; + defaultOpen?: boolean; + serial?: string; +} + +export default function OptimizePanel({ title, icon, items, onToggle, disabled, defaultOpen = true, serial }: OptimizePanelProps) { + const optimized = items.filter(i => i.status === 'optimized').length; + return ( + +
+ {items.map(item => ( + + ))} +
+
+ ); +} diff --git a/src/components/optimization/OptimizeResult.tsx b/src/components/optimization/OptimizeResult.tsx new file mode 100644 index 0000000..acbd5a2 --- /dev/null +++ b/src/components/optimization/OptimizeResult.tsx @@ -0,0 +1,38 @@ +import React from 'react'; + +interface OptimizeResultProps { + success: boolean; + message: string; + details?: string[]; + onClose?: () => void; +} + +export default function OptimizeResult({ success, message, details, onClose }: OptimizeResultProps) { + return ( +
+
+ + {success ? '▸' : '✕'} + +
+

+ {success ? '优化完成' : '优化失败'} +

+

{message}

+ {details && details.length > 0 && ( +
+ {details.map((d, i) => ( +

▸ {d}

+ ))} +
+ )} +
+ {onClose && ( + + )} +
+
+ ); +} diff --git a/src/components/schemes/CategoryTabs.tsx b/src/components/schemes/CategoryTabs.tsx new file mode 100644 index 0000000..dd7d141 --- /dev/null +++ b/src/components/schemes/CategoryTabs.tsx @@ -0,0 +1,39 @@ +import React from 'react'; + +interface Category { + code: string; + name: string; +} + +interface CategoryTabsProps { + categories: Category[]; + activeCode: string; + onSelect: (code: string) => void; + className?: string; +} + +export default function CategoryTabs({ categories, activeCode, onSelect, className = '' }: CategoryTabsProps) { + return ( +
+
+ {categories.map(cat => ( + + ))} +
+
+ ); +} diff --git a/src/components/schemes/SchemeCard.tsx b/src/components/schemes/SchemeCard.tsx new file mode 100644 index 0000000..9cd3720 --- /dev/null +++ b/src/components/schemes/SchemeCard.tsx @@ -0,0 +1,89 @@ +import React from 'react'; +import Button from '../ui/Button'; +import Card from '../ui/Card'; + +export interface SchemeData { + id: string; + title: string | null; + weaponName: string | null; + category: string | null; + viewsCount: number; + downloadsCount: number; + likesCount: number; + favoritesCount: number; + price: number; + isOfficial: boolean; + user?: { username: string }; +} + +interface SchemeCardProps { + scheme: SchemeData; + isFavorited?: boolean; + onFavorite?: (id: string) => void; + onUse?: (id: string) => void; + onClick?: (id: string) => void; + className?: string; +} + +export default function SchemeCard({ scheme, isFavorited, onFavorite, onUse, onClick, className = '' }: SchemeCardProps) { + return ( + onClick?.(scheme.id)} + className={`flex flex-col p-3 gap-2 ${className}`} + serial={scheme.isOfficial ? 'OFFICIAL' : undefined} + > + {/* 标题 */} +
+
+

+ {scheme.title || '未命名方案'} +

+

{scheme.weaponName || scheme.category || '通用'}

+
+ {scheme.isOfficial && ( + + 官方 + + )} +
+ + {/* 作者 */} + {scheme.user?.username && ( +

作者: {scheme.user.username}

+ )} + + {/* 价格 */} + {scheme.price > 0 && ( +

💰 {scheme.price}

+ )} + + {/* 操作按钮 */} +
+ + +
+ + {/* 统计数据 */} +
+ 👁 {scheme.viewsCount} + ⬇ {scheme.downloadsCount} + 👍 {scheme.likesCount} +
+
+ ); +} diff --git a/src/components/schemes/SchemeEditor.tsx b/src/components/schemes/SchemeEditor.tsx new file mode 100644 index 0000000..d42694d --- /dev/null +++ b/src/components/schemes/SchemeEditor.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +export default function SchemeEditor() { + return ( +
+ construction +

方案编辑器

+

开发中

+
+ ); +} diff --git a/src/components/schemes/SchemeList.tsx b/src/components/schemes/SchemeList.tsx new file mode 100644 index 0000000..ea7605a --- /dev/null +++ b/src/components/schemes/SchemeList.tsx @@ -0,0 +1,95 @@ +import React from 'react'; +import SchemeCard from './SchemeCard'; +import type { SchemeData } from './SchemeCard'; + +interface SchemeListProps { + schemes: SchemeData[]; + loading?: boolean; + favoritedIds?: Set; + page: number; + totalPages: number; + onPageChange: (page: number) => void; + onFavorite: (id: string) => void; + onUse: (id: string) => void; + onClick: (id: string) => void; + className?: string; +} + +export default function SchemeList({ + schemes, loading, favoritedIds = new Set(), + page, totalPages, onPageChange, + onFavorite, onUse, onClick, className = '' +}: SchemeListProps) { + if (loading) { + return ( +
+ {Array.from({ length: 6 }).map((_, i) => ( +
+
+
+
+
+ ))} +
+ ); + } + + if (!schemes.length) { + return ( +
+ 📭 +

暂无方案数据

+ EMPTY / 404 +
+ ); + } + + return ( +
+
+ {schemes.map(s => ( + + ))} +
+ + {/* 分页 */} + {totalPages > 1 && ( +
+ + {Array.from({ length: totalPages }).map((_, i) => ( + + ))} + +
+ )} +
+ ); +} diff --git a/src/components/schemes/SchemePreviewer.tsx b/src/components/schemes/SchemePreviewer.tsx new file mode 100644 index 0000000..c9668f7 --- /dev/null +++ b/src/components/schemes/SchemePreviewer.tsx @@ -0,0 +1,35 @@ +import React from 'react'; + +interface SchemePreviewerProps { + content?: string; + className?: string; +} + +export default function SchemePreviewer({ content, className = '' }: SchemePreviewerProps) { + if (!content) { + return ( +
+ 暂无预览内容 +
+ ); + } + + try { + const parsed = JSON.parse(content); + return ( +
+
+          {JSON.stringify(parsed, null, 2)}
+        
+
+ ); + } catch { + return ( +
+

+ {content} +

+
+ ); + } +} diff --git a/src/components/ui/Badge.tsx b/src/components/ui/Badge.tsx new file mode 100644 index 0000000..e63327e --- /dev/null +++ b/src/components/ui/Badge.tsx @@ -0,0 +1,25 @@ +import React from 'react'; + +type BadgeVariant = 'default' | 'vip' | 'success' | 'warning' | 'error'; + +interface BadgeProps { + children: React.ReactNode; + variant?: BadgeVariant; + className?: string; +} + +const styleMap: Record = { + default: 'border-[#333] text-[#555]', + vip: 'border-[#ff4500]/40 text-[#ff4500]', + success: 'border-[#ff4500]/40 text-[#ff4500]', + warning: 'border-[#ff4500]/40 text-[#ff4500]', + error: 'border-[#cc3300]/40 text-[#cc3300]', +}; + +export default function Badge({ children, variant = 'default', className = '' }: BadgeProps) { + return ( + + {children} + + ); +} diff --git a/src/components/ui/Button.tsx b/src/components/ui/Button.tsx new file mode 100644 index 0000000..0f8a8fb --- /dev/null +++ b/src/components/ui/Button.tsx @@ -0,0 +1,55 @@ +import React from 'react'; + +type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger'; +type ButtonSize = 'sm' | 'md' | 'lg'; + +interface ButtonProps extends React.ButtonHTMLAttributes { + variant?: ButtonVariant; + size?: ButtonSize; + loading?: boolean; +} + +const variantStyles: Record = { + primary: + 'bg-[#ff4500] text-[#111] border-[#ff4500] hover:bg-[#111] hover:text-[#ff4500]', + secondary: + 'bg-transparent text-[#e0e0e0] border-[#555] hover:bg-[#e0e0e0] hover:text-[#111]', + ghost: + 'bg-transparent text-[#888] border-[#333] hover:border-[#e0e0e0] hover:text-[#e0e0e0]', + danger: + 'bg-transparent text-[#cc3300] border-[#cc3300] hover:bg-[#cc3300] hover:text-[#111]', +}; + +const sizeStyles: Record = { + sm: 'px-3 py-1.5 text-[10px]', + md: 'px-5 py-2.5 text-[11px]', + lg: 'px-7 py-3 text-[13px]', +}; + +export default function Button({ + variant = 'primary', + size = 'md', + loading, + disabled, + className = '', + children, + ...props +}: ButtonProps) { + return ( + + ); +} diff --git a/src/components/ui/Card.tsx b/src/components/ui/Card.tsx new file mode 100644 index 0000000..45526d6 --- /dev/null +++ b/src/components/ui/Card.tsx @@ -0,0 +1,39 @@ +import React from 'react'; + +interface CardProps { + children: React.ReactNode; + highlighted?: boolean; + hoverable?: boolean; + className?: string; + onClick?: () => void; + serial?: string; +} + +export default function Card({ + children, + highlighted, + hoverable, + className = '', + onClick, + serial, +}: CardProps) { + return ( +
+ {/* Cut corner decorations */} +
+
+ + {serial && ( + {serial} + )} + + {children} +
+ ); +} diff --git a/src/components/ui/Compass.tsx b/src/components/ui/Compass.tsx new file mode 100644 index 0000000..3c47a1b --- /dev/null +++ b/src/components/ui/Compass.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +export default function Compass({ className = '' }: { className?: string }) { + return ( + + + + {[0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330].map((deg, i) => { + const rad = (deg - 90) * (Math.PI / 180); + const inner = i % 3 === 0 ? 12 : 13; + const outer = i % 3 === 0 ? 15 : 14.5; + return ( + + ); + })} + + + + ); +} diff --git a/src/components/ui/Input.tsx b/src/components/ui/Input.tsx new file mode 100644 index 0000000..6b2f3e5 --- /dev/null +++ b/src/components/ui/Input.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +interface InputProps extends React.InputHTMLAttributes { + label?: string; +} + +export default function Input({ label, className = '', ...props }: InputProps) { + return ( +
+ {label && {label}} + +
+ ); +} diff --git a/src/components/ui/Modal.tsx b/src/components/ui/Modal.tsx new file mode 100644 index 0000000..1b6c0ac --- /dev/null +++ b/src/components/ui/Modal.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; + +interface ModalProps { + open: boolean; + onClose: () => void; + title?: string; + children: React.ReactNode; + size?: 'sm' | 'md' | 'lg'; +} + +const sizeMap = { sm: 'max-w-sm', md: 'max-w-lg', lg: 'max-w-2xl' }; + +export default function Modal({ open, onClose, title, children, size = 'md' }: ModalProps) { + return ( + + {open && ( +
+ + + {title && ( +
+

{title}

+ +
+ )} +
{children}
+
+
+ )} +
+ ); +} diff --git a/src/components/ui/Panel.tsx b/src/components/ui/Panel.tsx new file mode 100644 index 0000000..974de73 --- /dev/null +++ b/src/components/ui/Panel.tsx @@ -0,0 +1,54 @@ +import React, { useState } from 'react'; + +interface PanelProps { + title: string; + children: React.ReactNode; + collapsible?: boolean; + defaultOpen?: boolean; + className?: string; + serial?: string; +} + +export default function Panel({ + title, + children, + collapsible, + defaultOpen = true, + className = '', + serial, +}: PanelProps) { + const [open, setOpen] = useState(defaultOpen); + + return ( +
+ {/* Cut corner */} +
+
+ + {/* Header */} +
collapsible && setOpen(!open)} + > +
+ +

+ {title} +

+
+
+ {serial && {serial}} + {collapsible && ( + + ▼ + + )} +
+
+ + {/* Body */} + {open &&
{children}
} +
+ ); +} diff --git a/src/components/ui/ProgressBar.tsx b/src/components/ui/ProgressBar.tsx new file mode 100644 index 0000000..c2c6420 --- /dev/null +++ b/src/components/ui/ProgressBar.tsx @@ -0,0 +1,29 @@ +import React from 'react'; + +interface ProgressBarProps { + value: number; + max?: number; + label?: string; + className?: string; +} + +export default function ProgressBar({ value, max = 100, label, className = '' }: ProgressBarProps) { + const pct = Math.min((value / max) * 100, 100); + + return ( +
+
+
+
+
+
+ {label && {label}} +
+ ); +} diff --git a/src/components/ui/Skeleton.tsx b/src/components/ui/Skeleton.tsx new file mode 100644 index 0000000..731520e --- /dev/null +++ b/src/components/ui/Skeleton.tsx @@ -0,0 +1,9 @@ +import React from 'react'; + +interface SkeletonProps { + className?: string; +} + +export default function Skeleton({ className = '' }: SkeletonProps) { + return
; +} diff --git a/src/components/ui/Toast.tsx b/src/components/ui/Toast.tsx new file mode 100644 index 0000000..cb33fbb --- /dev/null +++ b/src/components/ui/Toast.tsx @@ -0,0 +1,57 @@ +import React, { useEffect, useState } from 'react'; + +type ToastType = 'success' | 'error' | 'warning' | 'info'; + +interface ToastMessage { + id: number; + type: ToastType; + text: string; +} + +let toastId = 0; +const listeners: Set<(msg: ToastMessage) => void> = new Set(); + +export function showToast(text: string, type: ToastType = 'info') { + const msg: ToastMessage = { id: ++toastId, type, text }; + listeners.forEach(fn => fn(msg)); +} + +export function useToast() { + return (type: ToastType, text: string) => showToast(text, type); +} + +const typeColors: Record = { + success: 'border-[#ff4500] text-[#ff4500]', + error: 'border-[#cc3300] text-[#cc3300]', + warning: 'border-[#ff4500] text-[#ff4500]', + info: 'border-[#555] text-[#e0e0e0]', +}; + +export default function ToastContainer() { + const [toasts, setToasts] = useState([]); + + useEffect(() => { + const handler = (msg: ToastMessage) => { + setToasts(prev => [...prev, msg]); + setTimeout(() => { + setToasts(prev => prev.filter(t => t.id !== msg.id)); + }, 3000); + }; + listeners.add(handler); + return () => { listeners.delete(handler); }; + }, []); + + return ( +
+ {toasts.map(t => ( +
+ ▸ {t.text} +
+ ))} +
+ ); +} diff --git a/src/hooks/useApi.ts b/src/hooks/useApi.ts new file mode 100644 index 0000000..f00472b --- /dev/null +++ b/src/hooks/useApi.ts @@ -0,0 +1,25 @@ +import { useState, useCallback } from 'react'; + +export function useApi() { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const execute = useCallback(async (fn: () => Promise) => { + setLoading(true); + setError(null); + try { + const res = await fn(); + setData(res.data || res); + return res; + } catch (e: any) { + const msg = e?.response?.data?.message || e.message || '请求失败'; + setError(msg); + throw e; + } finally { + setLoading(false); + } + }, []); + + return { data, loading, error, execute }; +} diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts new file mode 100644 index 0000000..46c9726 --- /dev/null +++ b/src/hooks/useAuth.ts @@ -0,0 +1,23 @@ +import { useAuthStore } from '../stores/authStore'; +import { login as loginApi } from '../services/auth.api'; +import type { LoginRequest } from '../types'; + +export function useAuth() { + const store = useAuthStore(); + return { + ...store, + login: async (data: LoginRequest) => { + try { + const res = await loginApi(data); + if (res.success && res.token && res.user) { + store.login(res.token, res.user); + return true; + } + return false; + } catch (e: any) { + const msg = e?.response?.data?.message || '登录失败'; + throw new Error(msg); + } + }, + }; +} diff --git a/src/hooks/useElectron.ts b/src/hooks/useElectron.ts new file mode 100644 index 0000000..2427caa --- /dev/null +++ b/src/hooks/useElectron.ts @@ -0,0 +1,16 @@ +export function useElectron() { + if (typeof window !== 'undefined' && window.electronAPI) { + return window.electronAPI; + } + // Fallback for browser dev + return { + getAppVersion: async () => '7.0.4-dev', + getPlatform: () => 'web', + minimizeWindow: () => {}, + maximizeWindow: () => {}, + closeWindow: () => {}, + openExternal: async (url: string) => window.open(url, '_blank'), + startOverlay: async () => {}, + stopOverlay: async () => {}, + } as any; +} diff --git a/src/hooks/useLocalStorage.ts b/src/hooks/useLocalStorage.ts new file mode 100644 index 0000000..102c8e4 --- /dev/null +++ b/src/hooks/useLocalStorage.ts @@ -0,0 +1,15 @@ +import { useState, useCallback } from 'react'; + +export function useLocalStorage(key: string, initial: T): [T, (v: T) => void] { + const [value, setValue] = useState(() => { + try { + const stored = localStorage.getItem(key); + return stored ? JSON.parse(stored) : initial; + } catch { return initial; } + }); + const set = useCallback((v: T) => { + setValue(v); + localStorage.setItem(key, JSON.stringify(v)); + }, [key]); + return [value, set]; +} diff --git a/src/hooks/useVip.ts b/src/hooks/useVip.ts new file mode 100644 index 0000000..fabbc6d --- /dev/null +++ b/src/hooks/useVip.ts @@ -0,0 +1,25 @@ +import { useAuthStore } from '../stores/authStore'; +import { getVipStatus } from '../services/auth.api'; +import { useEffect, useState } from 'react'; + +export function useVip() { + const user = useAuthStore(s => s.user); + const isLoggedIn = useAuthStore(s => s.isLoggedIn); + const [days, setDays] = useState(0); + const [loading, setLoading] = useState(false); + + useEffect(() => { + if (!isLoggedIn || !user?.isVip) return; + setLoading(true); + getVipStatus().then(r => { + if (r.success) setDays(r.data?.daysRemaining || 0); + }).finally(() => setLoading(false)); + }, [isLoggedIn, user?.isVip]); + + return { + isVip: user?.isVip ?? false, + vipLevel: user?.vipLevel ?? 0, + daysRemaining: days, + loading, + }; +} diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..3bbcd57 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; +import '@fontsource-variable/inter'; +import '@fontsource-variable/material-symbols-outlined'; +import './styles/globals.css'; +import './styles/animations.css'; + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + +); diff --git a/src/pages/Crosshair.tsx b/src/pages/Crosshair.tsx new file mode 100644 index 0000000..a069ce1 --- /dev/null +++ b/src/pages/Crosshair.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import Card from '../components/ui/Card'; + +export default function Crosshair() { + return ( +
+
+

游戏准星

+ DEV-01 +
+ +

游戏准星开发中

+
+
+ ); +} diff --git a/src/pages/Exposure.tsx b/src/pages/Exposure.tsx new file mode 100644 index 0000000..1aa816d --- /dev/null +++ b/src/pages/Exposure.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import Panel from '../components/ui/Panel'; +import Card from '../components/ui/Card'; +import Button from '../components/ui/Button'; + +export default function Exposure() { + const navigate = useNavigate(); + + return ( +
+ {/* 标题 */} +
+

画面滤镜

+ PHASE-04 / DSP +
+ + {/* 操作按钮 */} +
+ + +
+ + {/* 已应用滤镜 */} + +
+ blur_on +

暂无已应用的滤镜

+

从滤镜社区下载或导入 ICC 配置文件

+
+
+ + {/* 本地滤镜 */} + +
+ folder +

暂无本地滤镜

+
+
+ + {/* 提示 */} + +

+ [提示] 滤镜使用 ICC 色彩配置文件进行显示校准。需要兼容的显示器和显卡驱动支持。 +

+
+
+ ); +} diff --git a/src/pages/FilterCommunity.tsx b/src/pages/FilterCommunity.tsx new file mode 100644 index 0000000..656b109 --- /dev/null +++ b/src/pages/FilterCommunity.tsx @@ -0,0 +1,98 @@ +import React, { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import FilterGrid from '../components/filters/FilterGrid'; +import type { FilterData } from '../components/filters/FilterCard'; +import Button from '../components/ui/Button'; +import Card from '../components/ui/Card'; +import { useToast } from '../components/ui/Toast'; +import { useAuthStore } from '../stores/authStore'; + +const CATEGORIES = [ + { code: '', name: '全部' }, { code: 'game', name: '游戏' }, { code: 'movie', name: '电影' }, + { code: 'portrait', name: '人像' }, { code: 'landscape', name: '风景' }, + { code: 'custom', name: '自定义' }, { code: 'vibrant', name: '鲜艳' }, +]; + +const PLACEHOLDER_FILTERS: FilterData[] = []; + +export default function FilterCommunity() { + const navigate = useNavigate(); + const toast = useToast(); + const isLoggedIn = useAuthStore(s => s.isLoggedIn); + + const [filters, setFilters] = useState(PLACEHOLDER_FILTERS); + const [loading, setLoading] = useState(false); + const [activeCategory, setActiveCategory] = useState(''); + const [sort, setSort] = useState<'likes' | 'new'>('likes'); + const [likedIds, setLikedIds] = useState>(new Set()); + + useEffect(() => { + setLoading(true); + setTimeout(() => { setLoading(false); }, 800); + }, [activeCategory, sort]); + + const handleLike = async (id: string) => { + if (!isLoggedIn) { toast('warning', '请先登录'); navigate('/login'); return; } + setLikedIds(prev => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n; }); + }; + + const handleDownload = async (_id: string) => { + toast('success', '滤镜已下载'); + }; + + return ( +
+ {/* 标题 */} +
+

滤镜社区

+ NET-01 / 公开 +
+ + {/* 排序切换 */} +
+ + +
+ + {/* 分类标签 */} +
+ {CATEGORIES.map(cat => ( + + ))} +
+ + {/* 列表 */} +
+ +
+ + {/* 提示 */} + +

+ [提示] 社区滤镜由用户创建的 ICC 配置文件。不同显示器效果可能不同,请谨慎使用。 +

+
+
+ ); +} diff --git a/src/pages/ForbiddenForce.tsx b/src/pages/ForbiddenForce.tsx new file mode 100644 index 0000000..707ccb7 --- /dev/null +++ b/src/pages/ForbiddenForce.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import Card from '../components/ui/Card'; + +export default function ForbiddenForce() { + return ( +
+
+

嘉豪之力

+ DEV-02 +
+ +

此功能开发中

+
+
+ ); +} diff --git a/src/pages/HardwareMonitor.tsx b/src/pages/HardwareMonitor.tsx new file mode 100644 index 0000000..b147027 --- /dev/null +++ b/src/pages/HardwareMonitor.tsx @@ -0,0 +1,171 @@ +import React, { useState, useEffect, useRef } from 'react'; +import Card from '../components/ui/Card'; + +interface SensorData { + cpuTemp: number; + cpuUsage: number; + cpuFreq: number; + gpuTemp: number; + gpuUsage: number; + gpuFreq: number; + gpuMem: number; + gpuMemTotal: number; + ramUsage: number; + ramTotal: number; +} + +function randAround(base: number, range: number): number { + return base + (Math.random() - 0.5) * range; +} + +function mockSensorData(): SensorData { + return { + cpuTemp: +randAround(65, 10).toFixed(1), + cpuUsage: +randAround(35, 20).toFixed(1), + cpuFreq: +randAround(3.8, 0.6).toFixed(2), + gpuTemp: +randAround(62, 8).toFixed(1), + gpuUsage: +randAround(40, 25).toFixed(1), + gpuFreq: +randAround(1850, 150).toFixed(0), + gpuMem: +randAround(4.2, 1.2).toFixed(1), + gpuMemTotal: 8, + ramUsage: +randAround(12.8, 2.0).toFixed(1), + ramTotal: 32, + }; +} + +function GaugeArc({ value, max, label, unit, color }: { value: number; max: number; label: string; unit: string; color: string }) { + const pct = Math.min(value / max, 1); + const dash = 150; // circumference of arc + const offset = dash * (1 - pct); + + return ( +
+ + {/* Background arc */} + + {/* Value arc */} + + {/* Center value */} + + {value} + + + {label} ({unit}) +
+ ); +} + +function BarGauge({ value, max, label, unit, color }: { value: number; max: number; label: string; unit: string; color: string }) { + const pct = Math.min(value / max, 1); + return ( +
+
+
+
+ {value}{unit} + {label} +
+ ); +} + +export default function HardwareMonitor() { + const [data, setData] = useState(mockSensorData()); + const intervalRef = useRef>(); + + useEffect(() => { + setData(mockSensorData()); + intervalRef.current = setInterval(() => { + setData(mockSensorData()); + }, 1500); + return () => clearInterval(intervalRef.current); + }, []); + + return ( +
+ {/* Header */} +
+

硬件监控

+
+ + 实时 +
+
+ + {/* CPU */} + +
+
+ memory +

CPU

+ Intel Core i9-13900K +
+ +
+ + + +
+
+
+ + {/* GPU */} + +
+
+ videocam +

GPU

+ NVIDIA RTX 4090 +
+ +
+ + + +
+ +
+ +
+
+
+ + {/* RAM */} + +
+
+ storage +

内存

+ DDR5 32GB +
+ +

{data.ramUsage} / {data.ramTotal} GB

+
+
+ + {/* Status footer */} + +

+ [INFO] 数据模拟中。对接 MaqiangTangHardwareMonitor.exe 后显示真实传感器数据。 +

+
+
+ ); +} diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx new file mode 100644 index 0000000..c95288a --- /dev/null +++ b/src/pages/Home.tsx @@ -0,0 +1,104 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import DesktopGrid from '../components/layout/DesktopGrid'; +import Card from '../components/ui/Card'; +import { useAuthStore } from '../stores/authStore'; + +export default function Home() { + const navigate = useNavigate(); + const user = useAuthStore(s => s.user); + const isLoggedIn = !!user; + const isVip = isLoggedIn; // TODO: proper VIP check + + // 模块定义:名称/权限对齐原版 + const desktopItems = [ + { id: 'optimization', icon: 'tune', label: '快速优化', action: () => navigate('/optimization'), vip: true }, + { id: 'exposure', icon: 'palette', label: '画面滤镜', action: () => navigate('/exposure'), vip: true }, + { id: 'filter-community', icon: 'photo_camera', label: '滤镜社区', action: () => navigate('/filter-community'), vip: true }, + { id: 'hardware-monitor', icon: 'monitor_heart', label: '硬件监控', action: () => navigate('/hardware-monitor') }, + { id: 'weapon', icon: 'crosshair', label: '改枪方案', action: () => navigate('/weapon'), loginRequired: true }, + { id: 'crosshair', icon: 'gps_fixed', label: '游戏准星', action: () => navigate('/crosshair'), loginRequired: true }, + { id: 'xixi-haha', icon: 'sentiment_satisfied', label: '神秘力量', action: () => navigate('/xixi-haha'), loginRequired: true }, + { id: 'forbidden-force', icon: 'block', label: '嘉豪之力', action: () => navigate('/forbidden-force'), vip: true }, + ]; + + const handleAction = (item: typeof desktopItems[0]) => { + if (item.vip && !isVip) { navigate('/login'); return; } + if (item.loginRequired && !isLoggedIn) { navigate('/login'); return; } + item.action(); + }; + + return ( +
+ {/* 状态条 */} + +
+ + + {user ? `用户: ${user.username}` : '未登录'} + +
+ +
+ + {/* 功能网格 */} +
+ 功能模块 v2 + ({ + ...item, + action: () => handleAction(item), + locked: (item.vip && !isVip) || (item.loginRequired && !isLoggedIn), + }))} + rows={2} + cols={4} + /> +
+ + {/* 社区动态 */} + +
+

最新动态

+ 实时 +
+
+ {[1, 2, 3].map(i => ( +
+ + [{String(i).padStart(4, '0')}] + 社区动态 #{i} +
+ ))} +
+
+ + {/* 底部启动按钮 */} +
+ + +
+ + {/* 底部技术信息 */} +
+ 系统: {typeof navigator !== 'undefined' && navigator.platform ? navigator.platform.substring(0, 8) : 'UNKNOWN'} + 节点: MBKPro-01 + 运行: -- +
+
+ ); +} diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx new file mode 100644 index 0000000..5fad043 --- /dev/null +++ b/src/pages/Login.tsx @@ -0,0 +1,140 @@ +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import Button from '../components/ui/Button'; +import Input from '../components/ui/Input'; +import Card from '../components/ui/Card'; +import { useAuth } from '../hooks/useAuth'; +import { useAuthStore } from '../stores/authStore'; +import { getVipStatus, activateVip } from '../services/auth.api'; + +export default function Login() { + const navigate = useNavigate(); + const { login } = useAuth(); + const isLoggedIn = useAuthStore(s => s.isLoggedIn); + + const [tab, setTab] = useState<'login' | 'register' | 'vip'>('login'); + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const [email, setEmail] = useState(''); + const [cardKey, setCardKey] = useState(''); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + + const handleLogin = async () => { + setLoading(true); setError(''); + try { + await login({ + username, password, + installId: 'maqt-desktop', + deviceHash: 'maqt-desktop', + platform: navigator.platform || 'win32', + osVersion: navigator.userAgent || '', + appVersion: '7.0.4', + }); + navigate('/'); + } catch (e: any) { + setError(e.message || '登录失败'); + } finally { setLoading(false); } + }; + + const handleActivateVip = async () => { + setLoading(true); setError(''); + try { + await activateVip(cardKey); + const status = await getVipStatus(); + if (status) navigate('/'); + } catch (e: any) { + setError(e.message || '激活失败'); + } finally { setLoading(false); } + }; + + return ( +
+ {/* 品牌 */} +
+

码枪堂 2.0

+

用户认证系统

+
+ + {/* 认证卡片 */} + + {/* 标签页 */} +
+ {(['login', 'register', 'vip'] as const).map(t => ( + + ))} +
+ + {/* 表单 */} +
+ {tab === 'vip' ? ( + <> + setCardKey(e.target.value)} + style={{ borderRadius: 0, borderColor: '#333', background: '#111', color: '#e0e0e0', fontSize: 10 }} + /> + + + ) : ( + <> + setUsername(e.target.value)} + style={{ borderRadius: 0, borderColor: '#333', background: '#111', color: '#e0e0e0', fontSize: 10 }} + /> + setPassword(e.target.value)} + style={{ borderRadius: 0, borderColor: '#333', background: '#111', color: '#e0e0e0', fontSize: 10 }} + /> + {tab === 'register' && ( + setEmail(e.target.value)} + style={{ borderRadius: 0, borderColor: '#333', background: '#111', color: '#e0e0e0', fontSize: 10 }} + /> + )} + + + )} + + {error && ( +

+ ✕ {error} +

+ )} + +

+ SYS-AUTH v1.0 +

+
+
+ + {/* 返回 */} + +
+ ); +} diff --git a/src/pages/Optimization.tsx b/src/pages/Optimization.tsx new file mode 100644 index 0000000..6e0e8e5 --- /dev/null +++ b/src/pages/Optimization.tsx @@ -0,0 +1,114 @@ +import React, { useState } from 'react'; +import OptimizePanel from '../components/optimization/OptimizePanel'; +import OptimizeResult from '../components/optimization/OptimizeResult'; +import Button from '../components/ui/Button'; +import Card from '../components/ui/Card'; +import { useToast } from '../components/ui/Toast'; +import { useAuthStore } from '../stores/authStore'; +import type { OptimizeItemData } from '../components/optimization/OptimizeItem'; + +const INITIAL_ITEMS: OptimizeItemData[] = [ + { id: 'power-plan', label: '卓越性能电源', description: '启用 Windows 卓越性能电源计划,释放 CPU/GPU 全部性能', category: 'system', icon: 'bolt', status: 'pending' }, + { id: 'gpu-sched', label: 'GPU 硬件加速', description: '启用硬件加速 GPU 调度,降低游戏输入延迟', category: 'system', icon: 'speed', status: 'pending' }, + { id: 'game-mode', label: '游戏模式', description: '启用 Windows 游戏模式,优化游戏资源分配', category: 'system', icon: 'sports_esports', status: 'pending' }, + { id: 'hyperv', label: '关闭 Hyper-V', description: '关闭 Hyper-V 虚拟机服务,释放系统资源', category: 'services', icon: 'memory', status: 'pending' }, + { id: 'services', label: '系统服务优化', description: '关闭非必要的 Windows 后台服务,减少资源占用', category: 'services', icon: 'build', status: 'pending' }, + { id: 'hpet', label: 'HPET 高性能', description: '切换 HPET 为高性能模式,提升计时精度', category: 'services', icon: 'timer', status: 'pending' }, + { id: 'network', label: '网络延迟优化', description: '优化 TCP/IP 参数,降低网络延迟', category: 'network', icon: 'wifi', status: 'pending' }, + { id: 'dns', label: 'DNS 缓存重置', description: '重置 DNS 解析缓存,优化域名解析速度', category: 'network', icon: 'dns', status: 'pending' }, + { id: 'mouse', label: '关闭鼠标加速', description: '关闭鼠标加速度,提升瞄准操控精准度', category: 'display', icon: 'mouse', status: 'pending' }, + { id: 'visual', label: '关闭视觉特效', description: '关闭窗口动画和透明效果,提升帧率', category: 'display', icon: 'visibility_off', status: 'pending' }, + { id: 'memory', label: '内存清理', description: '清理非必要内存占用,释放可用内存', category: 'memory', icon: 'clear_all', status: 'pending' }, +]; + +export default function Optimization() { + const isLoggedIn = useAuthStore(s => s.isLoggedIn); + const toast = useToast(); + + const [items, setItems] = useState(INITIAL_ITEMS); + const [result, setResult] = useState<{ success: boolean; message: string } | null>(null); + const [running, setRunning] = useState(false); + + const handleToggle = async (id: string, action: 'optimize' | 'restore') => { + if (!isLoggedIn) { toast('warning', '请先登录'); return; } + setRunning(true); + await new Promise(r => setTimeout(r, 1000)); + const success = Math.random() > 0.1; + setItems(prev => prev.map(i => + i.id === id + ? { ...i, status: success ? (action === 'optimize' ? 'optimized' as const : 'restored' as const) : 'error' as const } + : i + )); + toast(success ? 'success' : 'error', `${id} ${action === 'optimize' ? '优化' : '恢复'}${success ? '成功' : '失败'}`); + setRunning(false); + }; + + const handleOneClick = async () => { + if (!isLoggedIn) { toast('warning', '请先登录'); return; } + setRunning(true); + const pending = items.filter(i => i.status !== 'optimized'); + setItems(INITIAL_ITEMS); + + for (const item of pending) { + await new Promise(r => setTimeout(r, 500)); + setItems(prev => prev.map(i => i.id === item.id ? { ...i, status: 'optimized' as const } : i)); + } + setResult({ success: true, message: `已完成 ${pending.length} 项优化` }); + setRunning(false); + }; + + const systemItems = items.filter(i => i.category === 'system'); + const serviceItems = items.filter(i => i.category === 'services'); + const networkItems = items.filter(i => i.category === 'network'); + const displayItems = items.filter(i => i.category === 'display'); + const memoryItems = items.filter(i => i.category === 'memory'); + + return ( +
+ {/* 标题 */} +
+

快速优化

+ PHASE-05 +
+ + {/* 操作按钮 */} +
+ + +
+ + {/* 结果 */} + {result && ( + setResult(null)} + /> + )} + + {/* 优化面板 */} + + + + + + + {/* 提示 */} + +

+ [提示] 快速优化需要管理员权限。部分优化项重启后生效。 +

+
+
+ ); +} diff --git a/src/pages/SchemeDetail.tsx b/src/pages/SchemeDetail.tsx new file mode 100644 index 0000000..0184225 --- /dev/null +++ b/src/pages/SchemeDetail.tsx @@ -0,0 +1,114 @@ +import React, { useEffect, useState } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import Card from '../components/ui/Card'; +import Button from '../components/ui/Button'; +import { getSchemeById, useScheme } from '../services/schemes.api'; +import { addFavorite, removeFavorite } from '../services/favorites.api'; +import { useAuthStore } from '../stores/authStore'; +import { useToast } from '../components/ui/Toast'; +import type { SchemeData } from '../components/schemes/SchemeCard'; + +export default function SchemeDetail() { + const { id } = useParams<{ id: string }>(); + const navigate = useNavigate(); + const toast = useToast(); + const isLoggedIn = useAuthStore(s => s.isLoggedIn); + + const [scheme, setScheme] = useState(null); + const [loading, setLoading] = useState(true); + const [isFavorited, setIsFavorited] = useState(false); + + useEffect(() => { + if (!id) return; + setLoading(true); + getSchemeById(id).then(r => { + if (r.success && r.data) setScheme(r.data as SchemeData); + }).catch(() => {}).finally(() => setLoading(false)); + }, [id]); + + const handleUse = async () => { + if (!isLoggedIn) { toast('warning', '请先登录'); navigate('/login'); return; } + if (!scheme) return; + try { + await useScheme(scheme.id, scheme.category || 'AR'); + toast('success', '方案使用记录已保存'); + } catch { toast('error', '操作失败'); } + }; + + const handleFavorite = async () => { + if (!isLoggedIn) { toast('warning', '请先登录'); navigate('/login'); return; } + if (!scheme) return; + try { + if (isFavorited) { + await removeFavorite(scheme.id); + setIsFavorited(false); + toast('success', '已取消收藏'); + } else { + await addFavorite({ targetId: scheme.id, targetType: 'Scheme' }); + setIsFavorited(true); + toast('success', '已收藏'); + } + } catch { toast('error', '操作失败'); } + }; + + if (loading) { + return ( +
+
+

方案详情

+ LOADING... +
+
+
+ ); + } + + if (!scheme) { + return ( +
+
+

方案详情

+ 404 +
+ +

方案未找到或已删除

+
+
+ ); + } + + return ( +
+
+
+ +

方案详情

+
+ {scheme.isOfficial && 官方} +
+ + +
+

{scheme.title || '未命名方案'}

+ {scheme.weaponName &&

武器: {scheme.weaponName}

} + {scheme.user?.username &&

作者: {scheme.user.username}

} + {scheme.price > 0 &&

价格: {scheme.price}

} + +
+ 👁 浏览 {scheme.viewsCount} + ⬇ 下载 {scheme.downloadsCount} + 👍 点赞 {scheme.likesCount} + ★ 收藏 {scheme.favoritesCount} +
+
+
+ +
+ + +
+
+ ); +} diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx new file mode 100644 index 0000000..3be31f3 --- /dev/null +++ b/src/pages/Settings.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import Card from '../components/ui/Card'; + +export default function Settings() { + return ( +
+
+

设置

+ CFG-01 +
+ + +
+

账户

+
+

用户状态: 未登录

+

VIP: 未激活

+

设备ID: maqt-desktop-01

+
+
+
+ + +
+

应用

+
+

版本: 0.2.1

+

API: 待配置

+

代理: 无

+
+
+
+ + +

更多设置项开发中

+
+
+ ); +} diff --git a/src/pages/WeaponSchemes.tsx b/src/pages/WeaponSchemes.tsx new file mode 100644 index 0000000..2cc8821 --- /dev/null +++ b/src/pages/WeaponSchemes.tsx @@ -0,0 +1,115 @@ +import React, { useEffect, useState, useCallback } from 'react'; +import CategoryTabs from '../components/schemes/CategoryTabs'; +import SchemeList from '../components/schemes/SchemeList'; +import type { SchemeData } from '../components/schemes/SchemeCard'; +import { getSchemes, getCategory, useScheme } from '../services/schemes.api'; +import { addFavorite, removeFavorite, checkFavorite } from '../services/favorites.api'; +import { useAuthStore } from '../stores/authStore'; +import { useNavigate } from 'react-router-dom'; +import { useToast } from '../components/ui/Toast'; + +const DEFAULT_CATEGORIES = [ + { code: 'AR', name: '突击步枪' }, { code: 'SMG', name: '冲锋枪' }, + { code: 'SR', name: '狙击枪' }, { code: 'LMG', name: '轻机枪' }, + { code: 'SG', name: '霰弹枪' }, { code: 'Pistol', name: '手枪' }, + { code: 'Launcher', name: '发射器' }, +]; + +export default function WeaponSchemes() { + const navigate = useNavigate(); + const toast = useToast(); + const isLoggedIn = useAuthStore(s => s.isLoggedIn); + + const [categories, setCategories] = useState>(DEFAULT_CATEGORIES); + const [activeCode, setActiveCode] = useState('AR'); + const [schemes, setSchemes] = useState([]); + const [loading, setLoading] = useState(false); + const [page, setPage] = useState(1); + const [totalPages, setTotalPages] = useState(1); + const [favoritedIds, setFavoritedIds] = useState>(new Set()); + const [sort, setSort] = useState<'hot' | 'new'>('hot'); + + useEffect(() => { + getCategory('AR').then(r => { + if (r.success && Array.isArray(r.data) && r.data.length > 0) { + setCategories(r.data); + } + }).catch(() => {}); + }, []); + + const loadSchemes = useCallback(async (code: string, p: number, s: string) => { + setLoading(true); + try { + const res = await getSchemes({ sort: s, page: p, limit: 12, source: code, weaponCategory: code }); + if (res.success && Array.isArray(res.data)) { + setSchemes(res.data || []); + setTotalPages(Math.ceil((res as any).total || res.data.length / 12)); + } else { setSchemes([]); } + } catch { setSchemes([]); } + finally { setLoading(false); } + }, []); + + useEffect(() => { loadSchemes(activeCode, page, sort); }, [activeCode, page, sort, loadSchemes]); + + const handleCategoryChange = (code: string) => { setActiveCode(code); setPage(1); }; + + const handleFavorite = async (id: string) => { + if (!isLoggedIn) { toast('warning', '请先登录'); navigate('/login'); return; } + try { + if (favoritedIds.has(id)) { + await removeFavorite(id); + setFavoritedIds(prev => { const n = new Set(prev); n.delete(id); return n; }); + toast('success', '已取消收藏'); + } else { + await addFavorite({ targetId: id, targetType: 'Scheme' }); + setFavoritedIds(prev => new Set(prev).add(id)); + toast('success', '已收藏'); + } + } catch { toast('error', '操作失败'); } + }; + + const handleUse = async (id: string) => { + if (!isLoggedIn) { toast('warning', '请先登录'); navigate('/login'); return; } + try { + await useScheme(id, activeCode); + toast('success', '方案使用记录已保存'); + } catch { toast('error', '操作失败'); } + }; + + return ( +
+ {/* 标题 */} +
+

改枪方案

+
+ {(['hot', 'new'] as const).map(s => ( + + ))} +
+
+ + {/* 分类标签 */} + + + {/* 方案列表 */} + navigate(`/scheme-detail/${id}`)} + /> +
+ ); +} diff --git a/src/pages/XixiHaha.tsx b/src/pages/XixiHaha.tsx new file mode 100644 index 0000000..334a146 --- /dev/null +++ b/src/pages/XixiHaha.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import Card from '../components/ui/Card'; + +export default function XixiHaha() { + return ( +
+
+

神秘力量

+ DEV-03 +
+ +

此功能开发中

+
+
+ ); +} diff --git a/src/router.tsx b/src/router.tsx new file mode 100644 index 0000000..6a61fc9 --- /dev/null +++ b/src/router.tsx @@ -0,0 +1,80 @@ +import React, { Suspense, lazy } from 'react'; +import { Routes, Route } from 'react-router-dom'; +import PageContainer from './components/layout/PageContainer'; +import TopHud from './components/layout/TopHud'; + +const Home = lazy(() => import('./pages/Home')); +const Optimization = lazy(() => import('./pages/Optimization')); +const Exposure = lazy(() => import('./pages/Exposure')); +const FilterCommunity = lazy(() => import('./pages/FilterCommunity')); +const WeaponSchemes = lazy(() => import('./pages/WeaponSchemes')); +const SchemeDetail = lazy(() => import('./pages/SchemeDetail')); +const Crosshair = lazy(() => import('./pages/Crosshair')); +const ForbiddenForce = lazy(() => import('./pages/ForbiddenForce')); +const XixiHaha = lazy(() => import('./pages/XixiHaha')); +const HardwareMonitor = lazy(() => import('./pages/HardwareMonitor')); +const Settings = lazy(() => import('./pages/Settings')); +const Login = lazy(() => import('./pages/Login')); + +const pageTitles: Record = { + home: '桌面', + optimization: '快速优化', + exposure: '画面滤镜', + 'filter-community': '滤镜社区', + weapon: '改枪方案', + crosshair: '游戏准星', + 'forbidden-force': '嘉豪之力', + 'xixi-haha': '神秘力量', + 'hardware-monitor': '硬件监控', + settings: '设置', +}; + +function PageShell({ children, currentPage }: { children: React.ReactNode; currentPage: string }) { + return ( +
+ + + }> + {children} + + +
+ ); +} + +function LoadingFallback() { + return ( +
+
+ + 加载中... +
+
+ ); +} + +export default function AppRouter() { + return ( + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + ); +} diff --git a/src/services/api.ts b/src/services/api.ts new file mode 100644 index 0000000..4456bde --- /dev/null +++ b/src/services/api.ts @@ -0,0 +1,30 @@ +import axios from 'axios'; + +const API_BASE = 'https://gch3n.online/delta'; + +const api = axios.create({ + baseURL: API_BASE, + timeout: 15000, + headers: { 'Content-Type': 'application/json' }, +}); + +api.interceptors.request.use((config) => { + if (typeof window !== 'undefined') { + const token = localStorage.getItem('auth_token'); + if (token) config.headers.Authorization = `Bearer ${token}`; + } + return config; +}); + +api.interceptors.response.use( + (res) => res, + (err) => { + if (err.response?.status === 401 && typeof window !== 'undefined') { + localStorage.removeItem('auth_token'); + localStorage.removeItem('auth_user'); + } + return Promise.reject(err); + } +); + +export default api; diff --git a/src/services/auth.api.ts b/src/services/auth.api.ts new file mode 100644 index 0000000..aa5c43d --- /dev/null +++ b/src/services/auth.api.ts @@ -0,0 +1,37 @@ +import api from './api'; +import type { LoginRequest, LoginResponse, User, ApiResponse } from '../types'; + +export async function login(data: LoginRequest): Promise { + const res = await api.post('/api/login', data); + return res.data; +} + +export async function register(username: string, password: string, email: string): Promise { + const res = await api.post('/api/register', { username, password, email }); + return res.data; +} + +export async function getSessionStatus(): Promise> { + const res = await api.get('/api/session-status'); + return res.data; +} + +export async function getVipStatus(): Promise> { + const res = await api.get('/api/vip-status'); + return res.data; +} + +export async function activateVip(cardKey: string): Promise { + const res = await api.post('/api/activate-vip', { cardKey }); + return res.data; +} + +export async function getUserStats(userId: string): Promise { + const res = await api.get(`/api/user/stats/${userId}`); + return res.data; +} + +export async function getUserLimits(userId: string): Promise { + const res = await api.get(`/api/user/limits/${userId}`); + return res.data; +} diff --git a/src/services/favorites.api.ts b/src/services/favorites.api.ts new file mode 100644 index 0000000..4c03910 --- /dev/null +++ b/src/services/favorites.api.ts @@ -0,0 +1,26 @@ +import api from './api'; + +export async function getFavorites() { + const res = await api.get('/api/favorites'); + return res.data; +} + +export async function getFavoritesCount() { + const res = await api.get('/api/favorites/count'); + return res.data; +} + +export async function checkFavorite(schemeId: string, source?: string) { + const res = await api.get('/api/favorites/check', { params: { schemeId, source } }); + return res.data; +} + +export async function addFavorite(data: { targetId: string; targetType: string }) { + const res = await api.post('/api/favorites', data); + return res.data; +} + +export async function removeFavorite(id: string) { + const res = await api.delete(`/api/favorites/${id}`); + return res.data; +} diff --git a/src/services/schemes.api.ts b/src/services/schemes.api.ts new file mode 100644 index 0000000..751f0a0 --- /dev/null +++ b/src/services/schemes.api.ts @@ -0,0 +1,36 @@ +import api from './api'; +import type { Scheme, ApiResponse, Category } from '../types'; + +interface SchemesParams { + sort?: string; + page?: number; + limit?: number; + source?: string; + weaponCategory?: string; + weaponName?: string; +} + +export async function getSchemes(params?: SchemesParams): Promise> { + const res = await api.get('/api/schemes', { params }); + return res.data; +} + +export async function getSchemeById(id: string): Promise> { + const res = await api.get(`/api/schemes/${id}`); + return res.data; +} + +export async function getCategory(code: string): Promise> { + const res = await api.get(`/api/category/${code}`); + return res.data; +} + +export async function useScheme(id: string, source?: string): Promise> { + const res = await api.post(`/api/schemes/${id}/use`, { source }); + return res.data; +} + +export async function getUserSchemes(userId: string): Promise> { + const res = await api.get(`/api/user/schemes/${userId}`); + return res.data; +} diff --git a/src/stores/authStore.ts b/src/stores/authStore.ts new file mode 100644 index 0000000..51f83a6 --- /dev/null +++ b/src/stores/authStore.ts @@ -0,0 +1,70 @@ +import { create } from 'zustand'; +import api from '../services/api'; +import type { User } from '../types'; + +interface AuthState { + token: string | null; + user: User | null; + isLoggedIn: boolean; + loading: boolean; + login: (token: string, user: User) => void; + logout: () => void; + checkSession: () => Promise; + setUser: (user: User) => void; + hydrate: () => void; +} + +export const useAuthStore = create((set, get) => ({ + token: null, + user: null, + isLoggedIn: false, + loading: false, + + hydrate: () => { + const token = localStorage.getItem('auth_token'); + const userStr = localStorage.getItem('auth_user'); + if (token && userStr) { + try { + const user = JSON.parse(userStr); + set({ token, user, isLoggedIn: true }); + } catch { set({ token: null, user: null, isLoggedIn: false }); } + } + }, + + login: (token, user) => { + localStorage.setItem('auth_token', token); + localStorage.setItem('auth_user', JSON.stringify(user)); + set({ token, user, isLoggedIn: true }); + }, + + logout: () => { + localStorage.removeItem('auth_token'); + localStorage.removeItem('auth_user'); + set({ token: null, user: null, isLoggedIn: false }); + }, + + checkSession: async () => { + const { token } = get(); + if (!token) { set({ isLoggedIn: false }); return false; } + set({ loading: true }); + try { + const res = await api.get('/api/session-status'); + if (res.data.success && res.data.user) { + set({ user: res.data.user, isLoggedIn: true, loading: false }); + return true; + } + get().logout(); + set({ loading: false }); + return false; + } catch { + get().logout(); + set({ loading: false }); + return false; + } + }, + + setUser: (user) => { + localStorage.setItem('auth_user', JSON.stringify(user)); + set({ user }); + }, +})); diff --git a/src/stores/navigationStore.ts b/src/stores/navigationStore.ts new file mode 100644 index 0000000..1725006 --- /dev/null +++ b/src/stores/navigationStore.ts @@ -0,0 +1,13 @@ +import { create } from 'zustand'; + +interface NavState { + currentPage: string; + navigate: (page: string) => void; + goBack: () => void; +} + +export const useNavigationStore = create((set) => ({ + currentPage: 'home', + navigate: (page) => set({ currentPage: page }), + goBack: () => set({ currentPage: 'home' }), +})); diff --git a/src/stores/settingsStore.ts b/src/stores/settingsStore.ts new file mode 100644 index 0000000..31694e4 --- /dev/null +++ b/src/stores/settingsStore.ts @@ -0,0 +1,24 @@ +import { create } from 'zustand'; + +interface SettingsState { + autoLaunch: boolean; + closePreference: 'ask' | 'tray' | 'quit'; + setAutoLaunch: (v: boolean) => void; + setClosePreference: (v: 'ask' | 'tray' | 'quit') => void; + hydrate: () => void; +} + +export const useSettingsStore = create((set) => ({ + autoLaunch: false, + closePreference: 'ask', + setAutoLaunch: (v) => { localStorage.setItem('settings_autoLaunch', String(v)); set({ autoLaunch: v }); }, + setClosePreference: (v) => { localStorage.setItem('settings_closePref', v); set({ closePreference: v }); }, + hydrate: () => { + const a = localStorage.getItem('settings_autoLaunch'); + const c = localStorage.getItem('settings_closePref'); + set({ + autoLaunch: a === 'true', + closePreference: (c as any) || 'ask', + }); + }, +})); diff --git a/src/styles/animations.css b/src/styles/animations.css new file mode 100644 index 0000000..05da6c8 --- /dev/null +++ b/src/styles/animations.css @@ -0,0 +1,252 @@ +/* ===== 扫描线效果 ===== */ +@keyframes scanline { + 0% { + transform: translateY(-100%); + } + 100% { + transform: translateY(100%); + } +} + +.animate-scanline { + position: relative; + overflow: hidden; +} + +.animate-scanline::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 100%; + background: linear-gradient( + to bottom, + transparent 0%, + rgba(42, 157, 111, 0.1) 50%, + transparent 100% + ); + animation: scanline 3s linear infinite; + pointer-events: none; +} + +/* ===== 十字准星展开动画 ===== */ +@keyframes crosshair-expand { + 0% { + transform: scale(0) rotate(45deg); + opacity: 0; + } + 50% { + opacity: 1; + } + 100% { + transform: scale(1) rotate(0deg); + opacity: 1; + } +} + +.animate-crosshair { + animation: crosshair-expand 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; +} + +/* 十字准星线条 */ +.crosshair-line { + position: absolute; + background: var(--military-400); +} + +.crosshair-line.horizontal { + width: 20px; + height: 2px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.crosshair-line.vertical { + width: 2px; + height: 20px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +/* ===== 数字滚动动画 ===== */ +@keyframes digit-scroll { + 0% { + transform: translateY(100%); + opacity: 0; + } + 20% { + opacity: 1; + } + 80% { + opacity: 1; + } + 100% { + transform: translateY(-100%); + opacity: 0; + } +} + +.animate-digit { + display: inline-block; + animation: digit-scroll 0.3s ease-out forwards; +} + +/* 数字递增效果 */ +@keyframes count-up { + from { + --num: 0; + } + to { + --num: var(--target); + } +} + +.animate-count-up { + animation: count-up 0.5s ease-out forwards; + counter-reset: num var(--num); +} + +.animate-count-up::after { + content: counter(num); +} + +/* ===== 边框流光效果 ===== */ +@keyframes border-flow { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +.animate-border-flow { + position: relative; + background: linear-gradient( + 90deg, + var(--charcoal-800), + var(--military-600), + var(--darkgold-500), + var(--military-600), + var(--charcoal-800) + ); + background-size: 300% 100%; + animation: border-flow 3s ease infinite; +} + +/* 流光边框容器 */ +.border-flow-container { + position: relative; +} + +.border-flow-container::before { + content: ''; + position: absolute; + inset: 0; + padding: 1px; + border-radius: inherit; + background: linear-gradient( + 90deg, + var(--military-600), + var(--darkgold-500), + var(--military-600) + ); + background-size: 200% 100%; + animation: border-flow 2s linear infinite; + -webkit-mask: + linear-gradient(#fff 0 0) content-box, + linear-gradient(#fff 0 0); + mask: + linear-gradient(#fff 0 0) content-box, + linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + pointer-events: none; +} + +/* ===== 脉冲效果 ===== */ +@keyframes pulse-glow { + 0%, 100% { + box-shadow: 0 0 5px var(--military-500), 0 0 10px var(--military-500); + } + 50% { + box-shadow: 0 0 15px var(--military-400), 0 0 25px var(--military-400); + } +} + +.animate-pulse-glow { + animation: pulse-glow 2s ease-in-out infinite; +} + +/* ===== 闪烁效果 ===== */ +@keyframes blink { + 0%, 50% { + opacity: 1; + } + 51%, 100% { + opacity: 0; + } +} + +.animate-blink { + animation: blink 1s step-end infinite; +} + +/* ===== 渐变扫描 ===== */ +@keyframes gradient-shift { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +.animate-gradient { + background-size: 200% 200%; + animation: gradient-shift 5s ease infinite; +} + +/* ===== 悬浮动画 ===== */ +@keyframes float { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-5px); + } +} + +.animate-float { + animation: float 3s ease-in-out infinite; +} + +/* ===== 数据流动效果 ===== */ +@keyframes data-flow { + 0% { + background-position: -200% 0; + } + 100% { + background-position: 200% 0; + } +} + +.animate-data-flow { + background: linear-gradient( + 90deg, + transparent, + rgba(42, 157, 111, 0.3), + transparent + ); + background-size: 50% 100%; + animation: data-flow 2s linear infinite; +} diff --git a/src/styles/globals.css b/src/styles/globals.css new file mode 100644 index 0000000..bc1f4ec --- /dev/null +++ b/src/styles/globals.css @@ -0,0 +1,117 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + * { + scrollbar-width: none; + -webkit-font-smoothing: antialiased; + } + + body { + font-family: 'Inter', 'Helvetica', sans-serif; + background: #1a1a1a; + color: #e0e0e0; + overflow: hidden; + font-size: 12px; + line-height: 1.5; + } + + h1, h2, h3, h4, h5, h6 { + text-transform: uppercase; + letter-spacing: 0.08em; + } +} + +@layer components { + .material-symbols-outlined { + font-family: 'Material Symbols Outlined'; + font-weight: 300; + font-style: normal; + font-size: 20px; + line-height: 1; + letter-spacing: normal; + text-transform: none; + display: inline-block; + white-space: nowrap; + word-wrap: normal; + direction: ltr; + -webkit-font-smoothing: antialiased; + font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 20; + } + + /* Tech label annotation — tiny all-caps text for corners/edges */ + .tech-tag { + @apply text-[9px] tracking-[0.15em] uppercase font-mono; + color: #555; + } + + /* Crosshair decoration */ + .crosshair { + position: relative; + } + .crosshair::before, + .crosshair::after { + content: ''; + position: absolute; + background: #ff4500; + opacity: 0.3; + } + .crosshair::before { + width: 1px; + height: 8px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + .crosshair::after { + width: 8px; + height: 1px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + + /* Cut corner decoration (top-left) */ + .cut-corner-tl { + position: relative; + } + .cut-corner-tl::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 8px; + height: 8px; + border-top: 1px solid #ff4500; + border-left: 1px solid #ff4500; + opacity: 0.4; + pointer-events: none; + } + + /* Cut corner decoration (bottom-right) */ + .cut-corner-br { + position: relative; + } + .cut-corner-br::after { + content: ''; + position: absolute; + bottom: 0; + right: 0; + width: 8px; + height: 8px; + border-bottom: 1px solid #ff4500; + border-right: 1px solid #ff4500; + opacity: 0.4; + pointer-events: none; + } + + /* Tech serial label */ + .tech-sn { + font-family: 'JetBrains Mono', monospace; + font-size: 8px; + letter-spacing: 0.1em; + color: #444; + text-transform: uppercase; + } +} diff --git a/src/types/electron.d.ts b/src/types/electron.d.ts new file mode 100644 index 0000000..2a428b8 --- /dev/null +++ b/src/types/electron.d.ts @@ -0,0 +1,36 @@ +export interface ElectronAPI { + // 通用 + getAppVersion: () => Promise; + getPlatform: () => string; + + // Overlay + startOverlay: (options: any) => Promise; + stopOverlay: () => Promise; + + // 硬件监控 + startMonitor: () => Promise; + stopMonitor: () => Promise; + + // 文件/路径 + openExternal: (url: string) => Promise; + getResourcesPath: () => Promise; + existsSync: (path: string) => Promise; + + // 系统优化 + optimizeItem: (id: string) => Promise; + restoreItem: (id: string) => Promise; + getOptimizeItems: () => Promise; + + // 窗口控制 + minimizeWindow: () => Promise; + maximizeWindow: () => Promise; + closeWindow: () => Promise; +} + +declare global { + interface Window { + electronAPI: ElectronAPI; + } +} + +export {}; diff --git a/src/types/global.d.ts b/src/types/global.d.ts new file mode 100644 index 0000000..2b20215 --- /dev/null +++ b/src/types/global.d.ts @@ -0,0 +1,101 @@ +/// + +// 全局类型声明 + +declare namespace AppTypes { + // 用户信息 + interface User { + id: string; + username: string; + email: string; + avatar?: string; + createdAt: string; + } + + // 硬件信息 + interface HardwareInfo { + cpu: CPUInfo; + gpu: GPUInfo; + memory: MemoryInfo; + storage: StorageInfo[]; + motherboard: MotherboardInfo; + } + + interface CPUInfo { + name: string; + cores: number; + threads: number; + baseFrequency: number; + maxFrequency: number; + temperature: number; + usage: number; + } + + interface GPUInfo { + name: string; + vram: number; + temperature: number; + usage: number; + clockSpeed: number; + } + + interface MemoryInfo { + total: number; + used: number; + free: number; + speed: number; + } + + interface StorageInfo { + name: string; + type: 'SSD' | 'HDD' | 'NVMe'; + total: number; + used: number; + health: number; + } + + interface MotherboardInfo { + manufacturer: string; + model: string; + biosVersion: string; + } + + // 优化项 + interface OptimizeItem { + id: string; + name: string; + description: string; + category: 'system' | 'network' | 'gaming' | 'privacy'; + status: 'idle' | 'optimizing' | 'optimized' | 'failed'; + impact: 'low' | 'medium' | 'high'; + } + + // 配置方案 + interface Scheme { + id: string; + name: string; + description: string; + game: string; + filters: FilterConfig[]; + createdAt: string; + updatedAt: string; + } + + interface FilterConfig { + id: string; + name: string; + enabled: boolean; + settings: Record; + } +} + +// CSS Modules +declare module '*.module.css' { + const classes: { [key: string]: string }; + export default classes; +} + +declare module '*.module.scss' { + const classes: { [key: string]: string }; + export default classes; +} diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..ef87e93 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,56 @@ +export interface User { + id: string; + username: string; + email: string; + avatar: string | null; + isVip: boolean; + vipExpireAt: string | null; + vipLevel: number; +} + +export interface Scheme { + id: string; + title: string | null; + weaponName: string | null; + category: string | null; + userId: string; + description: string | null; + viewsCount: number; + downloadsCount: number; + likesCount: number; + favoritesCount: number; + price: number; + status: string; + isOfficial: boolean; + createdAt: string; + user?: { username: string; avatar: string | null }; +} + +export interface Category { + code: string; + name: string; + icon: string; +} + +export interface LoginRequest { + username: string; + password: string; + installId?: string; + deviceHash?: string; + platform?: string; + osVersion?: string; + appVersion?: string; +} + +export interface LoginResponse { + success: boolean; + token?: string; + user?: User; + message?: string; +} + +export interface ApiResponse { + success: boolean; + data?: T; + message?: string; +} diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..0d8981d --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,40 @@ +import type { Config } from 'tailwindcss'; + +const config: Config = { + content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], + theme: { + extend: { + colors: { + // New palette: Industrial/Tech style + tactical: { + bg: '#1a1a1a', + surface: '#222222', + border: '#333333', + borderLight: '#555555', + text: '#e0e0e0', + textMuted: '#888888', + textDim: '#555555', + accent: '#ff4500', + accentDim: '#cc3700', + black: '#111111', + dark: '#1e1e1e', + gray: '#333333', + green: '#ff4500', + gold: '#ff4500', + goldLight: '#ff6a33', + warn: '#cc3300', + army: '#ff4500', + armyDark: '#1a0a00', + }, + }, + fontFamily: { + sans: ['Inter', 'Helvetica', 'sans-serif'], + mono: ['JetBrains Mono', 'monospace'], + tech: ['Inter', 'sans-serif'], + }, + }, + }, + plugins: [], +}; + +export default config; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..290dc4c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src/**/*"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..c9d5f41 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts", "electron/**/*"] +} diff --git a/tsconfig.node.tsbuildinfo b/tsconfig.node.tsbuildinfo new file mode 100644 index 0000000..69a0f2c --- /dev/null +++ b/tsconfig.node.tsbuildinfo @@ -0,0 +1 @@ +{"fileNames":[],"fileInfos":[],"root":[],"options":{"allowSyntheticDefaultImports":true,"composite":true,"module":99,"outDir":"./","skipLibCheck":true,"strict":true},"errors":true,"version":"5.9.3"} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..3683f86 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import path from 'path'; + +export default defineConfig({ + plugins: [react()], + base: './', + root: '.', + build: { + outDir: 'dist', + emptyOutDir: true, + }, + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, +});