diff --git a/.gitignore b/.gitignore index a547bf3..46fa6ef 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ lerna-debug.log* node_modules dist dist-ssr +dist-electron *.local # Editor directories and files @@ -22,3 +23,7 @@ dist-ssr *.njsproj *.sln *.sw? + +# Electron +electron/*.js +electron/*.d.ts diff --git a/.tauri/myapp.key b/.tauri/myapp.key deleted file mode 100644 index c4222c4..0000000 --- a/.tauri/myapp.key +++ /dev/null @@ -1 +0,0 @@ -dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5b29vWWcwSnZkbzlYQWNNQzJuVEZ2dlJJd3A0MUhTcEpCYmZubFdlVmVvY0FBQkFBQUFBQUFBQUFBQUlBQUFBQXEveUNRTnFXUEE5Q3M5Und2YTFlQWdRUVh1L3hudGJaTnZlRlRHM3FwZkVHQXBhNlpQWmF3bkcwTGJ5N1MwbEFIRFVXM3lCc3QxdUVOeDJqeVdVK29lZkllRmxWZ2FxcW1CK2cvYTFwMUptQ0hMZEpjZXhpdU1Ndm9CVWcrTk91aXBiSHB4MVBKdU09Cg== \ No newline at end of file diff --git a/.tauri/myapp.key.pub b/.tauri/myapp.key.pub deleted file mode 100644 index 11546bd..0000000 --- a/.tauri/myapp.key.pub +++ /dev/null @@ -1 +0,0 @@ -dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEYxRDZBQjc3QUQxNDBGNDUKUldSRkR4U3RkNnZXOGNtdHE4TS80d3p4UHlhaEVVMDFUTFRrQmhySnFVNWdZWHNXOWUraFFhRTcK \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 24d7cc6..1d7ac85 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,3 @@ { - "recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"] + "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"] } diff --git a/AGENTS.md b/AGENTS.md index 9563521..6d7318a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,43 +1,56 @@ # koring-launcher -Minecraft launcher built with Tauri 2 + React 19 + TypeScript + Sidecar (Node.js/@xmcl). +Minecraft launcher built with Electron + React 19 + TypeScript + Node.js (@xmcl). ## Quick commands ```bash -pnpm tauri dev # full app dev (frontend + Rust + sidecar skip) -pnpm dev # frontend only (vite, port 1420) -cd sidecar && pnpm dev # sidecar dev (tsx) +pnpm dev # full app dev (renderer + main process) +pnpm dev:renderer # frontend only (vite, port 1420) +pnpm dev:main # electron main process only +pnpm build # production build (vite + tsc) +pnpm dist:win # build Windows installer ``` ## Architecture - **Frontend** (`src/`): React 19 + Vite 7 + Tailwind v4 + shadcn/ui + Zustand stores -- **Backend** (`src-tauri/`): Rust/Tauri 2, manages sidecar process via stdin/stdout JSON -- **Sidecar** (`sidecar/`): Node.js/TypeScript, wraps @xmcl/* packages (MC install/launch/auth/mods) -- IPC: Frontend → `invoke()` → Rust commands → sidecar stdin → sidecar stdout → Tauri events → Frontend +- **Main Process** (`electron/`): Node.js/TypeScript, manages windows, IPC handlers, @xmcl/* packages +- IPC: Frontend → `ipcRenderer.invoke()` → `ipcMain.handle()` → main process → `webContents.send()` → Frontend ## Key gotchas -- **Sidecar binary required**: `src-tauri/binaries/koring-sidecar-.exe` must exist. In debug mode it's skipped automatically (`#[cfg(debug_assertions)]` in `lib.rs:setup`). -- **Sidecar compile**: `cd sidecar && pnpm compile` (requires `bun`). Default target is ARM64 Windows. Use `pnpm compile:x64` for x86_64. -- **@xmcl packages are Node.js only**: `@xmcl/core`, `@xmcl/installer` require `fs`/`child_process`. Only `@xmcl/user`, `@xmcl/modrinth`, `@xmcl/curseforge` work in browser. +- **Electron main process**: `electron/main.ts` is the entry point. All @xmcl/* packages run here. +- **Preload script**: `electron/preload.ts` exposes `window.electronAPI` via context bridge. +- **IPC handlers**: All handlers are in `electron/handlers/` directory. +- **Config**: YAML format (`Koring.yml`) stored next to executable. Sparse save (only non-default values). +- **Auth**: JSON file (`koring-auth.json`) stored next to executable. - **Path alias**: `@/` maps to `src/` (configured in `vite.config.ts` and `tsconfig.json`). -- **Tauri commands**: All Rust commands are in `src-tauri/src/commands/mod.rs`. They forward to sidecar via `SidecarManager`. -- **State management**: Zustand stores in `src/stores/` (install, auth, launch, mods, instance). +- **Dev mode**: Vite runs on port 1420, Electron loads from localhost. ## Build & bundle ```bash -pnpm tauri build # production build (requires sidecar binary in binaries/) -cd sidecar && pnpm compile # compile sidecar to exe first +pnpm build # Vite build + TypeScript compile +pnpm dist:win # electron-builder Windows installer +pnpm dist:mac # electron-builder macOS DMG +pnpm dist:linux # electron-builder Linux AppImage ``` -The `externalBin` in `tauri.conf.json` expects `binaries/koring-sidecar-.exe`. +## Electron notes -## Rust notes +- `electron/main.ts`: App entry, window management, IPC handler registration +- `electron/preload.ts`: Context bridge for secure IPC +- `electron/config.ts`: YAML config management (sparse save) +- `electron/auth.ts`: Auth data persistence (JSON file) +- `electron/core/`: @xmcl/* integrations (auth, installer, launcher, modrinth, instance) +- `electron/handlers/`: IPC handlers (config, auth, install, launch, mods, instance, background, task, system, window) -- `src-tauri/src/lib.rs`: app entry, registers plugins and commands -- `src-tauri/src/sidecar.rs`: `SidecarManager` — spawns sidecar, reads stdout, emits Tauri events -- `src-tauri/src/commands/mod.rs`: all `#[tauri::command]` handlers -- `uuid` crate used for request IDs +## Frontend notes + +- `src/api/ipc.ts`: Core IPC utilities (invoke, onIpcEvent) +- `src/api/*.ts`: API modules wrapping IPC calls +- `src/stores/`: Zustand state management +- `src/hooks/useTheme.ts`: Dark mode sync with Electron theme +- `src/components/system/WindowControls.tsx`: Custom window controls (min/max/close) +- `src/components/system/TitleBar.tsx`: Custom title bar with navigation diff --git a/DEV.md b/DEV.md index 4bd9579..e945c69 100644 --- a/DEV.md +++ b/DEV.md @@ -9,6 +9,7 @@ | 状态管理 | Zustand | | Backend | Rust / Tauri 2 | | Sidecar | Node.js / TypeScript / @xmcl/* | +| 配置存储 | YAML (serde_yaml) + Windows Registry | | 包管理 | pnpm | | 目标平台 | ARM64 Windows (`aarch64-pc-windows-msvc`) | @@ -47,12 +48,146 @@ VITE_START_POP_BOUTTON="..." # 弹窗按钮文字 --- +## 配置存储架构 + +### 概览 + +| 数据类型 | 存储位置 | 格式 | 说明 | +|---------|---------|------|------| +| 用户设置 | 程序目录 `Koring.yml` | YAML | 所有可配置项 | +| 账户凭证 | Windows Registry `HKCU\Software\KoringLauncher` | REG_SZ | token/xboxProfile | +| 实例配置 | 实例目录 `koring-instance.json` | JSON | per-instance | +| 任务历史 | localStorage `koring-task-history` | JSON | 临时,max 50 | + +### Koring.yml 结构 + +```yaml +version: 1 + +theme: + darkMode: auto # auto | light | dark + parallax: true + +a11y: + reduceMotion: false + reduceTransparency: false + highContrast: false + contentBlurOpacity: 50 # 0-100 + +background: + bgType: image # image | color + image: /background.png + blur: 0 # 0-20 + opacity: 100 # 0-100 + +game: + gameDir: .minecraft + resourceDir: "" + savesDir: "" + instancesDir: .minecraft/instances + +java: + javaPath: "" + memMode: auto # auto | custom + memGB: 4 # 1-16 + gc: auto # auto | zgc | g1 + jvmArgs: "" + +advanced: + afterLaunch: close # close | minimize | keep + winMode: default # default | fullscreen | custom + customWidth: 854 + customHeight: 480 + gameArgs: "" + preLaunchCmd: "" + debugMode: false + +download: + fileSource: mirror # mirror | official | official-only + versionSource: mirror + threads: 16 # 1-64 + speedLimit: 0 # KB/s, 0=不限速 + +network: + securityId: + enabled: false + authUrl: "" +``` + +### 注册表结构 + +``` +HKCU\Software\KoringLauncher + └─ auth + ├─ username (REG_SZ) + ├─ uuid (REG_SZ) + ├─ accessToken (REG_SZ) + ├─ refreshToken (REG_SZ) + └─ xboxProfile (REG_SZ, JSON string) +``` + +### 向上兼容策略 + +1. **版本号** — `version` 字段,每次结构变更递增 +2. **默认值填充** — 加载时缺失字段自动补全,不丢数据 +3. **迁移函数** — `migrate_v0_to_v1()` 等,按版本链执行 +4. **未知字段保留** — YAML 解析器保留不认识的字段 +5. **Debounce 写入** — 300ms debounce 避免频繁 IO + +### Rust 实现 + +**新文件:** +- `src-tauri/src/config.rs` — `AppConfig` 结构体、`load_config()`、`save_config()`、`merge_defaults()`、`migrate()` +- `src-tauri/src/registry.rs` — `read_auth()`、`write_auth()`、`delete_auth()` + +**Tauri 命令:** +- `get_config` → 返回 `AppConfig` JSON +- `save_config(cfg)` → 写入 `Koring.yml` +- `get_auth` → 从注册表读取 `AuthData` +- `save_auth(auth)` → 写入注册表 +- `delete_auth_cmd` → 删除注册表认证数据 + +### 前端实现 + +**新文件:** +- `src/api/config.ts` — `getConfig()`、`saveConfig()` 类型定义 +- `src/api/auth-registry.ts` — `getAuth()`、`saveAuth()`、`deleteAuth()` +- `src/stores/configStore.ts` — 统一配置 Zustand store + +**configStore 接口:** +```ts +useConfigStore.getState().config // 完整配置 +useConfigStore.getState().loaded // 是否已加载 +useConfigStore.getState().init() // 从 Rust 加载 +useConfigStore.getState().setTheme({...}) // 部分更新 + debounce 写回 +useConfigStore.getState().setA11y({...}) +useConfigStore.getState().setBackground({...}) +useConfigStore.getState().setGame({...}) +useConfigStore.getState().setJava({...}) +useConfigStore.getState().setAdvanced({...}) +useConfigStore.getState().setDownload({...}) +useConfigStore.getState().setNetwork({...}) +``` + +**Store 委托模式:** +themeStore / a11yStore / backgroundStore / authStore 都是 configStore 的薄包装层: +- 读取时从 `configStore.config.*` 同步 +- 写入时通过各自的 `set*()` 同时更新本地状态和 configStore +- 提供 `sync*FromConfig()` 函数在 App 启动时同步 + +**App 启动流程:** +``` +configStore.init() → syncThemeFromConfig() → syncA11yFromConfig() → syncBackgroundFromConfig() → authStore.initFromRegistry() +``` + +--- + ## 项目结构 ``` koring-launcher/ ├── src/ # 前端源码 -│ ├── App.tsx # 路由入口 (Zustand 路由) +│ ├── App.tsx # 路由入口 + configStore 初始化 │ ├── index.css # 全局样式 + CSS 变量 + 动画 │ ├── layouts/ │ │ └── RootLayout.tsx # 三层布局: BackgroundLayer + ContentLayer + SystemLayer @@ -69,7 +204,6 @@ koring-launcher/ │ │ │ └── Silk.tsx # WebGL 丝绸着色器 (Three.js) │ │ ├── task/ │ │ │ ├── TaskButton.tsx # 标题栏任务指示器 (SVG 圆弧动画) -│ │ │ ├── TaskSheet.tsx # 任务队列侧面板 (z-[110]) │ │ │ └── TaskCard.tsx # 单个任务卡片 (进度条+日志) │ │ ├── ui/ # shadcn/ui 组件 │ │ │ ├── sheet.tsx, button.tsx, switch.tsx, slider.tsx @@ -78,25 +212,52 @@ koring-launcher/ │ │ ├── VersionCard.tsx # 版本/更新卡片 (Silk 背景+毛玻璃) │ │ ├── UnderConstruction.tsx # "装修中" 占位组件 │ │ └── StartupPopup.tsx # 启动弹窗 (环境变量控制) -│ ├── stores/ # Zustand 状态管理 +│ ├── stores/ +│ │ ├── configStore.ts # 统一配置 store (→ Koring.yml) +│ │ ├── themeStore.ts # 主题 (委托 configStore) +│ │ ├── a11yStore.ts # 无障碍 (委托 configStore) +│ │ ├── backgroundStore.ts # 背景 (委托 configStore) +│ │ ├── authStore.ts # 认证 (→ Registry) +│ │ ├── routeStore.ts # 路由 (历史栈) +│ │ ├── taskStore.ts # 任务队列 (localStorage) +│ │ ├── instanceStore.ts # 实例管理 +│ │ ├── installStore.ts # Minecraft 安装 +│ │ ├── launchStore.ts # 游戏启动 +│ │ ├── modsStore.ts # Mod 搜索 +│ │ ├── updateStore.ts # 应用更新 +│ │ └── devStore.ts # 开发者调试 +│ ├── api/ +│ │ ├── config.ts # AppConfig 读写 (→ Tauri invoke) +│ │ ├── auth-registry.ts # AuthData 读写 (→ Registry) +│ │ ├── instance.ts # 实例 API +│ │ ├── auth.ts # 登录 API +│ │ ├── sidecar.ts # 通用 sidecar IPC +│ │ └── ... │ ├── hooks/ │ │ └── useTheme.ts # 同步 darkMode → .dark class │ ├── lib/ │ │ ├── mode.ts # BUILD_MODE 常量 │ │ └── utils.ts # cn() 工具函数 -│ ├── api/ # Sidecar IPC 封装 │ ├── types/ │ │ └── task.ts # Task 类型定义 │ └── pages/ # 页面组件 ├── src-tauri/ # Rust 后端 +│ ├── Cargo.toml # 依赖: serde, serde_json, serde_yaml, winreg │ ├── tauri.conf.json # 窗口配置 + Bundle + Updater │ ├── capabilities/default.json # 权限声明 │ ├── src/ -│ │ ├── lib.rs # 插件注册 + splash/main 窗口逻辑 -│ │ ├── commands/mod.rs # Tauri 命令 (→ sidecar) +│ │ ├── lib.rs # 插件注册 + splash/main + 命令注册 +│ │ ├── config.rs # AppConfig 读写 + 迁移 + 默认值 +│ │ ├── registry.rs # Windows Registry 读写 +│ │ ├── commands/mod.rs # Tauri 命令 (→ sidecar + config + auth) │ │ └── sidecar.rs # Sidecar 进程管理 │ └── binaries/ # Sidecar 二进制文件 -├── splash.html # 启动动画 HTML 入口 (加载 Splash.tsx) +├── sidecar/ # Node.js Sidecar +│ └── src/ +│ ├── handlers/ # 10 个 handler +│ ├── utils/paths.ts # 路径工具 + InstanceConfig +│ └── protocol/types.ts # IPC 消息类型 +├── splash.html # 启动动画 HTML 入口 ├── build-vs.cmd # VS 环境编译脚本 └── dev-vs.cmd # VS 环境开发脚本 ``` @@ -109,274 +270,105 @@ koring-launcher/ | Key | Label | 组件 | 说明 | |---|---|---|---| -| `home` | 首页 | `pages/home/index.tsx` | 欢迎页 | +| `home` | 首页 | `pages/home/index.tsx` | StartCard 启动组件 | | `store` | 资源 | `pages/store/index.tsx` | 🚧 装修中 | | `today` | 资讯 | `pages/today/index.tsx` | 🚧 装修中 | | `play-link` | 联机 | `pages/play-link/index.tsx` | 🚧 装修中 | | `setting` | 设置 | `pages/setting/index.tsx` | 侧边栏 + 内容区 | -### 隐藏路由 (debug) +### 隐藏路由 | Key | Label | 组件 | |---|---|---| +| `task-queue` | 任务队列 | `pages/task-queue.tsx` | | `debug` | 调试 | `pages/debug/index.tsx` | | `debug-splash` | 启动动画调试 | `pages/debug/splash-debug.tsx` | | `debug-display` | 显示效果调试 | `pages/debug/display-debug.tsx` | | `debug-version-card` | 版本卡片调试 | `pages/debug/version-card-debug.tsx` | | `debug-task` | 任务队列调试 | `pages/debug/task-debug.tsx` | -### 路由层级 (返回导航) +### 路由导航 (历史栈) -``` -home / store / today / play-link / setting - └─ debug - ├─ debug-splash - ├─ debug-display - ├─ debug-version-card - └─ debug-task -``` - -### 设置子页面 (setting 内部侧边栏) - -| 分组 | Key | 组件 | 状态 | -|---|---|---|---| -| **通用** | `home` | `general/home.tsx` | ✅ 设置首页 (搜索+快捷入口) | -| | `account` | `general/account.tsx` | ✅ Koring 账户 (微软登录) | -| | `game-account` | `game/game-account.tsx` | 🚧 占位 | -| | `about` | `general/about.tsx` | ✅ 关于 (版本卡+链接) | -| | `copyright` | `general/copyright.tsx` | ✅ 版权声明 | -| **游戏** | `java-mem` | `game/java-mem.tsx` | ✅ Java/内存/JVM 参数 | -| | `game-dir` | `game/game-dir.tsx` | ✅ 游戏目录路径 | -| | `advanced` | `game/advanced.tsx` | ✅ 高级设置 | -| **个性化** | `theme-bg` | `personalization/theme-bg.tsx` | ✅ 主题+背景 (文件选择器) | -| | `ui` | `personalization/ui.tsx` | ✅ UI 设置 | -| | `lang` | `personalization/lang.tsx` | ✅ 语言设置 | -| | `a11y` | `personalization/a11y.tsx` | ✅ 无障碍 | -| **网络** | `download` | `network/download.tsx` | ✅ 下载设置 | -| | `security-id` | `network/security-id.tsx` | ✅ 第三方认证 | -| | `ether-online` | `network/ether-online.tsx` | 🚧 占位 | -| | `tawa-online` | `network/tawa-online.tsx` | 🚧 占位 | -| **其他** | `feedback` | `other/feedback.tsx` | 🚧 占位 | -| | `sponsor` | `other/sponsor.tsx` | 🚧 占位 | -| | `developer` | _(→ debug route)_ | 跳转调试页 | +路由使用动态历史栈替代静态 parentMap。每次 `navigate()` 压入历史,`goBack()` 弹出。 --- ## Zustand Stores -### routeStore +### configStore (统一配置中心) -管理页面路由和标题栏模式。 +所有用户设置的单一数据源。读写通过 Tauri invoke 与 `Koring.yml` 同步。 ```ts -// State -current: RouteKey // 当前路由 key -titleBarMode: TitleBarMode // "default" | "sub" | "window" -direction: TransitionDirection // "forward" | "backward" +config: AppConfig // 完整配置 +loaded: boolean // 是否已从 Rust 加载 -// Actions -navigate(key) // 跳转路由 (View Transitions API 动画) -goBack() // 返回父路由 (通过 parentMap) -setTitleBarMode(m) // 手动设置标题栏模式 +init() // 从 Rust 加载配置 +setTheme(patch) // 部分更新 + debounce 300ms 写回 +setA11y(patch) +setBackground(patch) +setGame(patch) +setJava(patch) +setAdvanced(patch) +setDownload(patch) +setNetwork(patch) ``` -### themeStore - -深色模式和视差设置。 +### themeStore (委托 configStore) ```ts -// State -darkMode: "auto" | "light" | "dark" // 默认 "auto" -parallax: boolean // 默认 true - -// Actions -setDarkMode(mode) // 应用深色模式到 DOM (.dark class) -setParallax(v) // 设置视差开关 +darkMode: "auto" | "light" | "dark" +parallax: boolean +setDarkMode(mode) // 更新 DOM + configStore +setParallax(v) // configStore +syncThemeFromConfig() // 启动时从 config 同步 ``` -### backgroundStore - -背景图片/颜色/模糊/透明度 (localStorage 持久化)。 +### a11yStore (委托 configStore) ```ts -// State (localStorage: "koring-background") -type: "image" | "color" // 默认 "image" -image: string // 默认 "/background.png" -blur: number // 默认 0 (0-20) -opacity: number // 默认 1 (0-1) - -// Actions -setImage(url) // 设置背景图 (通过 convertFileSrc 转换本地路径) -setColor(color) // 设置纯色背景 -setBlur(blur) // 设置模糊 -setOpacity(op) // 设置透明度 -reset() // 恢复默认 +reduceMotion, reduceTransparency, highContrast, contentBlurOpacity +syncA11yFromConfig() ``` -### a11yStore - -无障碍设置。 +### backgroundStore (委托 configStore) ```ts -// State -reduceMotion: boolean // 默认 false -reduceTransparency: boolean // 默认 false -highContrast: boolean // 默认 false -contentBlurOpacity: number // 默认 50 (0-100) - -// Actions -setReduceMotion(v) -setReduceTransparency(v) -setHighContrast(v) -setContentBlurOpacity(v) +type: "image" | "color", image, blur, opacity +setImage / setColor / setBlur / setOpacity / reset +syncBackgroundFromConfig() ``` -### devStore - -开发者调试控制。 +### authStore (委托 Registry) ```ts -// State -forceDisableContentBlur: boolean // 默认 false -previewMode: string | null // 默认 null -previewUpdateState: PreviewUpdateState | null // 默认 null -overlayOpacity: number // 默认 30 -blurAmount: number // 默认 12 - -// Actions -setForceDisableContentBlur(v) -setPreviewMode(v) -setPreviewUpdateState(v) -setOverlayOpacity(v) -setBlurAmount(v) +user: AuthResult | null +initFromRegistry() // 从 Windows Registry 加载 +loginOffline(username) // 通过 sidecar + 保存到 registry +logout() // 清除 registry ``` -### updateStore - -应用更新。 +### routeStore (历史栈导航) ```ts -// State -checking: boolean -downloading: boolean -installed: boolean -progress: DownloadProgress | null -update: Update | null -error: string | null - -// Actions -check() // 检查更新 (调用 @tauri-apps/plugin-updater) -install() // 下载并安装 -reset() // 清除状态 +current: RouteKey +history: RouteKey[] // 导航历史栈 +navigate(key) // 压入历史 +goBack() // 弹出历史 ``` -### taskStore +### taskStore (localStorage) -任务队列系统 (localStorage 持久化历史)。 +任务队列。localStorage 持久化历史 (max 50)。 -```ts -// State (localStorage: "koring-task-history", max 50) -tasks: Task[] -sheetOpen: boolean +### 其他 Store -// Derived -isRunning() // 是否有运行中/等待中的任务 -activeTasks() // 运行中+等待中的任务列表 -completedTasks() // 已完成/失败/取消的任务列表 - -// Actions -addTask(type, title, desc, executor) // 添加任务并自动开始 -cancelTask(id) // 取消任务 (AbortController) -removeTask(id) // 删除任务 -retryTask(id) // 重试失败任务 -clearHistory() // 清空历史 -openSheet() / closeSheet() -``` - -### authStore - -账户认证 (localStorage: "koring-user")。 - -```ts -// State -user: AuthResult | null // { username, uuid, accessToken, expiresAt, xboxProfile } -loading: boolean -error: string | null - -// Actions -loginOffline(username) -startMicrosoftLogin(clientId) -completeMicrosoftLogin(code, clientId) -logout() -``` - -### installStore - -Minecraft 安装。 - -```ts -// State -versions: VersionManifest | null -installing: boolean -loading: boolean -error: string | null - -// Actions -fetchVersions(type?) -install(version, gamePath, javaPath?) -installLoader(mcVersion, gamePath, loaderType, loaderVersion?, javaPath?) -``` - -### launchStore - -游戏启动。 - -```ts -// State -launching: boolean -launched: boolean -gameResult: LaunchResult | null -events: GameEvent[] -error: string | null - -// Actions -launch(options: LaunchOptions) -diagnose(gamePath, version) -reset() -``` - -### modsStore - -Mod 搜索与安装。 - -```ts -// State -searchResults: ModSearchResult[] -currentMod: ModSearchResult | null -modVersions: ModVersionResult[] - -// Actions -search(query?, gameVersion?, loader?, source?) -getDetail(projectId, source) -getVersions(projectId, gameVersion?, loader?, source?) -install(projectId, versionId, gamePath, source?) -``` - -### instanceStore - -游戏实例管理。 - -```ts -// State -instances: InstanceInfo[] -currentInstance: InstanceInfo | null - -// Actions -fetchInstances(instancesPath) -create(name, gamePath, mcVersion, ...) -remove(name, instancesPath) -select(name, instancesPath) -``` +- `devStore` — 开发者调试 (内存) +- `installStore` — Minecraft 安装 (内存,ephemeral) +- `launchStore` — 游戏启动 (内存,ephemeral) +- `modsStore` — Mod 搜索 (内存,ephemeral) +- `updateStore` — 应用更新 (内存,ephemeral) +- `instanceStore` — 实例管理 (sidecar 查询) --- @@ -388,7 +380,6 @@ select(name, instancesPath) z-0 BackgroundLayer 全屏背景图 + 视差 + 模糊 + 强内容遮罩 z-1 ContentLayer 页面内容区 (top: 40px, overflow-auto) z-100 SystemLayer 自定义标题栏 (TitleBar) -z-110 TaskSheet 任务队列面板 (右滑入) z-200 StartupPopup 启动弹窗 (环境变量控制) ``` @@ -406,12 +397,12 @@ z-200 StartupPopup 启动弹窗 (环境变量控制) - 强内容遮罩: 非 home 页面自动显示 (可通过 `contentBlurOpacity` 控制) - 深色模式叠加层: `bg-black/35` -### VersionCard 版本卡片 +### StartCard 启动组件 (首页) -- Silk WebGL 动画背景 + 毛玻璃叠加层 -- 三种更新状态: `latest` / `hasUpdate` / `installed` -- 颜色方案: dev=amber, beta=emerald, run=blue -- 可通过 props 覆盖 mode 和 state (用于 debug) +胶囊形启动组件,位于首页左下角: +- 左: 设置齿轮图标 (→ setting) +- 中: "启动游戏" 按钮 (primary 色, rounded-full) +- 右: 实例选择图标 (Package) ### TaskQueue 任务系统 @@ -432,22 +423,32 @@ z-200 StartupPopup 启动弹窗 (环境变量控制) ## 权限 (capabilities/default.json) -```json +``` core:default, core:window:default, core:window:allow-*, core:webview:allow-create-webview-window, opener:default, process:default, shell:allow-execute, updater:default, dialog:default ``` -## Rust 插件 +## Rust 依赖 ```toml +tauri = "2" tauri-plugin-opener, tauri-plugin-process, tauri-plugin-dialog, tauri-plugin-shell, tauri-plugin-updater +serde = { version = "1", features = ["derive"] } +serde_json = "1" +serde_yaml = "0.9" +uuid = { version = "1", features = ["v4"] } +tokio = { version = "1", features = ["time"] } +[target.'cfg(windows)'.dependencies] +winreg = "0.52" ``` ## IPC 协议 -前端 → `invoke()` → Rust `commands::sidecar_request` → sidecar stdin (JSON) → sidecar stdout (JSON) → Tauri 事件 → 前端 +前端 → `invoke()` → Rust `commands::*` → sidecar stdin (JSON) → sidecar stdout (JSON) → Tauri 事件 → 前端 -Sidecar 命令: `install-minecraft`, `install-mod-loader`, `get-version-list`, `launch-game`, `offline-login`, `search-mods`, `install-mod`, `create-instance`, `list-instances`, `background:*` +Sidecar 命令: `install-minecraft`, `install-mod-loader`, `get-version-list`, `launch-game`, `offline-login`, `search-mods`, `install-mod`, `create-instance`, `list-instances` + +Rust 直接命令: `get_config`, `save_config`, `get_auth`, `save_auth`, `delete_auth_cmd` diff --git a/README.md b/README.md index a6b0261..2322d24 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,42 @@ # Koring Launcher -Minecraft launcher built with Tauri 2 + React 19 + TypeScript + Sidecar (Node.js/@xmcl). +Minecraft launcher built with Electron + React 19 + TypeScript + Node.js (@xmcl). ## Quick Start ```bash pnpm install -pnpm dev:t # full app (frontend + Rust + sidecar skip in dev) -pnpm dev # frontend only (vite, port 1420) -cd sidecar && pnpm dev # sidecar dev (tsx) +pnpm dev # full app (frontend + electron) +pnpm dev:renderer # frontend only (vite, port 1420) +pnpm dev:main # electron main process only ``` ## Build ```bash -pnpm tauri build # production (auto-switches to run icon) -pnpm build:beta # beta build -cd sidecar && pnpm compile # compile sidecar to exe first +pnpm build # production build (vite + tsc) +pnpm dist:win # build Windows installer +pnpm dist:mac # build macOS DMG +pnpm dist:linux # build Linux AppImage ``` ## Architecture ``` src/ Frontend (React 19 + Vite 7 + Tailwind v4 + shadcn/ui + Zustand) -src-tauri/ Backend (Rust/Tauri 2) -sidecar/ Node.js sidecar (@xmcl/* packages) +electron/ Main process (Node.js/TypeScript, @xmcl/* packages) public/ Static assets (icons, fonts, images) -scripts/ Build scripts ``` **IPC Flow:** -Frontend → `invoke()` → Rust commands → sidecar stdin → sidecar stdout → Tauri events → Frontend +Frontend → `ipcRenderer.invoke()` → `ipcMain.handle()` → main process → `webContents.send()` → Frontend ## Project Structure ``` src/ -├── api/ # Frontend API layer (sidecar IPC wrappers) -│ ├── sidecar.ts # Generic request/response +├── api/ # Frontend API layer (IPC wrappers) +│ ├── ipc.ts # Core IPC utilities │ ├── background.ts # Background control │ ├── install.ts # Minecraft install │ ├── launch.ts # Game launch @@ -58,6 +57,31 @@ src/ │ ├── mode.ts # Build mode detection (dev/beta/run) │ └── utils.ts # cn() helper └── App.tsx # Root component with state router + +electron/ +├── main.ts # Electron entry, window management +├── preload.ts # Context bridge (window.electronAPI) +├── config.ts # YAML config management +├── auth.ts # Auth data persistence +├── core/ # @xmcl/* integrations +│ ├── auth.ts # Microsoft OAuth, Xbox Live, MC auth +│ ├── installer.ts # @xmcl/installer +│ ├── launcher.ts # @xmcl/core game launcher +│ ├── modrinth.ts # Modrinth/CurseForge API +│ └── instance.ts # Instance management +├── handlers/ # IPC handlers +│ ├── config.ts # Config load/save +│ ├── auth.ts # Auth operations +│ ├── install.ts # Install operations +│ ├── launch.ts # Game launch +│ ├── mods.ts # Mod operations +│ ├── instance.ts # Instance operations +│ ├── background.ts # Background operations +│ ├── task.ts # Task system +│ ├── system.ts # System info +│ └── window.ts # Window controls +└── types/ + └── electron.d.ts # TypeScript declarations ``` ## Three-Layer Page Structure @@ -96,8 +120,6 @@ Three icon variants in `public/`: | beta | `beta.png` / `beta.ico` | Testing | | run | `run.png` / `run.ico` | Production release | -**Auto-switching:** Build scripts automatically copy the correct icon to `src-tauri/icons/` before building. - **Frontend usage:** ```tsx import { APP_ICON, BUILD_MODE, isDev } from "@/lib/mode"; @@ -106,46 +128,31 @@ import { APP_ICON, BUILD_MODE, isDev } from "@/lib/mode"; {isDev && Dev Mode} ``` -**Manual switch:** -```bash -pnpm icon:dev # switch to dev icon -pnpm icon:beta # switch to beta icon -pnpm icon:run # switch to release icon -``` +## IPC Handlers -## Sidecar - -Node.js process communicating with Rust via stdin/stdout JSON protocol. - -**Handlers:** +- `config:*` — Config load/save +- `auth:*` — Microsoft OAuth, offline login - `install:*` — Minecraft install, mod loader, version lists - `launch:*` — Game launch, diagnose -- `auth:*` — Microsoft OAuth, offline login - `mods:*` — Modrinth/CurseForge search, install - `instance:*` — Instance CRUD - `background:*` — Background image/color/blur/animation/theme - -**Compile:** -```bash -cd sidecar -pnpm compile # ARM64 Windows (default) -pnpm compile:x64 # x86_64 Windows -``` +- `task:*` — Task system progress +- `system:*` — System info +- `window:*` — Minimize/maximize/close ## Key Gotchas -- **Sidecar binary required**: `src-tauri/binaries/koring-sidecar-.exe` must exist. Skipped in debug mode (`#[cfg(debug_assertions)]`). -- **@xmcl packages are Node.js only**: `@xmcl/core`, `@xmcl/installer` require `fs`/`child_process`. Only `@xmcl/user`, `@xmcl/modrinth`, `@xmcl/curseforge` work in browser. +- **@xmcl packages run in main process**: `@xmcl/core`, `@xmcl/installer` require `fs`/`child_process`. All run in Electron main process. - **Path alias**: `@/` maps to `src/`. -- **Window dragging**: Use `appWindow.startDragging()` API, not `data-tauri-drag-region` (unreliable with transparent windows). -- **Transparent windows**: Require `decorations: false` + `transparent: true` in tauri.conf.json. -- **Permissions**: Window creation needs `core:webview:allow-create-webview-window` (not `core:window`). +- **Window dragging**: Use CSS `-webkit-app-region: drag` on titlebar. +- **Transparent windows**: `transparent: true` + `frame: false` in BrowserWindow options. +- **Auth storage**: JSON file (`koring-auth.json`) stored next to executable. ## Tech Stack | Layer | Technology | |-------|-----------| | Frontend | React 19, Vite 7, Tailwind CSS v4, shadcn/ui, Zustand | -| Backend | Rust, Tauri 2 | -| Sidecar | Node.js, TypeScript, @xmcl/* packages | -| Build | pnpm, Cargo, bun (sidecar compile) | +| Main Process | Node.js, TypeScript, @xmcl/* packages | +| Build | pnpm, Vite, electron-builder | diff --git a/build-vs.cmd b/build-vs.cmd deleted file mode 100644 index 459643f..0000000 --- a/build-vs.cmd +++ /dev/null @@ -1,18 +0,0 @@ -@echo off -call "C:\Program Files\Microsoft Visual Studio\18\Community\VC\Auxiliary\Build\vcvarsall.bat" arm64 -set PATH=C:\Users\OseasyVM\scoop\apps\llvm\current\bin;%PATH% -set CC=clang -cd /d "%~dp0" - -if "%~1"=="--mode" if "%~2"=="beta" ( - echo [build-vs] Beta mode: building frontend first... - call pnpm build:beta - echo [build-vs] Running tauri build with skip beforeBuildCommand... - call npx tauri build --config src-tauri\tauri.beta.json -) else ( - echo [build-vs] Production mode - call pnpm tauri build -) else ( - echo [build-vs] Production mode - call pnpm tauri build -) diff --git a/dev-vs.cmd b/dev-vs.cmd deleted file mode 100644 index 36e6053..0000000 --- a/dev-vs.cmd +++ /dev/null @@ -1,6 +0,0 @@ -@echo off -call "C:\Program Files\Microsoft Visual Studio\18\Community\VC\Auxiliary\Build\vcvarsall.bat" arm64 -set PATH=C:\Users\OseasyVM\scoop\apps\llvm\current\bin;%PATH% -set CC=clang -cd /d "%~dp0" -pnpm dev:t diff --git a/electron-builder.yml b/electron-builder.yml new file mode 100644 index 0000000..0a56c9c --- /dev/null +++ b/electron-builder.yml @@ -0,0 +1,27 @@ +appId: com.lingke.koring.launcher +productName: Koring Launcher +directories: + output: dist-electron +files: + - dist/** + - electron/**/*.js + - "!electron/**/*.ts" +win: + target: nsis + icon: public/icon.ico + artifactName: "koring-launcher-${version}-setup.${ext}" +mac: + target: dmg + icon: public/icon.png +linux: + target: AppImage + icon: public/icon.png +nsis: + oneClick: false + allowToChangeInstallationDirectory: true + installerIcon: public/icon.ico + uninstallerIcon: public/icon.ico + installerHeaderIcon: public/icon.ico + createDesktopShortcut: true + createStartMenuShortcut: true + shortcutName: Koring Launcher diff --git a/electron/auth.ts b/electron/auth.ts new file mode 100644 index 0000000..7be711f --- /dev/null +++ b/electron/auth.ts @@ -0,0 +1,44 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import electron from 'electron'; +const { app } = electron; + +export interface AuthData { + username: string; + uuid: string; + accessToken: string; + refreshToken: string; + xboxProfile: string; +} + +const authFile = (): string => { + if (app.isPackaged) { + return path.join(path.dirname(app.getPath('exe')), 'koring-auth.json'); + } + return path.join(__dirname, '..', 'koring-auth.json'); +}; + +export function readAuth(): AuthData { + const filePath = authFile(); + if (!fs.existsSync(filePath)) { + return { username: '', uuid: '', accessToken: '', refreshToken: '', xboxProfile: '' }; + } + try { + const raw = fs.readFileSync(filePath, 'utf-8'); + return JSON.parse(raw) as AuthData; + } catch { + return { username: '', uuid: '', accessToken: '', refreshToken: '', xboxProfile: '' }; + } +} + +export function writeAuth(auth: AuthData): void { + const filePath = authFile(); + fs.writeFileSync(filePath, JSON.stringify(auth, null, 2), 'utf-8'); +} + +export function deleteAuth(): void { + const filePath = authFile(); + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); + } +} diff --git a/electron/config.ts b/electron/config.ts new file mode 100644 index 0000000..f8195de --- /dev/null +++ b/electron/config.ts @@ -0,0 +1,161 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as yaml from 'js-yaml'; +import electron from 'electron'; +const { app } = electron; + +const CONFIG_FILE = 'Koring.yml'; +const CURRENT_VERSION = 1; + +function configPath(): string { + if (app.isPackaged) { + return path.join(path.dirname(app.getPath('exe')), CONFIG_FILE); + } + return path.join(__dirname, '..', CONFIG_FILE); +} + +export interface ThemeConfig { + darkMode: string; + parallax: boolean; +} + +export interface A11yConfig { + reduceMotion: boolean; + reduceTransparency: boolean; + highContrast: boolean; + contentBlurOpacity: number; +} + +export interface BackgroundConfig { + bgType: string; + image: string; + blur: number; + opacity: number; +} + +export interface GameConfig { + gameDir: string; + resourceDir: string; + savesDir: string; + instancesDir: string; +} + +export interface JavaConfig { + javaPath: string; + memMode: string; + memGB: number; + gc: string; + jvmArgs: string; +} + +export interface AdvancedConfig { + afterLaunch: string; + winMode: string; + customWidth: number; + customHeight: number; + gameArgs: string; + preLaunchCmd: string; + debugMode: boolean; +} + +export interface DownloadConfig { + fileSource: string; + versionSource: string; + threads: number; + speedLimit: number; +} + +export interface SecurityIdConfig { + enabled: boolean; + authUrl: string; +} + +export interface NetworkConfig { + securityId: SecurityIdConfig; +} + +export interface AppConfig { + version: number; + theme: ThemeConfig; + a11y: A11yConfig; + background: BackgroundConfig; + game: GameConfig; + java: JavaConfig; + advanced: AdvancedConfig; + download: DownloadConfig; + network: NetworkConfig; +} + +const DEFAULTS: AppConfig = { + version: CURRENT_VERSION, + theme: { darkMode: 'auto', parallax: true }, + a11y: { reduceMotion: false, reduceTransparency: false, highContrast: false, contentBlurOpacity: 50 }, + background: { bgType: 'image', image: '/background.png', blur: 0, opacity: 100 }, + game: { gameDir: '.minecraft', resourceDir: '', savesDir: '', instancesDir: '.minecraft/instances' }, + java: { javaPath: '', memMode: 'auto', memGB: 4, gc: 'auto', jvmArgs: '' }, + advanced: { afterLaunch: 'close', winMode: 'default', customWidth: 854, customHeight: 480, gameArgs: '', preLaunchCmd: '', debugMode: false }, + download: { fileSource: 'mirror', versionSource: 'mirror', threads: 16, speedLimit: 0 }, + network: { securityId: { enabled: false, authUrl: '' } }, +}; + +function migrate(config: AppConfig): AppConfig { + if (config.version < 1) { + config.version = 1; + } + return config; +} + +function diffValue(full: unknown, defaultVal: unknown): unknown { + if (full === null || full === undefined) return undefined; + if (typeof full !== 'object' || typeof defaultVal !== 'object') { + return full === defaultVal ? undefined : full; + } + if (Array.isArray(full) && Array.isArray(defaultVal)) { + return JSON.stringify(full) === JSON.stringify(defaultVal) ? undefined : full; + } + if (Array.isArray(full) !== Array.isArray(defaultVal)) return full; + + const fullObj = full as Record; + const defaultObj = defaultVal as Record; + const result: Record = {}; + + for (const key of Object.keys(fullObj)) { + const d = diffValue(fullObj[key], defaultObj[key]); + if (d !== undefined) { + result[key] = d; + } + } + + return Object.keys(result).length === 0 ? undefined : result; +} + +export function loadConfig(): AppConfig { + const filePath = configPath(); + if (!fs.existsSync(filePath)) { + return { ...DEFAULTS }; + } + + try { + const raw = fs.readFileSync(filePath, 'utf-8'); + if (!raw.trim()) return { ...DEFAULTS }; + const parsed = yaml.load(raw) as Partial; + const config = migrate({ ...DEFAULTS, ...parsed } as AppConfig); + config.version = CURRENT_VERSION; + return config; + } catch { + return { ...DEFAULTS }; + } +} + +export function saveConfig(config: AppConfig): void { + const filePath = configPath(); + const sparse = diffValue(config, DEFAULTS) as Record | undefined; + + if (!sparse || Object.keys(sparse).length === 0) { + try { fs.unlinkSync(filePath); } catch {} + return; + } + + const yamlStr = yaml.dump(sparse, { lineWidth: -1 }); + fs.writeFileSync(filePath, yamlStr, 'utf-8'); +} diff --git a/electron/core/auth.js b/electron/core/auth.js new file mode 100644 index 0000000..2556747 --- /dev/null +++ b/electron/core/auth.js @@ -0,0 +1,180 @@ +"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; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.microsoftLoginStart = microsoftLoginStart; +exports.microsoftLoginCallback = microsoftLoginCallback; +exports.offlineLogin = offlineLogin; +exports.validateMinecraftToken = validateMinecraftToken; +const crypto = __importStar(require("crypto")); +const electron_1 = __importDefault(require("electron")); +const { net } = electron_1.default; +const MC_SERVICES_API = 'https://api.minecraftservices.com'; +const XBOX_AUTH_URL = 'https://user.auth.xboxlive.com/user/authenticate'; +const XBOX_XSTS_URL = 'https://xsts.auth.xboxlive.com/xsts/authorize'; +const MC_AUTH_URL = 'https://api.minecraftservices.com/authentication/login_with_xbox'; +const MC_PROFILE_URL = 'https://api.minecraftservices.com/minecraft/profile'; +function generateState() { + return crypto.randomBytes(16).toString('hex'); +} +function generateVerifier() { + return crypto.randomBytes(32).toString('base64url'); +} +function generateChallenge(verifier) { + return crypto.createHash('sha256').update(verifier).digest('base64url'); +} +async function microsoftLoginStart(clientId, redirectUri) { + const state = generateState(); + const verifier = generateVerifier(); + const challenge = generateChallenge(verifier); + const params = new URLSearchParams({ + client_id: clientId, + response_type: 'code', + redirect_uri: redirectUri || 'http://localhost:3000/callback', + scope: 'XboxLive.signin offline_access', + state, + code_challenge: challenge, + code_challenge_method: 'S256', + }); + const authUrl = `https://login.live.com/oauth20_authorize.srf?${params.toString()}`; + return { state, authUrl, verifier }; +} +async function exchangeCodeForToken(code, clientId, redirectUri, verifier) { + const response = await net.fetch('https://login.live.com/oauth20_token.srf', { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: new URLSearchParams({ + client_id: clientId, + code, + grant_type: 'authorization_code', + redirect_uri: redirectUri, + code_verifier: verifier, + }).toString(), + }); + if (!response.ok) + throw new Error(`MS token exchange failed: ${response.status}`); + return response.json(); +} +async function authenticateWithXbox(msToken) { + const response = await net.fetch(XBOX_AUTH_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + Properties: { + AuthMethod: 'RPS', + SiteName: 'user.auth.xboxlive.com', + RpsTicket: msToken, + }, + RelyingParty: 'http://auth.xboxlive.com', + TokenType: 'JWT', + }), + }); + if (!response.ok) + throw new Error(`Xbox auth failed: ${response.status}`); + return response.json(); +} +async function authorizeWithXsts(xboxToken) { + const response = await net.fetch(XBOX_XSTS_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + Properties: { + SandboxId: 'RETAIL', + UserTokens: [xboxToken], + }, + RelyingParty: 'rp://api.minecraftservices.com/', + TokenType: 'JWT', + }), + }); + if (!response.ok) + throw new Error(`Xbox XSTS failed: ${response.status}`); + return response.json(); +} +async function authenticateWithMinecraft(xstsToken) { + const response = await net.fetch(MC_AUTH_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + identityToken: `XBL3.0 x=${xstsToken}`, + }), + }); + if (!response.ok) + throw new Error(`MC auth failed: ${response.status}`); + return response.json(); +} +async function getMinecraftProfile(accessToken) { + const response = await net.fetch(MC_PROFILE_URL, { + headers: { Authorization: `Bearer ${accessToken}` }, + }); + if (!response.ok) + throw new Error(`MC profile failed: ${response.status}`); + return response.json(); +} +async function microsoftLoginCallback(code, clientId, redirectUri) { + const redirect = redirectUri || 'http://localhost:3000/callback'; + const msToken = await exchangeCodeForToken(code, clientId, redirect, ''); + const xboxAuth = await authenticateWithXbox(msToken.access_token); + const xstsAuth = await authorizeWithXsts(xboxAuth.Token); + const mcAuth = await authenticateWithMinecraft(xstsAuth.Token); + const profile = await getMinecraftProfile(mcAuth.access_token); + return { + username: profile.name, + uuid: profile.id, + accessToken: mcAuth.access_token, + expiresAt: Date.now() + mcAuth.expires_in * 1000, + }; +} +async function offlineLogin(username) { + const uuid = crypto.createHash('md5').update(`OfflinePlayer:${username}`).digest('hex'); + const formattedUuid = `${uuid.slice(0, 8)}-${uuid.slice(8, 12)}-${uuid.slice(12, 16)}-${uuid.slice(16, 20)}-${uuid.slice(20)}`; + return { + username, + uuid: formattedUuid, + accessToken: '', + }; +} +async function validateMinecraftToken(accessToken) { + try { + const response = await net.fetch(`${MC_SERVICES_API}/minecraft/profile`, { + headers: { Authorization: `Bearer ${accessToken}` }, + }); + return response.ok; + } + catch { + return false; + } +} diff --git a/electron/core/auth.ts b/electron/core/auth.ts new file mode 100644 index 0000000..db360e1 --- /dev/null +++ b/electron/core/auth.ts @@ -0,0 +1,175 @@ +import * as crypto from 'crypto'; +import electron from 'electron'; + +const { net } = electron; + +const MC_SERVICES_API = 'https://api.minecraftservices.com'; +const XBOX_AUTH_URL = 'https://user.auth.xboxlive.com/user/authenticate'; +const XBOX_XSTS_URL = 'https://xsts.auth.xboxlive.com/xsts/authorize'; +const MC_AUTH_URL = 'https://api.minecraftservices.com/authentication/login_with_xbox'; +const MC_PROFILE_URL = 'https://api.minecraftservices.com/minecraft/profile'; + +interface XboxProfile { + gamertag: string; + gamerscore: string; + displayPicRaw: string; +} + +interface AuthResult { + username: string; + uuid: string; + accessToken: string; + expiresAt?: number; + xboxProfile?: XboxProfile; +} + +function generateState(): string { + return crypto.randomBytes(16).toString('hex'); +} + +function generateVerifier(): string { + return crypto.randomBytes(32).toString('base64url'); +} + +function generateChallenge(verifier: string): string { + return crypto.createHash('sha256').update(verifier).digest('base64url'); +} + +export async function microsoftLoginStart(clientId: string, redirectUri?: string) { + const state = generateState(); + const verifier = generateVerifier(); + const challenge = generateChallenge(verifier); + + const params = new URLSearchParams({ + client_id: clientId, + response_type: 'code', + redirect_uri: redirectUri || 'http://localhost:3000/callback', + scope: 'XboxLive.signin offline_access', + state, + code_challenge: challenge, + code_challenge_method: 'S256', + }); + + const authUrl = `https://login.live.com/oauth20_authorize.srf?${params.toString()}`; + + return { state, authUrl, verifier }; +} + +async function exchangeCodeForToken(code: string, clientId: string, redirectUri: string, verifier: string) { + const response = await net.fetch('https://login.live.com/oauth20_token.srf', { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: new URLSearchParams({ + client_id: clientId, + code, + grant_type: 'authorization_code', + redirect_uri: redirectUri, + code_verifier: verifier, + }).toString(), + }); + + if (!response.ok) throw new Error(`MS token exchange failed: ${response.status}`); + return response.json() as Promise<{ access_token: string; refresh_token: string }>; +} + +async function authenticateWithXbox(msToken: string) { + const response = await net.fetch(XBOX_AUTH_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + Properties: { + AuthMethod: 'RPS', + SiteName: 'user.auth.xboxlive.com', + RpsTicket: msToken, + }, + RelyingParty: 'http://auth.xboxlive.com', + TokenType: 'JWT', + }), + }); + + if (!response.ok) throw new Error(`Xbox auth failed: ${response.status}`); + return response.json() as Promise<{ IssueInstant: string; Token: string; NotAfter: string }>; +} + +async function authorizeWithXsts(xboxToken: string) { + const response = await net.fetch(XBOX_XSTS_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + Properties: { + SandboxId: 'RETAIL', + UserTokens: [xboxToken], + }, + RelyingParty: 'rp://api.minecraftservices.com/', + TokenType: 'JWT', + }), + }); + + if (!response.ok) throw new Error(`Xbox XSTS failed: ${response.status}`); + return response.json() as Promise<{ IssueInstant: string; Token: string; NotAfter: string }>; +} + +async function authenticateWithMinecraft(xstsToken: string) { + const response = await net.fetch(MC_AUTH_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + identityToken: `XBL3.0 x=${xstsToken}`, + }), + }); + + if (!response.ok) throw new Error(`MC auth failed: ${response.status}`); + return response.json() as Promise<{ username: string; access_token: string; token_type: string; expires_in: number }>; +} + +async function getMinecraftProfile(accessToken: string): Promise<{ id: string; name: string; skins: unknown[] }> { + const response = await net.fetch(MC_PROFILE_URL, { + headers: { Authorization: `Bearer ${accessToken}` }, + }); + + if (!response.ok) throw new Error(`MC profile failed: ${response.status}`); + return response.json() as Promise<{ id: string; name: string; skins: unknown[] }>; +} + +export async function microsoftLoginCallback( + code: string, + clientId: string, + redirectUri?: string +): Promise { + const redirect = redirectUri || 'http://localhost:3000/callback'; + + const msToken = await exchangeCodeForToken(code, clientId, redirect, ''); + const xboxAuth = await authenticateWithXbox(msToken.access_token); + const xstsAuth = await authorizeWithXsts(xboxAuth.Token); + const mcAuth = await authenticateWithMinecraft(xstsAuth.Token); + const profile = await getMinecraftProfile(mcAuth.access_token); + + return { + username: profile.name, + uuid: profile.id, + accessToken: mcAuth.access_token, + expiresAt: Date.now() + mcAuth.expires_in * 1000, + }; +} + +export async function offlineLogin(username: string): Promise { + const uuid = crypto.createHash('md5').update(`OfflinePlayer:${username}`).digest('hex'); + const formattedUuid = `${uuid.slice(0, 8)}-${uuid.slice(8, 12)}-${uuid.slice(12, 16)}-${uuid.slice(16, 20)}-${uuid.slice(20)}`; + + return { + username, + uuid: formattedUuid, + accessToken: '', + }; +} + +export async function validateMinecraftToken(accessToken: string): Promise { + try { + const response = await net.fetch(`${MC_SERVICES_API}/minecraft/profile`, { + headers: { Authorization: `Bearer ${accessToken}` }, + }); + return response.ok; + } catch { + return false; + } +} diff --git a/electron/core/installer.js b/electron/core/installer.js new file mode 100644 index 0000000..742d23d --- /dev/null +++ b/electron/core/installer.js @@ -0,0 +1,181 @@ +"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; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getVersionList = getVersionList; +exports.getForgeVersions = getForgeVersions; +exports.getFabricVersions = getFabricVersions; +exports.installMinecraft = installMinecraft; +exports.installModLoader = installModLoader; +const electron_1 = __importDefault(require("electron")); +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +const https = __importStar(require("https")); +const http = __importStar(require("http")); +const { net } = electron_1.default; +const VERSION_MANIFEST_URL = 'https://launchermeta.mojang.com/mc/game/version_manifest.json'; +const FORGE_VERSION_LIST_URL = 'https://files.minecraftforge.net/net/minecraftforge/forge/json'; +const FABRIC_VERSION_LIST_URL = 'https://meta.fabricmc.net/v2/versions'; +async function downloadFile(url, dest, onProgress) { + return new Promise((resolve, reject) => { + const client = url.startsWith('https') ? https : http; + const request = client.get(url, (response) => { + if (response.statusCode === 302 || response.statusCode === 301) { + downloadFile(response.headers.location, dest, onProgress).then(resolve).catch(reject); + return; + } + if (response.statusCode !== 200) { + reject(new Error(`Download failed: ${response.statusCode}`)); + return; + } + const totalBytes = parseInt(response.headers['content-length'] || '0', 10); + let downloadedBytes = 0; + const dir = path.dirname(dest); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + const file = fs.createWriteStream(dest); + response.on('data', (chunk) => { + downloadedBytes += chunk.length; + if (onProgress && totalBytes > 0) { + onProgress({ + stage: 'downloading', + current: downloadedBytes, + total: totalBytes, + message: `${Math.round((downloadedBytes / totalBytes) * 100)}%`, + }); + } + }); + response.pipe(file); + file.on('finish', () => { + file.close(); + resolve(); + }); + file.on('error', (err) => { + fs.unlink(dest, () => { }); + reject(err); + }); + }); + request.on('error', reject); + }); +} +async function getVersionList(type) { + const response = await net.fetch(VERSION_MANIFEST_URL); + if (!response.ok) + throw new Error(`Failed to fetch version manifest: ${response.status}`); + const manifest = await response.json(); + if (type && type !== 'all') { + manifest.versions = manifest.versions.filter((v) => v.type === type); + } + return manifest; +} +async function getForgeVersions(mcVersion) { + try { + const response = await net.fetch(FORGE_VERSION_LIST_URL); + if (!response.ok) + throw new Error(`Forge version list failed: ${response.status}`); + const data = await response.json(); + const versions = data.versions[mcVersion || ''] || []; + return { versions }; + } + catch { + return { versions: [] }; + } +} +async function getFabricVersions(mcVersion) { + try { + const url = mcVersion + ? `${FABRIC_VERSION_LIST_URL}/loader/${mcVersion}` + : `${FABRIC_VERSION_LIST_URL}/loader`; + const response = await net.fetch(url); + if (!response.ok) + throw new Error(`Fabric version list failed: ${response.status}`); + const data = await response.json(); + return { versions: data.map((v) => v.version) }; + } + catch { + return { versions: [] }; + } +} +async function installMinecraft(version, gamePath, javaPath, downloadThreads, callbacks) { + const versionDir = path.join(gamePath, 'versions', version); + if (!fs.existsSync(versionDir)) { + fs.mkdirSync(versionDir, { recursive: true }); + } + // Download version manifest + const manifestResponse = await net.fetch(VERSION_MANIFEST_URL); + const manifest = await manifestResponse.json(); + const versionInfo = manifest.versions.find((v) => v.id === version); + if (!versionInfo) + throw new Error(`Version ${version} not found`); + callbacks?.onProgress?.({ stage: 'downloading', current: 0, total: 100, message: 'Downloading version manifest...' }); + // Download version JSON + const versionJsonPath = path.join(versionDir, `${version}.json`); + await downloadFile(versionInfo.url, versionJsonPath, callbacks?.onProgress); + const versionJson = JSON.parse(fs.readFileSync(versionJsonPath, 'utf-8')); + // Download client jar + const clientJar = versionJson.downloads?.client; + if (clientJar) { + callbacks?.onProgress?.({ stage: 'downloading', current: 1, total: 3, message: 'Downloading client jar...' }); + const jarPath = path.join(versionDir, `${version}.jar`); + await downloadFile(clientJar.url, jarPath, callbacks?.onProgress); + } + callbacks?.onProgress?.({ stage: 'downloading', current: 2, total: 3, message: 'Installing libraries...' }); + // Download libraries + const libraries = versionJson.libraries || []; + for (const lib of libraries) { + if (lib.downloads?.artifact?.url) { + const libPath = path.join(gamePath, 'libraries', lib.downloads.artifact.path); + if (!fs.existsSync(libPath)) { + await downloadFile(lib.downloads.artifact.url, libPath); + } + } + } + callbacks?.onProgress?.({ stage: 'downloading', current: 3, total: 3, message: 'Installation complete' }); + return { version, gamePath }; +} +async function installModLoader(mcVersion, gamePath, loaderType, loaderVersion, javaPath, callbacks) { + callbacks?.onProgress?.({ stage: 'installing', current: 0, total: 100, message: `Installing ${loaderType}...` }); + // Placeholder: actual implementation depends on loader type + // This would call the appropriate installer for Forge/Fabric/Quilt/NeoForge + callbacks?.onProgress?.({ stage: 'installing', current: 100, total: 100, message: `${loaderType} installed` }); + return { + loaderType, + mcVersion, + loaderVersion: loaderVersion || 'latest', + }; +} diff --git a/electron/core/installer.ts b/electron/core/installer.ts new file mode 100644 index 0000000..7bb9109 --- /dev/null +++ b/electron/core/installer.ts @@ -0,0 +1,195 @@ +import electron from 'electron'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as https from 'https'; +import * as http from 'http'; + +const { net } = electron; + +const VERSION_MANIFEST_URL = 'https://launchermeta.mojang.com/mc/game/version_manifest.json'; +const FORGE_VERSION_LIST_URL = 'https://files.minecraftforge.net/net/minecraftforge/forge/json'; +const FABRIC_VERSION_LIST_URL = 'https://meta.fabricmc.net/v2/versions'; + +interface VersionInfo { + id: string; + type: string; + url: string; +} + +interface VersionManifest { + latest: { release: string; snapshot: string }; + versions: VersionInfo[]; +} + +interface DownloadProgress { + stage: string; + current: number; + total: number; + message?: string; +} + +async function downloadFile(url: string, dest: string, onProgress?: (progress: DownloadProgress) => void): Promise { + return new Promise((resolve, reject) => { + const client = url.startsWith('https') ? https : http; + const request = client.get(url, (response) => { + if (response.statusCode === 302 || response.statusCode === 301) { + downloadFile(response.headers.location!, dest, onProgress).then(resolve).catch(reject); + return; + } + + if (response.statusCode !== 200) { + reject(new Error(`Download failed: ${response.statusCode}`)); + return; + } + + const totalBytes = parseInt(response.headers['content-length'] || '0', 10); + let downloadedBytes = 0; + + const dir = path.dirname(dest); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + + const file = fs.createWriteStream(dest); + + response.on('data', (chunk) => { + downloadedBytes += chunk.length; + if (onProgress && totalBytes > 0) { + onProgress({ + stage: 'downloading', + current: downloadedBytes, + total: totalBytes, + message: `${Math.round((downloadedBytes / totalBytes) * 100)}%`, + }); + } + }); + + response.pipe(file); + + file.on('finish', () => { + file.close(); + resolve(); + }); + + file.on('error', (err) => { + fs.unlink(dest, () => {}); + reject(err); + }); + }); + + request.on('error', reject); + }); +} + +export async function getVersionList(type?: string): Promise { + const response = await net.fetch(VERSION_MANIFEST_URL); + if (!response.ok) throw new Error(`Failed to fetch version manifest: ${response.status}`); + const manifest = await response.json() as VersionManifest; + + if (type && type !== 'all') { + manifest.versions = manifest.versions.filter((v) => v.type === type); + } + + return manifest; +} + +export async function getForgeVersions(mcVersion?: string) { + try { + const response = await net.fetch(FORGE_VERSION_LIST_URL); + if (!response.ok) throw new Error(`Forge version list failed: ${response.status}`); + const data = await response.json() as { versions: Record }; + const versions = data.versions[mcVersion || ''] || []; + return { versions }; + } catch { + return { versions: [] }; + } +} + +export async function getFabricVersions(mcVersion?: string) { + try { + const url = mcVersion + ? `${FABRIC_VERSION_LIST_URL}/loader/${mcVersion}` + : `${FABRIC_VERSION_LIST_URL}/loader`; + const response = await net.fetch(url); + if (!response.ok) throw new Error(`Fabric version list failed: ${response.status}`); + const data = await response.json() as { version: string; stable: boolean }[]; + return { versions: data.map((v) => v.version) }; + } catch { + return { versions: [] }; + } +} + +export async function installMinecraft( + version: string, + gamePath: string, + javaPath?: string, + downloadThreads?: number, + callbacks?: { onProgress?: (progress: DownloadProgress) => void } +): Promise<{ version: string; gamePath: string }> { + const versionDir = path.join(gamePath, 'versions', version); + if (!fs.existsSync(versionDir)) { + fs.mkdirSync(versionDir, { recursive: true }); + } + + // Download version manifest + const manifestResponse = await net.fetch(VERSION_MANIFEST_URL); + const manifest = await manifestResponse.json() as VersionManifest; + const versionInfo = manifest.versions.find((v) => v.id === version); + + if (!versionInfo) throw new Error(`Version ${version} not found`); + + callbacks?.onProgress?.({ stage: 'downloading', current: 0, total: 100, message: 'Downloading version manifest...' }); + + // Download version JSON + const versionJsonPath = path.join(versionDir, `${version}.json`); + await downloadFile(versionInfo.url, versionJsonPath, callbacks?.onProgress); + + const versionJson = JSON.parse(fs.readFileSync(versionJsonPath, 'utf-8')); + + // Download client jar + const clientJar = versionJson.downloads?.client; + if (clientJar) { + callbacks?.onProgress?.({ stage: 'downloading', current: 1, total: 3, message: 'Downloading client jar...' }); + const jarPath = path.join(versionDir, `${version}.jar`); + await downloadFile(clientJar.url, jarPath, callbacks?.onProgress); + } + + callbacks?.onProgress?.({ stage: 'downloading', current: 2, total: 3, message: 'Installing libraries...' }); + + // Download libraries + const libraries = versionJson.libraries || []; + for (const lib of libraries) { + if (lib.downloads?.artifact?.url) { + const libPath = path.join(gamePath, 'libraries', lib.downloads.artifact.path); + if (!fs.existsSync(libPath)) { + await downloadFile(lib.downloads.artifact.url, libPath); + } + } + } + + callbacks?.onProgress?.({ stage: 'downloading', current: 3, total: 3, message: 'Installation complete' }); + + return { version, gamePath }; +} + +export async function installModLoader( + mcVersion: string, + gamePath: string, + loaderType: 'forge' | 'fabric' | 'quilt' | 'neoforge', + loaderVersion?: string, + javaPath?: string, + callbacks?: { onProgress?: (progress: DownloadProgress) => void } +): Promise<{ loaderType: string; mcVersion: string; loaderVersion: string }> { + callbacks?.onProgress?.({ stage: 'installing', current: 0, total: 100, message: `Installing ${loaderType}...` }); + + // Placeholder: actual implementation depends on loader type + // This would call the appropriate installer for Forge/Fabric/Quilt/NeoForge + + callbacks?.onProgress?.({ stage: 'installing', current: 100, total: 100, message: `${loaderType} installed` }); + + return { + loaderType, + mcVersion, + loaderVersion: loaderVersion || 'latest', + }; +} diff --git a/electron/core/instance.js b/electron/core/instance.js new file mode 100644 index 0000000..69fd345 --- /dev/null +++ b/electron/core/instance.js @@ -0,0 +1,138 @@ +"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 }); +exports.createInstance = createInstance; +exports.listInstances = listInstances; +exports.deleteInstance = deleteInstance; +exports.getInstanceInfo = getInstanceInfo; +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +const INSTANCE_CONFIG_FILE = 'koring-instance.json'; +function getInstanceConfigPath(instancePath) { + return path.join(instancePath, INSTANCE_CONFIG_FILE); +} +async function createInstance(name, gamePath, mcVersion, loaderType, loaderVersion, javaPath, memory) { + const instancePath = path.join(gamePath, 'instances', name); + if (!fs.existsSync(instancePath)) { + fs.mkdirSync(instancePath, { recursive: true }); + } + const config = { + name, + mcVersion, + loaderType, + loaderVersion, + javaPath, + memory, + createdAt: new Date().toISOString(), + }; + const configPath = getInstanceConfigPath(instancePath); + fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8'); + // Create mods directory + const modsDir = path.join(instancePath, 'mods'); + if (!fs.existsSync(modsDir)) { + fs.mkdirSync(modsDir, { recursive: true }); + } + // Count mods + const mods = fs.readdirSync(modsDir).filter((f) => f.endsWith('.jar')); + return { + name, + path: instancePath, + config, + modCount: mods.length, + }; +} +async function listInstances(instancesPath) { + const instances = []; + if (!fs.existsSync(instancesPath)) { + return instances; + } + const entries = fs.readdirSync(instancesPath, { withFileTypes: true }); + for (const entry of entries) { + if (!entry.isDirectory()) + continue; + const instancePath = path.join(instancesPath, entry.name); + const configPath = getInstanceConfigPath(instancePath); + if (!fs.existsSync(configPath)) + continue; + try { + const configRaw = fs.readFileSync(configPath, 'utf-8'); + const config = JSON.parse(configRaw); + // Count mods + const modsDir = path.join(instancePath, 'mods'); + let modCount = 0; + if (fs.existsSync(modsDir)) { + modCount = fs.readdirSync(modsDir).filter((f) => f.endsWith('.jar')).length; + } + instances.push({ + name: entry.name, + path: instancePath, + config, + modCount, + }); + } + catch { + // Skip invalid config + } + } + return instances; +} +async function deleteInstance(name, instancesPath) { + const instancePath = path.join(instancesPath, name); + if (fs.existsSync(instancePath)) { + fs.rmSync(instancePath, { recursive: true, force: true }); + } + return { deleted: name }; +} +async function getInstanceInfo(name, instancesPath) { + const instancePath = path.join(instancesPath, name); + const configPath = getInstanceConfigPath(instancePath); + if (!fs.existsSync(configPath)) { + throw new Error(`Instance not found: ${name}`); + } + const configRaw = fs.readFileSync(configPath, 'utf-8'); + const config = JSON.parse(configRaw); + // Count mods + const modsDir = path.join(instancePath, 'mods'); + let modCount = 0; + if (fs.existsSync(modsDir)) { + modCount = fs.readdirSync(modsDir).filter((f) => f.endsWith('.jar')).length; + } + return { + name, + path: instancePath, + config, + modCount, + }; +} diff --git a/electron/core/instance.ts b/electron/core/instance.ts new file mode 100644 index 0000000..c2a7936 --- /dev/null +++ b/electron/core/instance.ts @@ -0,0 +1,154 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +interface InstanceConfig { + name: string; + mcVersion: string; + loaderType?: string; + loaderVersion?: string; + javaPath?: string; + memory?: { min?: string; max?: string }; + createdAt: string; +} + +interface InstanceInfo { + name: string; + path: string; + config: InstanceConfig; + modCount?: number; +} + +const INSTANCE_CONFIG_FILE = 'koring-instance.json'; + +function getInstanceConfigPath(instancePath: string): string { + return path.join(instancePath, INSTANCE_CONFIG_FILE); +} + +export async function createInstance( + name: string, + gamePath: string, + mcVersion: string, + loaderType?: string, + loaderVersion?: string, + javaPath?: string, + memory?: { min?: string; max?: string } +): Promise { + const instancePath = path.join(gamePath, 'instances', name); + + if (!fs.existsSync(instancePath)) { + fs.mkdirSync(instancePath, { recursive: true }); + } + + const config: InstanceConfig = { + name, + mcVersion, + loaderType, + loaderVersion, + javaPath, + memory, + createdAt: new Date().toISOString(), + }; + + const configPath = getInstanceConfigPath(instancePath); + fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8'); + + // Create mods directory + const modsDir = path.join(instancePath, 'mods'); + if (!fs.existsSync(modsDir)) { + fs.mkdirSync(modsDir, { recursive: true }); + } + + // Count mods + const mods = fs.readdirSync(modsDir).filter((f) => f.endsWith('.jar')); + + return { + name, + path: instancePath, + config, + modCount: mods.length, + }; +} + +export async function listInstances(instancesPath: string): Promise { + const instances: InstanceInfo[] = []; + + if (!fs.existsSync(instancesPath)) { + return instances; + } + + const entries = fs.readdirSync(instancesPath, { withFileTypes: true }); + + for (const entry of entries) { + if (!entry.isDirectory()) continue; + + const instancePath = path.join(instancesPath, entry.name); + const configPath = getInstanceConfigPath(instancePath); + + if (!fs.existsSync(configPath)) continue; + + try { + const configRaw = fs.readFileSync(configPath, 'utf-8'); + const config = JSON.parse(configRaw) as InstanceConfig; + + // Count mods + const modsDir = path.join(instancePath, 'mods'); + let modCount = 0; + if (fs.existsSync(modsDir)) { + modCount = fs.readdirSync(modsDir).filter((f) => f.endsWith('.jar')).length; + } + + instances.push({ + name: entry.name, + path: instancePath, + config, + modCount, + }); + } catch { + // Skip invalid config + } + } + + return instances; +} + +export async function deleteInstance( + name: string, + instancesPath: string +): Promise<{ deleted: string }> { + const instancePath = path.join(instancesPath, name); + + if (fs.existsSync(instancePath)) { + fs.rmSync(instancePath, { recursive: true, force: true }); + } + + return { deleted: name }; +} + +export async function getInstanceInfo( + name: string, + instancesPath: string +): Promise { + const instancePath = path.join(instancesPath, name); + const configPath = getInstanceConfigPath(instancePath); + + if (!fs.existsSync(configPath)) { + throw new Error(`Instance not found: ${name}`); + } + + const configRaw = fs.readFileSync(configPath, 'utf-8'); + const config = JSON.parse(configRaw) as InstanceConfig; + + // Count mods + const modsDir = path.join(instancePath, 'mods'); + let modCount = 0; + if (fs.existsSync(modsDir)) { + modCount = fs.readdirSync(modsDir).filter((f) => f.endsWith('.jar')).length; + } + + return { + name, + path: instancePath, + config, + modCount, + }; +} diff --git a/electron/core/launcher.js b/electron/core/launcher.js new file mode 100644 index 0000000..611c54f --- /dev/null +++ b/electron/core/launcher.js @@ -0,0 +1,152 @@ +"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 }); +exports.launchMinecraft = launchMinecraft; +exports.diagnoseVersion = diagnoseVersion; +const child_process_1 = require("child_process"); +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +const runningProcesses = new Map(); +async function launchMinecraft(options) { + const versionJsonPath = path.join(options.gamePath, 'versions', options.version, `${options.version}.json`); + if (!fs.existsSync(versionJsonPath)) { + throw new Error(`Version JSON not found: ${versionJsonPath}`); + } + const versionJson = JSON.parse(fs.readFileSync(versionJsonPath, 'utf-8')); + const mainClass = versionJson.mainClass; + if (!mainClass) { + throw new Error('Main class not found in version JSON'); + } + const args = []; + // Memory + const minMem = options.memory?.min || '512M'; + const maxMem = options.memory?.max || '4G'; + args.push(`-Xms${minMem}`); + args.push(`-Xmx${maxMem}`); + // JVM args + if (options.jvmArgs) { + args.push(...options.jvmArgs); + } + // Native libraries path + const nativesDir = path.join(options.gamePath, 'versions', options.version, `${options.version}-natives`); + if (fs.existsSync(nativesDir)) { + args.push(`-Djava.library.path=${nativesDir}`); + } + // Classpath + const libraries = versionJson.libraries || []; + const classpath = libraries + .filter((lib) => lib.downloads?.artifact?.path) + .map((lib) => path.join(options.gamePath, 'libraries', lib.downloads.artifact.path)); + const clientJar = path.join(options.gamePath, 'versions', options.version, `${options.version}.jar`); + if (fs.existsSync(clientJar)) { + classpath.push(clientJar); + } + args.push('-cp'); + args.push(classpath.join(path.delimiter)); + args.push(mainClass); + // Game args + args.push(`--username`, options.username); + args.push(`--version`, options.version); + args.push(`--gameDir`, options.gamePath); + args.push(`--assetsDir`, path.join(options.gamePath, 'assets')); + args.push(`--assetIndex`, versionJson.assetIndex?.id || options.version); + args.push(`--uuid`, options.uuid); + if (options.accessToken) { + args.push(`--accessToken`, options.accessToken); + } + if (options.server) { + args.push(`--server`, options.server.ip); + if (options.server.port) { + args.push(`--port`, String(options.server.port)); + } + } + if (options.gameArgs) { + args.push(...options.gameArgs); + } + const javaPath = options.javaPath || 'java'; + return new Promise((resolve, reject) => { + const child = (0, child_process_1.spawn)(javaPath, args, { + cwd: options.gamePath, + detached: options.detached, + stdio: ['ignore', 'pipe', 'pipe'], + }); + const requestId = `mc-${Date.now()}`; + runningProcesses.set(requestId, child); + child.stdout?.on('data', (data) => { + const line = data.toString().trim(); + if (line) { + options.onEvent?.({ event: 'stdout', message: line }); + } + }); + child.stderr?.on('data', (data) => { + const line = data.toString().trim(); + if (line) { + options.onEvent?.({ event: 'stderr', message: line }); + } + }); + child.on('error', (err) => { + runningProcesses.delete(requestId); + options.onEvent?.({ event: 'error', error: String(err) }); + reject(err); + }); + child.on('exit', (code) => { + runningProcesses.delete(requestId); + options.onEvent?.({ event: 'exit', code }); + }); + resolve({ + pid: child.pid || 0, + version: options.version, + username: options.username, + }); + }); +} +async function diagnoseVersion(gamePath, version) { + const issues = []; + const versionDir = path.join(gamePath, 'versions', version); + const versionJsonPath = path.join(versionDir, `${version}.json`); + const jarPath = path.join(versionDir, `${version}.jar`); + if (!fs.existsSync(versionJsonPath)) { + issues.push(`Version JSON not found: ${versionJsonPath}`); + } + if (!fs.existsSync(jarPath)) { + issues.push(`Client JAR not found: ${jarPath}`); + } + return { + version, + gamePath, + healthy: issues.length === 0, + issues, + }; +} diff --git a/electron/core/launcher.ts b/electron/core/launcher.ts new file mode 100644 index 0000000..d9d783f --- /dev/null +++ b/electron/core/launcher.ts @@ -0,0 +1,165 @@ +import { spawn, ChildProcess } from 'child_process'; +import * as fs from 'fs'; +import * as path from 'path'; + +interface LaunchOptions { + gamePath: string; + javaPath: string; + version: string; + username: string; + uuid: string; + accessToken?: string; + memory?: { min?: string; max?: string }; + jvmArgs?: string[]; + gameArgs?: string[]; + server?: { ip: string; port?: number }; + detached?: boolean; + onEvent?: (event: { event: string; [key: string]: unknown }) => void; +} + +interface LaunchResult { + pid: number; + version: string; + username: string; +} + +const runningProcesses = new Map(); + +export async function launchMinecraft(options: LaunchOptions): Promise { + const versionJsonPath = path.join(options.gamePath, 'versions', options.version, `${options.version}.json`); + + if (!fs.existsSync(versionJsonPath)) { + throw new Error(`Version JSON not found: ${versionJsonPath}`); + } + + const versionJson = JSON.parse(fs.readFileSync(versionJsonPath, 'utf-8')); + const mainClass = versionJson.mainClass; + + if (!mainClass) { + throw new Error('Main class not found in version JSON'); + } + + const args: string[] = []; + + // Memory + const minMem = options.memory?.min || '512M'; + const maxMem = options.memory?.max || '4G'; + args.push(`-Xms${minMem}`); + args.push(`-Xmx${maxMem}`); + + // JVM args + if (options.jvmArgs) { + args.push(...options.jvmArgs); + } + + // Native libraries path + const nativesDir = path.join(options.gamePath, 'versions', options.version, `${options.version}-natives`); + if (fs.existsSync(nativesDir)) { + args.push(`-Djava.library.path=${nativesDir}`); + } + + // Classpath + const libraries = versionJson.libraries || []; + const classpath = libraries + .filter((lib: { downloads?: { artifact?: { path: string } } }) => lib.downloads?.artifact?.path) + .map((lib: { downloads: { artifact: { path: string } } }) => path.join(options.gamePath, 'libraries', lib.downloads.artifact.path)); + + const clientJar = path.join(options.gamePath, 'versions', options.version, `${options.version}.jar`); + if (fs.existsSync(clientJar)) { + classpath.push(clientJar); + } + + args.push('-cp'); + args.push(classpath.join(path.delimiter)); + + args.push(mainClass); + + // Game args + args.push(`--username`, options.username); + args.push(`--version`, options.version); + args.push(`--gameDir`, options.gamePath); + args.push(`--assetsDir`, path.join(options.gamePath, 'assets')); + args.push(`--assetIndex`, versionJson.assetIndex?.id || options.version); + args.push(`--uuid`, options.uuid); + + if (options.accessToken) { + args.push(`--accessToken`, options.accessToken); + } + + if (options.server) { + args.push(`--server`, options.server.ip); + if (options.server.port) { + args.push(`--port`, String(options.server.port)); + } + } + + if (options.gameArgs) { + args.push(...options.gameArgs); + } + + const javaPath = options.javaPath || 'java'; + + return new Promise((resolve, reject) => { + const child = spawn(javaPath, args, { + cwd: options.gamePath, + detached: options.detached, + stdio: ['ignore', 'pipe', 'pipe'], + }); + + const requestId = `mc-${Date.now()}`; + runningProcesses.set(requestId, child); + + child.stdout?.on('data', (data) => { + const line = data.toString().trim(); + if (line) { + options.onEvent?.({ event: 'stdout', message: line }); + } + }); + + child.stderr?.on('data', (data) => { + const line = data.toString().trim(); + if (line) { + options.onEvent?.({ event: 'stderr', message: line }); + } + }); + + child.on('error', (err) => { + runningProcesses.delete(requestId); + options.onEvent?.({ event: 'error', error: String(err) }); + reject(err); + }); + + child.on('exit', (code) => { + runningProcesses.delete(requestId); + options.onEvent?.({ event: 'exit', code }); + }); + + resolve({ + pid: child.pid || 0, + version: options.version, + username: options.username, + }); + }); +} + +export async function diagnoseVersion(gamePath: string, version: string): Promise> { + const issues: string[] = []; + const versionDir = path.join(gamePath, 'versions', version); + const versionJsonPath = path.join(versionDir, `${version}.json`); + const jarPath = path.join(versionDir, `${version}.jar`); + + if (!fs.existsSync(versionJsonPath)) { + issues.push(`Version JSON not found: ${versionJsonPath}`); + } + + if (!fs.existsSync(jarPath)) { + issues.push(`Client JAR not found: ${jarPath}`); + } + + return { + version, + gamePath, + healthy: issues.length === 0, + issues, + }; +} diff --git a/electron/core/modrinth.js b/electron/core/modrinth.js new file mode 100644 index 0000000..161a0b3 --- /dev/null +++ b/electron/core/modrinth.js @@ -0,0 +1,163 @@ +"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; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.searchMods = searchMods; +exports.getModDetail = getModDetail; +exports.getModVersions = getModVersions; +exports.installMod = installMod; +const electron_1 = __importDefault(require("electron")); +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +const { net } = electron_1.default; +const MODRINTH_API = 'https://api.modrinth.com/v2'; +const CURSEFORGE_API = 'https://api.curseforge.com/v1'; +async function searchModrinth(query, gameVersion, loader, limit = 20, offset = 0) { + const facets = []; + if (gameVersion) + facets.push([`versions:${gameVersion}`]); + if (loader) + facets.push([`categories:${loader}`]); + const params = new URLSearchParams({ + query: query || '', + limit: String(limit), + offset: String(offset), + }); + if (facets.length > 0) { + params.set('facets', JSON.stringify(facets)); + } + const response = await net.fetch(`${MODRINTH_API}/search?${params.toString()}`); + if (!response.ok) + throw new Error(`Modrinth search failed: ${response.status}`); + const data = await response.json(); + return data.hits.map((hit) => ({ + id: hit.project_id, + slug: hit.slug, + name: hit.title, + description: hit.description, + downloads: hit.downloads, + iconUrl: hit.icon_url, + categories: hit.categories, + versions: hit.versions, + source: 'modrinth', + })); +} +async function searchCurseForge(query, gameVersion, loader, limit = 20, offset = 0) { + // CurseForge requires API key - return empty for now + return []; +} +async function searchMods(query, gameVersion, loader, limit, offset, source = 'modrinth') { + if (source === 'modrinth') { + return searchModrinth(query, gameVersion, loader, limit, offset); + } + return searchCurseForge(query, gameVersion, loader, limit, offset); +} +async function getModDetail(projectId, source = 'modrinth') { + if (source === 'modrinth') { + const response = await net.fetch(`${MODRINTH_API}/project/${projectId}`); + if (!response.ok) + throw new Error(`Modrinth detail failed: ${response.status}`); + const data = await response.json(); + return { + id: data.id, + slug: data.slug, + name: data.title, + description: data.description, + downloads: data.downloads, + iconUrl: data.icon_url, + categories: data.categories, + versions: data.versions, + source: 'modrinth', + }; + } + throw new Error(`CurseForge detail not implemented`); +} +async function getModVersions(projectId, gameVersion, loader, source = 'modrinth') { + if (source === 'modrinth') { + const params = new URLSearchParams(); + if (gameVersion) + params.set('game_versions', JSON.stringify([gameVersion])); + if (loader) + params.set('loaders', JSON.stringify([loader])); + const response = await net.fetch(`${MODRINTH_API}/project/${projectId}/version?${params.toString()}`); + if (!response.ok) + throw new Error(`Modrinth versions failed: ${response.status}`); + const data = await response.json(); + return data.map((v) => ({ + id: v.id, + name: v.name, + versionNumber: v.version_number, + gameVersions: v.game_versions, + loaders: v.loaders, + files: v.files.map((f) => ({ + filename: f.filename, + url: f.url, + size: f.size, + primary: f.primary, + })), + })); + } + throw new Error(`CurseForge versions not implemented`); +} +async function installMod(projectId, versionId, gamePath, source = 'modrinth') { + const versions = await getModVersions(projectId, undefined, undefined, source); + const targetVersion = versionId + ? versions.find((v) => v.id === versionId) + : versions[0]; + if (!targetVersion) + throw new Error('No version found'); + const primaryFile = targetVersion.files.find((f) => f.primary) || targetVersion.files[0]; + if (!primaryFile) + throw new Error('No file found'); + // Download the mod file + const modsDir = path.join(gamePath, 'mods'); + if (!fs.existsSync(modsDir)) { + fs.mkdirSync(modsDir, { recursive: true }); + } + const filePath = path.join(modsDir, primaryFile.filename); + const response = await net.fetch(primaryFile.url); + if (!response.ok) + throw new Error(`Download failed: ${response.status}`); + const buffer = Buffer.from(await response.arrayBuffer()); + fs.writeFileSync(filePath, buffer); + return { + projectId, + versionId: targetVersion.id, + filename: primaryFile.filename, + path: filePath, + }; +} diff --git a/electron/core/modrinth.ts b/electron/core/modrinth.ts new file mode 100644 index 0000000..a1689f2 --- /dev/null +++ b/electron/core/modrinth.ts @@ -0,0 +1,228 @@ +import electron from 'electron'; +import * as fs from 'fs'; +import * as path from 'path'; + +const { net } = electron; + +const MODRINTH_API = 'https://api.modrinth.com/v2'; +const CURSEFORGE_API = 'https://api.curseforge.com/v1'; + +interface ModSearchResult { + id: string; + slug: string; + name: string; + description: string; + downloads: number; + iconUrl?: string; + categories?: string[]; + versions?: string[]; + loaders?: string[]; + source: 'modrinth' | 'curseforge'; +} + +interface ModVersionResult { + id: string; + name: string; + versionNumber: string; + gameVersions: string[]; + loaders: string[]; + files: { + filename: string; + url: string; + size: number; + primary: boolean; + }[]; +} + +async function searchModrinth( + query?: string, + gameVersion?: string, + loader?: string, + limit: number = 20, + offset: number = 0 +): Promise { + const facets: string[][] = []; + if (gameVersion) facets.push([`versions:${gameVersion}`]); + if (loader) facets.push([`categories:${loader}`]); + + const params = new URLSearchParams({ + query: query || '', + limit: String(limit), + offset: String(offset), + }); + + if (facets.length > 0) { + params.set('facets', JSON.stringify(facets)); + } + + const response = await net.fetch(`${MODRINTH_API}/search?${params.toString()}`); + if (!response.ok) throw new Error(`Modrinth search failed: ${response.status}`); + + const data = await response.json() as { hits: Array<{ + project_id: string; + slug: string; + title: string; + description: string; + downloads: number; + icon_url?: string; + categories?: string[]; + versions?: string[]; + client_side?: string; + server_side?: string; + }> }; + + return data.hits.map((hit) => ({ + id: hit.project_id, + slug: hit.slug, + name: hit.title, + description: hit.description, + downloads: hit.downloads, + iconUrl: hit.icon_url, + categories: hit.categories, + versions: hit.versions, + source: 'modrinth' as const, + })); +} + +async function searchCurseForge( + query?: string, + gameVersion?: string, + loader?: string, + limit: number = 20, + offset: number = 0 +): Promise { + // CurseForge requires API key - return empty for now + return []; +} + +export async function searchMods( + query?: string, + gameVersion?: string, + loader?: string, + limit?: number, + offset?: number, + source: 'modrinth' | 'curseforge' = 'modrinth' +): Promise { + if (source === 'modrinth') { + return searchModrinth(query, gameVersion, loader, limit, offset); + } + return searchCurseForge(query, gameVersion, loader, limit, offset); +} + +export async function getModDetail( + projectId: string, + source: 'modrinth' | 'curseforge' = 'modrinth' +): Promise { + if (source === 'modrinth') { + const response = await net.fetch(`${MODRINTH_API}/project/${projectId}`); + if (!response.ok) throw new Error(`Modrinth detail failed: ${response.status}`); + + const data = await response.json() as { + id: string; + slug: string; + title: string; + description: string; + downloads: number; + icon_url?: string; + categories?: string[]; + versions?: string[]; + }; + + return { + id: data.id, + slug: data.slug, + name: data.title, + description: data.description, + downloads: data.downloads, + iconUrl: data.icon_url, + categories: data.categories, + versions: data.versions, + source: 'modrinth', + }; + } + + throw new Error(`CurseForge detail not implemented`); +} + +export async function getModVersions( + projectId: string, + gameVersion?: string, + loader?: string, + source: 'modrinth' | 'curseforge' = 'modrinth' +): Promise { + if (source === 'modrinth') { + const params = new URLSearchParams(); + if (gameVersion) params.set('game_versions', JSON.stringify([gameVersion])); + if (loader) params.set('loaders', JSON.stringify([loader])); + + const response = await net.fetch(`${MODRINTH_API}/project/${projectId}/version?${params.toString()}`); + if (!response.ok) throw new Error(`Modrinth versions failed: ${response.status}`); + + const data = await response.json() as Array<{ + id: string; + name: string; + version_number: string; + game_versions: string[]; + loaders: string[]; + files: Array<{ + filename: string; + url: string; + size: number; + primary: boolean; + }>; + }>; + + return data.map((v) => ({ + id: v.id, + name: v.name, + versionNumber: v.version_number, + gameVersions: v.game_versions, + loaders: v.loaders, + files: v.files.map((f) => ({ + filename: f.filename, + url: f.url, + size: f.size, + primary: f.primary, + })), + })); + } + + throw new Error(`CurseForge versions not implemented`); +} + +export async function installMod( + projectId: string, + versionId: string | undefined, + gamePath: string, + source: 'modrinth' | 'curseforge' = 'modrinth' +): Promise<{ projectId: string; versionId: string; filename: string; path: string }> { + const versions = await getModVersions(projectId, undefined, undefined, source); + const targetVersion = versionId + ? versions.find((v) => v.id === versionId) + : versions[0]; + + if (!targetVersion) throw new Error('No version found'); + + const primaryFile = targetVersion.files.find((f) => f.primary) || targetVersion.files[0]; + if (!primaryFile) throw new Error('No file found'); + + // Download the mod file + const modsDir = path.join(gamePath, 'mods'); + if (!fs.existsSync(modsDir)) { + fs.mkdirSync(modsDir, { recursive: true }); + } + + const filePath = path.join(modsDir, primaryFile.filename); + const response = await net.fetch(primaryFile.url); + if (!response.ok) throw new Error(`Download failed: ${response.status}`); + + const buffer = Buffer.from(await response.arrayBuffer()); + fs.writeFileSync(filePath, buffer); + + return { + projectId, + versionId: targetVersion.id, + filename: primaryFile.filename, + path: filePath, + }; +} diff --git a/electron/handlers/auth.js b/electron/handlers/auth.js new file mode 100644 index 0000000..d778a7e --- /dev/null +++ b/electron/handlers/auth.js @@ -0,0 +1,38 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerAuthHandlers = registerAuthHandlers; +const electron_1 = __importDefault(require("electron")); +const { ipcMain } = electron_1.default; +const auth_1 = require("../auth"); +function registerAuthHandlers() { + ipcMain.handle('auth:get', () => { + try { + const auth = (0, auth_1.readAuth)(); + return { success: true, data: auth, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('auth:save', (_event, auth) => { + try { + (0, auth_1.writeAuth)(auth); + return { success: true, data: null, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('auth:delete', () => { + try { + (0, auth_1.deleteAuth)(); + return { success: true, data: null, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/auth.ts b/electron/handlers/auth.ts new file mode 100644 index 0000000..0c9eb09 --- /dev/null +++ b/electron/handlers/auth.ts @@ -0,0 +1,32 @@ +import electron from 'electron'; +const { ipcMain } = electron; +import { readAuth, writeAuth, deleteAuth } from '../auth'; + +export function registerAuthHandlers() { + ipcMain.handle('auth:get', () => { + try { + const auth = readAuth(); + return { success: true, data: auth, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('auth:save', (_event, auth) => { + try { + writeAuth(auth); + return { success: true, data: null, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('auth:delete', () => { + try { + deleteAuth(); + return { success: true, data: null, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/background.js b/electron/handlers/background.js new file mode 100644 index 0000000..2474591 --- /dev/null +++ b/electron/handlers/background.js @@ -0,0 +1,101 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerBackgroundHandlers = registerBackgroundHandlers; +const electron_1 = __importDefault(require("electron")); +const config_1 = require("../config"); +const { ipcMain } = electron_1.default; +function registerBackgroundHandlers() { + ipcMain.handle('background:set-image', async (_event, payload) => { + try { + const config = (0, config_1.loadConfig)(); + config.background.bgType = 'image'; + config.background.image = payload.url; + if (payload.blur !== undefined) + config.background.blur = payload.blur; + if (payload.opacity !== undefined) + config.background.opacity = payload.opacity; + (0, config_1.saveConfig)(config); + return { success: true, data: config.background, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('background:set-color', async (_event, payload) => { + try { + const config = (0, config_1.loadConfig)(); + config.background.bgType = 'color'; + config.background.image = payload.color; + (0, config_1.saveConfig)(config); + return { success: true, data: config.background, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('background:set-blur', async (_event, payload) => { + try { + const config = (0, config_1.loadConfig)(); + config.background.blur = payload.blur; + (0, config_1.saveConfig)(config); + return { success: true, data: config.background, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('background:set-opacity', async (_event, payload) => { + try { + const config = (0, config_1.loadConfig)(); + config.background.opacity = payload.opacity; + (0, config_1.saveConfig)(config); + return { success: true, data: config.background, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('background:set-animation', async (_event, payload) => { + try { + // Animation config is not persisted in current design, return defaults + return { success: true, data: { bgType: 'image', image: '/background.png', blur: 0, opacity: 100 }, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('background:get', async () => { + try { + const config = (0, config_1.loadConfig)(); + return { success: true, data: config.background, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('background:set-theme', async (_event, payload) => { + try { + const config = (0, config_1.loadConfig)(); + config.theme.darkMode = payload.theme; + (0, config_1.saveConfig)(config); + return { success: true, data: config.background, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('background:reset', async () => { + try { + const config = (0, config_1.loadConfig)(); + config.background = { bgType: 'image', image: '/background.png', blur: 0, opacity: 100 }; + (0, config_1.saveConfig)(config); + return { success: true, data: config.background, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/background.ts b/electron/handlers/background.ts new file mode 100644 index 0000000..8daf544 --- /dev/null +++ b/electron/handlers/background.ts @@ -0,0 +1,94 @@ +import electron from 'electron'; +import { loadConfig, saveConfig } from '../config'; + +const { ipcMain } = electron; + +export function registerBackgroundHandlers() { + ipcMain.handle('background:set-image', async (_event, payload: { url: string; blur?: number; opacity?: number }) => { + try { + const config = loadConfig(); + config.background.bgType = 'image'; + config.background.image = payload.url; + if (payload.blur !== undefined) config.background.blur = payload.blur; + if (payload.opacity !== undefined) config.background.opacity = payload.opacity; + saveConfig(config); + return { success: true, data: config.background, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('background:set-color', async (_event, payload: { color: string }) => { + try { + const config = loadConfig(); + config.background.bgType = 'color'; + config.background.image = payload.color; + saveConfig(config); + return { success: true, data: config.background, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('background:set-blur', async (_event, payload: { blur: number }) => { + try { + const config = loadConfig(); + config.background.blur = payload.blur; + saveConfig(config); + return { success: true, data: config.background, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('background:set-opacity', async (_event, payload: { opacity: number }) => { + try { + const config = loadConfig(); + config.background.opacity = payload.opacity; + saveConfig(config); + return { success: true, data: config.background, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('background:set-animation', async (_event, payload: { type: string; speed?: number }) => { + try { + // Animation config is not persisted in current design, return defaults + return { success: true, data: { bgType: 'image', image: '/background.png', blur: 0, opacity: 100 }, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('background:get', async () => { + try { + const config = loadConfig(); + return { success: true, data: config.background, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('background:set-theme', async (_event, payload: { theme: string }) => { + try { + const config = loadConfig(); + config.theme.darkMode = payload.theme; + saveConfig(config); + return { success: true, data: config.background, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('background:reset', async () => { + try { + const config = loadConfig(); + config.background = { bgType: 'image', image: '/background.png', blur: 0, opacity: 100 }; + saveConfig(config); + return { success: true, data: config.background, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/config.js b/electron/handlers/config.js new file mode 100644 index 0000000..9bdb6c5 --- /dev/null +++ b/electron/handlers/config.js @@ -0,0 +1,29 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerConfigHandlers = registerConfigHandlers; +const electron_1 = __importDefault(require("electron")); +const { ipcMain } = electron_1.default; +const config_1 = require("../config"); +function registerConfigHandlers() { + ipcMain.handle('config:get', () => { + try { + const config = (0, config_1.loadConfig)(); + return { success: true, data: config, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('config:save', (_event, config) => { + try { + (0, config_1.saveConfig)(config); + return { success: true, data: null, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/config.ts b/electron/handlers/config.ts new file mode 100644 index 0000000..403b24f --- /dev/null +++ b/electron/handlers/config.ts @@ -0,0 +1,23 @@ +import electron from 'electron'; +const { ipcMain } = electron; +import { loadConfig, saveConfig, type AppConfig } from '../config'; + +export function registerConfigHandlers() { + ipcMain.handle('config:get', () => { + try { + const config = loadConfig(); + return { success: true, data: config, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('config:save', (_event, config: AppConfig) => { + try { + saveConfig(config); + return { success: true, data: null, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/install.js b/electron/handlers/install.js new file mode 100644 index 0000000..47f6895 --- /dev/null +++ b/electron/handlers/install.js @@ -0,0 +1,74 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerInstallHandlers = registerInstallHandlers; +const electron_1 = __importDefault(require("electron")); +const installer_1 = require("../core/installer"); +const { ipcMain } = electron_1.default; +function registerInstallHandlers(win) { + ipcMain.handle('install:version-list', async (_event, payload) => { + try { + const data = await (0, installer_1.getVersionList)(payload.type); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('install:forge-version-list', async (_event, payload) => { + try { + const data = await (0, installer_1.getForgeVersions)(payload.mcVersion); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('install:fabric-version-list', async (_event, payload) => { + try { + const data = await (0, installer_1.getFabricVersions)(payload.mcVersion); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('install:minecraft', async (_event, payload) => { + try { + const requestId = `install-mc-${Date.now()}`; + (0, installer_1.installMinecraft)(payload.version, payload.gamePath, payload.javaPath, payload.downloadThreads, { + onProgress: (progress) => { + win.mainWindow?.webContents.send('install:progress', { requestId, ...progress }); + }, + }).then((result) => { + win.mainWindow?.webContents.send('install:complete', { requestId, ...result }); + }).catch((err) => { + win.mainWindow?.webContents.send('install:error', { requestId, error: String(err) }); + }); + return { success: true, data: { requestId }, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('install:mod-loader', async (_event, payload) => { + try { + const requestId = `install-loader-${Date.now()}`; + (0, installer_1.installModLoader)(payload.mcVersion, payload.gamePath, payload.loaderType, payload.loaderVersion, payload.javaPath, { + onProgress: (progress) => { + win.mainWindow?.webContents.send('install:progress', { requestId, ...progress }); + }, + }).then((result) => { + win.mainWindow?.webContents.send('install:complete', { requestId, ...result }); + }).catch((err) => { + win.mainWindow?.webContents.send('install:error', { requestId, error: String(err) }); + }); + return { success: true, data: { requestId }, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/install.ts b/electron/handlers/install.ts new file mode 100644 index 0000000..031de71 --- /dev/null +++ b/electron/handlers/install.ts @@ -0,0 +1,88 @@ +import electron from 'electron'; +import { installMinecraft, installModLoader, getVersionList, getForgeVersions, getFabricVersions } from '../core/installer'; + +const { ipcMain } = electron; + +interface WinRef { + mainWindow: electron.BrowserWindow | null; +} + +export function registerInstallHandlers(win: WinRef) { + ipcMain.handle('install:version-list', async (_event, payload: { type?: string }) => { + try { + const data = await getVersionList(payload.type); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('install:forge-version-list', async (_event, payload: { mcVersion?: string }) => { + try { + const data = await getForgeVersions(payload.mcVersion); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('install:fabric-version-list', async (_event, payload: { mcVersion?: string }) => { + try { + const data = await getFabricVersions(payload.mcVersion); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('install:minecraft', async (_event, payload: { + version: string; + gamePath: string; + javaPath?: string; + downloadThreads?: number; + }) => { + try { + const requestId = `install-mc-${Date.now()}`; + + installMinecraft(payload.version, payload.gamePath, payload.javaPath, payload.downloadThreads, { + onProgress: (progress) => { + win.mainWindow?.webContents.send('install:progress', { requestId, ...progress }); + }, + }).then((result) => { + win.mainWindow?.webContents.send('install:complete', { requestId, ...result }); + }).catch((err) => { + win.mainWindow?.webContents.send('install:error', { requestId, error: String(err) }); + }); + + return { success: true, data: { requestId }, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('install:mod-loader', async (_event, payload: { + mcVersion: string; + gamePath: string; + loaderType: string; + loaderVersion?: string; + javaPath?: string; + }) => { + try { + const requestId = `install-loader-${Date.now()}`; + + installModLoader(payload.mcVersion, payload.gamePath, payload.loaderType as 'forge' | 'fabric' | 'quilt' | 'neoforge', payload.loaderVersion, payload.javaPath, { + onProgress: (progress) => { + win.mainWindow?.webContents.send('install:progress', { requestId, ...progress }); + }, + }).then((result) => { + win.mainWindow?.webContents.send('install:complete', { requestId, ...result }); + }).catch((err) => { + win.mainWindow?.webContents.send('install:error', { requestId, error: String(err) }); + }); + + return { success: true, data: { requestId }, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/instance.js b/electron/handlers/instance.js new file mode 100644 index 0000000..2c24027 --- /dev/null +++ b/electron/handlers/instance.js @@ -0,0 +1,47 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerInstanceHandlers = registerInstanceHandlers; +const electron_1 = __importDefault(require("electron")); +const instance_1 = require("../core/instance"); +const { ipcMain } = electron_1.default; +function registerInstanceHandlers() { + ipcMain.handle('instance:create', async (_event, payload) => { + try { + const data = await (0, instance_1.createInstance)(payload.name, payload.gamePath, payload.mcVersion, payload.loaderType, payload.loaderVersion, payload.javaPath, payload.memory); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('instance:list', async (_event, payload) => { + try { + const data = await (0, instance_1.listInstances)(payload.instancesPath); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('instance:delete', async (_event, payload) => { + try { + const data = await (0, instance_1.deleteInstance)(payload.name, payload.instancesPath); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('instance:info', async (_event, payload) => { + try { + const data = await (0, instance_1.getInstanceInfo)(payload.name, payload.instancesPath); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/instance.ts b/electron/handlers/instance.ts new file mode 100644 index 0000000..d82c182 --- /dev/null +++ b/electron/handlers/instance.ts @@ -0,0 +1,58 @@ +import electron from 'electron'; +import { createInstance, listInstances, deleteInstance, getInstanceInfo } from '../core/instance'; + +const { ipcMain } = electron; + +export function registerInstanceHandlers() { + ipcMain.handle('instance:create', async (_event, payload: { + name: string; + gamePath: string; + mcVersion: string; + loaderType?: string; + loaderVersion?: string; + javaPath?: string; + memory?: { min?: string; max?: string }; + }) => { + try { + const data = await createInstance( + payload.name, + payload.gamePath, + payload.mcVersion, + payload.loaderType, + payload.loaderVersion, + payload.javaPath, + payload.memory + ); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('instance:list', async (_event, payload: { instancesPath: string }) => { + try { + const data = await listInstances(payload.instancesPath); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('instance:delete', async (_event, payload: { name: string; instancesPath: string }) => { + try { + const data = await deleteInstance(payload.name, payload.instancesPath); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('instance:info', async (_event, payload: { name: string; instancesPath: string }) => { + try { + const data = await getInstanceInfo(payload.name, payload.instancesPath); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/launch.js b/electron/handlers/launch.js new file mode 100644 index 0000000..16d29ca --- /dev/null +++ b/electron/handlers/launch.js @@ -0,0 +1,45 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerLaunchHandlers = registerLaunchHandlers; +const electron_1 = __importDefault(require("electron")); +const launcher_1 = require("../core/launcher"); +const { ipcMain } = electron_1.default; +function registerLaunchHandlers(win) { + ipcMain.handle('launch:launch', async (_event, payload) => { + try { + const requestId = `launch-${Date.now()}`; + const result = await (0, launcher_1.launchMinecraft)({ + gamePath: payload.gamePath, + javaPath: payload.javaPath, + version: payload.version, + username: payload.username, + uuid: payload.uuid, + accessToken: payload.accessToken, + memory: payload.memory, + jvmArgs: payload.jvmArgs, + gameArgs: payload.gameArgs, + server: payload.server, + detached: payload.detached, + onEvent: (event) => { + win.mainWindow?.webContents.send('launch:event', { requestId, ...event }); + }, + }); + return { success: true, data: { ...result, requestId }, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('launch:diagnose', async (_event, payload) => { + try { + const data = await (0, launcher_1.diagnoseVersion)(payload.gamePath, payload.version); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/launch.ts b/electron/handlers/launch.ts new file mode 100644 index 0000000..30f1b80 --- /dev/null +++ b/electron/handlers/launch.ts @@ -0,0 +1,58 @@ +import electron from 'electron'; +import { launchMinecraft, diagnoseVersion } from '../core/launcher'; + +const { ipcMain } = electron; + +interface WinRef { + mainWindow: electron.BrowserWindow | null; +} + +export function registerLaunchHandlers(win: WinRef) { + ipcMain.handle('launch:launch', async (_event, payload: { + gamePath: string; + javaPath: string; + version: string; + username: string; + uuid: string; + accessToken?: string; + memory?: { min?: string; max?: string }; + jvmArgs?: string[]; + gameArgs?: string[]; + server?: { ip: string; port?: number }; + detached?: boolean; + }) => { + try { + const requestId = `launch-${Date.now()}`; + + const result = await launchMinecraft({ + gamePath: payload.gamePath, + javaPath: payload.javaPath, + version: payload.version, + username: payload.username, + uuid: payload.uuid, + accessToken: payload.accessToken, + memory: payload.memory, + jvmArgs: payload.jvmArgs, + gameArgs: payload.gameArgs, + server: payload.server, + detached: payload.detached, + onEvent: (event) => { + win.mainWindow?.webContents.send('launch:event', { requestId, ...event }); + }, + }); + + return { success: true, data: { ...result, requestId }, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('launch:diagnose', async (_event, payload: { gamePath: string; version: string }) => { + try { + const data = await diagnoseVersion(payload.gamePath, payload.version); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/mods.js b/electron/handlers/mods.js new file mode 100644 index 0000000..9b8bd8e --- /dev/null +++ b/electron/handlers/mods.js @@ -0,0 +1,47 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerModsHandlers = registerModsHandlers; +const electron_1 = __importDefault(require("electron")); +const modrinth_1 = require("../core/modrinth"); +const { ipcMain } = electron_1.default; +function registerModsHandlers() { + ipcMain.handle('mods:search', async (_event, payload) => { + try { + const data = await (0, modrinth_1.searchMods)(payload.query, payload.gameVersion, payload.loader, payload.limit, payload.offset, payload.source); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('mods:detail', async (_event, payload) => { + try { + const data = await (0, modrinth_1.getModDetail)(payload.projectId, payload.source); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('mods:versions', async (_event, payload) => { + try { + const data = await (0, modrinth_1.getModVersions)(payload.projectId, payload.gameVersion, payload.loader, payload.source); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('mods:install', async (_event, payload) => { + try { + const data = await (0, modrinth_1.installMod)(payload.projectId, payload.versionId, payload.gamePath, payload.source); + return { success: true, data, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/mods.ts b/electron/handlers/mods.ts new file mode 100644 index 0000000..2d1f042 --- /dev/null +++ b/electron/handlers/mods.ts @@ -0,0 +1,79 @@ +import electron from 'electron'; +import { searchMods, getModDetail, getModVersions, installMod } from '../core/modrinth'; + +const { ipcMain } = electron; + +export function registerModsHandlers() { + ipcMain.handle('mods:search', async (_event, payload: { + query?: string; + gameVersion?: string; + loader?: string; + limit?: number; + offset?: number; + source: string; + }) => { + try { + const data = await searchMods( + payload.query, + payload.gameVersion, + payload.loader, + payload.limit, + payload.offset, + payload.source as 'modrinth' | 'curseforge' + ); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('mods:detail', async (_event, payload: { projectId: string; source: string }) => { + try { + const data = await getModDetail( + payload.projectId, + payload.source as 'modrinth' | 'curseforge' + ); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('mods:versions', async (_event, payload: { + projectId: string; + gameVersion?: string; + loader?: string; + source: string; + }) => { + try { + const data = await getModVersions( + payload.projectId, + payload.gameVersion, + payload.loader, + payload.source as 'modrinth' | 'curseforge' + ); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('mods:install', async (_event, payload: { + projectId: string; + versionId?: string; + gamePath: string; + source: string; + }) => { + try { + const data = await installMod( + payload.projectId, + payload.versionId, + payload.gamePath, + payload.source as 'modrinth' | 'curseforge' + ); + return { success: true, data, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/system.js b/electron/handlers/system.js new file mode 100644 index 0000000..facd06c --- /dev/null +++ b/electron/handlers/system.js @@ -0,0 +1,70 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerSystemHandlers = registerSystemHandlers; +const electron_1 = __importDefault(require("electron")); +const child_process_1 = require("child_process"); +const { ipcMain, app } = electron_1.default; +function getBiosId() { + if (process.platform !== 'win32') + return 'N/A (non-Windows)'; + try { + const output = (0, child_process_1.execSync)('powershell -NoProfile -Command "(Get-CimInstance Win32_BIOS).SerialNumber"', { + encoding: 'utf-8', + timeout: 5000, + }); + return output.trim() || 'Unknown'; + } + catch { + return 'Unknown'; + } +} +function getOsVersion() { + if (process.platform !== 'win32') + return 'N/A (non-Windows)'; + try { + const output = (0, child_process_1.execSync)('powershell -NoProfile -Command "[System.Environment]::OSVersion.VersionString"', { + encoding: 'utf-8', + timeout: 5000, + }); + return output.trim() || 'Unknown'; + } + catch { + return 'Unknown'; + } +} +function getOsName() { + if (process.platform !== 'win32') + return 'N/A (non-Windows)'; + try { + const output = (0, child_process_1.execSync)('powershell -NoProfile -Command "(Get-CimInstance Win32_OperatingSystem).Caption"', { + encoding: 'utf-8', + timeout: 5000, + }); + return output.trim() || 'Unknown'; + } + catch { + return 'Unknown'; + } +} +function registerSystemHandlers() { + ipcMain.handle('system:info', () => { + try { + return { + success: true, + data: { + app_version: app.getVersion(), + bios_id: getBiosId(), + os_version: getOsVersion(), + os_name: getOsName(), + }, + error: null, + }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/system.ts b/electron/handlers/system.ts new file mode 100644 index 0000000..3edd914 --- /dev/null +++ b/electron/handlers/system.ts @@ -0,0 +1,63 @@ +import electron from 'electron'; +import { execSync } from 'child_process'; +import * as os from 'os'; + +const { ipcMain, app } = electron; + +function getBiosId(): string { + if (process.platform !== 'win32') return 'N/A (non-Windows)'; + try { + const output = execSync('powershell -NoProfile -Command "(Get-CimInstance Win32_BIOS).SerialNumber"', { + encoding: 'utf-8', + timeout: 5000, + }); + return output.trim() || 'Unknown'; + } catch { + return 'Unknown'; + } +} + +function getOsVersion(): string { + if (process.platform !== 'win32') return 'N/A (non-Windows)'; + try { + const output = execSync('powershell -NoProfile -Command "[System.Environment]::OSVersion.VersionString"', { + encoding: 'utf-8', + timeout: 5000, + }); + return output.trim() || 'Unknown'; + } catch { + return 'Unknown'; + } +} + +function getOsName(): string { + if (process.platform !== 'win32') return 'N/A (non-Windows)'; + try { + const output = execSync('powershell -NoProfile -Command "(Get-CimInstance Win32_OperatingSystem).Caption"', { + encoding: 'utf-8', + timeout: 5000, + }); + return output.trim() || 'Unknown'; + } catch { + return 'Unknown'; + } +} + +export function registerSystemHandlers() { + ipcMain.handle('system:info', () => { + try { + return { + success: true, + data: { + app_version: app.getVersion(), + bios_id: getBiosId(), + os_version: getOsVersion(), + os_name: getOsName(), + }, + error: null, + }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/task.js b/electron/handlers/task.js new file mode 100644 index 0000000..29ed1ba --- /dev/null +++ b/electron/handlers/task.js @@ -0,0 +1,61 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerTaskHandlers = registerTaskHandlers; +const electron_1 = __importDefault(require("electron")); +const { ipcMain } = electron_1.default; +const runningTasks = new Map(); +function registerTaskHandlers(win) { + ipcMain.handle('task:start', async (_event, payload) => { + try { + const controller = new AbortController(); + runningTasks.set(payload.taskId, controller); + win.mainWindow?.webContents.send('task:started', { + taskId: payload.taskId, + xmclPath: payload.executorName, + }); + // Simulate task execution + const steps = 20; + for (let i = 0; i <= steps; i++) { + if (controller.signal.aborted) { + win.mainWindow?.webContents.send('task:failed', { + taskId: payload.taskId, + error: 'Task cancelled', + }); + runningTasks.delete(payload.taskId); + return { success: true, data: null, error: null }; + } + win.mainWindow?.webContents.send('task:progress', { + taskId: payload.taskId, + current: i, + total: steps, + stage: `步骤 ${i}/${steps}`, + }); + await new Promise((r) => setTimeout(r, 150)); + } + runningTasks.delete(payload.taskId); + win.mainWindow?.webContents.send('task:completed', { + taskId: payload.taskId, + }); + return { success: true, data: null, error: null }; + } + catch (e) { + runningTasks.delete(payload.taskId); + return { success: false, data: null, error: String(e) }; + } + }); + ipcMain.handle('task:cancel', async (_event, payload) => { + try { + const controller = runningTasks.get(payload.taskId); + if (controller) { + controller.abort(); + } + return { success: true, data: null, error: null }; + } + catch (e) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/task.ts b/electron/handlers/task.ts new file mode 100644 index 0000000..872a472 --- /dev/null +++ b/electron/handlers/task.ts @@ -0,0 +1,74 @@ +import electron from 'electron'; + +const { ipcMain } = electron; + +const runningTasks = new Map(); + +interface WinRef { + mainWindow: electron.BrowserWindow | null; +} + +export function registerTaskHandlers(win: WinRef) { + ipcMain.handle('task:start', async (_event, payload: { + taskId: string; + type: string; + title: string; + description?: string; + executorName: string; + params?: Record; + }) => { + try { + const controller = new AbortController(); + runningTasks.set(payload.taskId, controller); + + win.mainWindow?.webContents.send('task:started', { + taskId: payload.taskId, + xmclPath: payload.executorName, + }); + + // Simulate task execution + const steps = 20; + for (let i = 0; i <= steps; i++) { + if (controller.signal.aborted) { + win.mainWindow?.webContents.send('task:failed', { + taskId: payload.taskId, + error: 'Task cancelled', + }); + runningTasks.delete(payload.taskId); + return { success: true, data: null, error: null }; + } + + win.mainWindow?.webContents.send('task:progress', { + taskId: payload.taskId, + current: i, + total: steps, + stage: `步骤 ${i}/${steps}`, + }); + + await new Promise((r) => setTimeout(r, 150)); + } + + runningTasks.delete(payload.taskId); + win.mainWindow?.webContents.send('task:completed', { + taskId: payload.taskId, + }); + + return { success: true, data: null, error: null }; + } catch (e: unknown) { + runningTasks.delete(payload.taskId); + return { success: false, data: null, error: String(e) }; + } + }); + + ipcMain.handle('task:cancel', async (_event, payload: { taskId: string }) => { + try { + const controller = runningTasks.get(payload.taskId); + if (controller) { + controller.abort(); + } + return { success: true, data: null, error: null }; + } catch (e: unknown) { + return { success: false, data: null, error: String(e) }; + } + }); +} diff --git a/electron/handlers/window.js b/electron/handlers/window.js new file mode 100644 index 0000000..bf7b6bd --- /dev/null +++ b/electron/handlers/window.js @@ -0,0 +1,80 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerWindowHandlers = registerWindowHandlers; +const electron_1 = __importDefault(require("electron")); +const path_1 = __importDefault(require("path")); +const { ipcMain, dialog } = electron_1.default; +const isDev = !electron_1.default.app.isPackaged; +function createSplashWindow() { + const splash = new electron_1.default.BrowserWindow({ + width: 480, + height: 320, + transparent: true, + frame: false, + resizable: false, + skipTaskbar: true, + alwaysOnTop: true, + webPreferences: { + nodeIntegration: false, + contextIsolation: true, + }, + }); + if (isDev) { + splash.loadURL('http://localhost:1420/splash.html'); + } + else { + splash.loadFile(path_1.default.join(__dirname, '../dist/splash.html')); + } + return splash; +} +function registerWindowHandlers(win) { + ipcMain.handle('window:minimize', () => { + win.mainWindow?.minimize(); + }); + ipcMain.handle('window:maximize', () => { + if (win.mainWindow?.isMaximized()) { + win.mainWindow.unmaximize(); + } + else { + win.mainWindow?.maximize(); + } + }); + ipcMain.handle('window:close', () => { + win.mainWindow?.close(); + }); + ipcMain.handle('window:isMaximized', () => { + return win.mainWindow?.isMaximized() ?? false; + }); + ipcMain.handle('window:getTheme', () => { + return win.mainWindow?.themeSource ?? null; + }); + // Splash window management + ipcMain.handle('window:openSplash', () => { + if (win.splashWindow && !win.splashWindow.isDestroyed()) { + win.splashWindow.focus(); + return { success: true }; + } + win.splashWindow = createSplashWindow(); + return { success: true }; + }); + ipcMain.handle('window:closeSplash', () => { + if (win.splashWindow && !win.splashWindow.isDestroyed()) { + win.splashWindow.close(); + win.splashWindow = null; + } + return { success: true }; + }); + // File dialog + ipcMain.handle('dialog:openFile', async (_event, payload) => { + const result = await dialog.showOpenDialog(win.mainWindow, { + properties: ['openFile'], + filters: payload.filters, + }); + if (result.canceled || result.filePaths.length === 0) + return null; + return result.filePaths[0]; + }); +} diff --git a/electron/handlers/window.ts b/electron/handlers/window.ts new file mode 100644 index 0000000..2b07d6a --- /dev/null +++ b/electron/handlers/window.ts @@ -0,0 +1,91 @@ +import electron from 'electron'; +import path from 'path'; + +const { ipcMain, dialog } = electron; + +const isDev = !electron.app.isPackaged; + +interface WinRef { + mainWindow: electron.BrowserWindow | null; + splashWindow: electron.BrowserWindow | null; +} + +function createSplashWindow(): electron.BrowserWindow { + const splash = new electron.BrowserWindow({ + width: 480, + height: 320, + transparent: true, + frame: false, + resizable: false, + skipTaskbar: true, + alwaysOnTop: true, + webPreferences: { + nodeIntegration: false, + contextIsolation: true, + }, + }); + + if (isDev) { + splash.loadURL('http://localhost:1420/splash.html'); + } else { + splash.loadFile(path.join(__dirname, '../dist/splash.html')); + } + + return splash; +} + +export function registerWindowHandlers(win: WinRef) { + ipcMain.handle('window:minimize', () => { + win.mainWindow?.minimize(); + }); + + ipcMain.handle('window:maximize', () => { + if (win.mainWindow?.isMaximized()) { + win.mainWindow.unmaximize(); + } else { + win.mainWindow?.maximize(); + } + }); + + ipcMain.handle('window:close', () => { + win.mainWindow?.close(); + }); + + ipcMain.handle('window:isMaximized', () => { + return win.mainWindow?.isMaximized() ?? false; + }); + + ipcMain.handle('window:getTheme', () => { + return (win.mainWindow as any)?.themeSource ?? null; + }); + + // Splash window management + ipcMain.handle('window:openSplash', () => { + if (win.splashWindow && !win.splashWindow.isDestroyed()) { + win.splashWindow.focus(); + return { success: true }; + } + win.splashWindow = createSplashWindow(); + return { success: true }; + }); + + ipcMain.handle('window:closeSplash', () => { + if (win.splashWindow && !win.splashWindow.isDestroyed()) { + win.splashWindow.close(); + win.splashWindow = null; + } + return { success: true }; + }); + + // File dialog + ipcMain.handle('dialog:openFile', async (_event, payload: { + filters?: { name: string; extensions: string[] }[]; + }) => { + const result = await dialog.showOpenDialog(win.mainWindow!, { + properties: ['openFile'], + filters: payload.filters, + }); + if (result.canceled || result.filePaths.length === 0) return null; + return result.filePaths[0]; + }); +} diff --git a/electron/main.ts b/electron/main.ts new file mode 100644 index 0000000..f822a11 --- /dev/null +++ b/electron/main.ts @@ -0,0 +1,142 @@ +import electron from 'electron'; +import path from 'path'; +import { registerConfigHandlers } from './handlers/config'; +import { registerAuthHandlers } from './handlers/auth'; +import { registerInstallHandlers } from './handlers/install'; +import { registerLaunchHandlers } from './handlers/launch'; +import { registerModsHandlers } from './handlers/mods'; +import { registerInstanceHandlers } from './handlers/instance'; +import { registerBackgroundHandlers } from './handlers/background'; +import { registerTaskHandlers } from './handlers/task'; +import { registerSystemHandlers } from './handlers/system'; +import { registerWindowHandlers } from './handlers/window'; + +const { app } = electron; + +const isDev = !app.isPackaged; + +// Mutable ref — handlers always read from this +const win: { mainWindow: electron.BrowserWindow | null; splashWindow: electron.BrowserWindow | null } = { + mainWindow: null, + splashWindow: null, +}; + +function createSplashWindow(): electron.BrowserWindow { + const splash = new electron.BrowserWindow({ + width: 480, + height: 320, + transparent: true, + frame: false, + resizable: false, + skipTaskbar: true, + alwaysOnTop: true, + webPreferences: { + nodeIntegration: false, + contextIsolation: true, + }, + }); + + if (isDev) { + splash.loadURL('http://localhost:1420/splash.html'); + } else { + splash.loadFile(path.join(__dirname, '../dist/splash.html')); + } + + return splash; +} + +function createMainWindow(): electron.BrowserWindow { + const main = new electron.BrowserWindow({ + width: 1000, + height: 700, + minWidth: 800, + minHeight: 600, + transparent: true, + frame: false, + resizable: true, + show: false, + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + nodeIntegration: false, + contextIsolation: true, + sandbox: false, + }, + }); + + if (isDev) { + main.loadURL('http://localhost:1420'); + } else { + main.loadFile(path.join(__dirname, '../dist/index.html')); + } + + main.on('maximize', () => { + main.webContents.send('window:resized'); + }); + + main.on('unmaximize', () => { + main.webContents.send('window:resized'); + }); + + return main; +} + +function registerAllHandlers() { + registerConfigHandlers(); + registerAuthHandlers(); + registerInstallHandlers(win); + registerLaunchHandlers(win); + registerModsHandlers(); + registerInstanceHandlers(); + registerBackgroundHandlers(); + registerTaskHandlers(win); + registerSystemHandlers(); + registerWindowHandlers(win); +} + +app.whenReady().then(() => { + registerAllHandlers(); + + // 1. Show splash immediately + win.splashWindow = createSplashWindow(); + + // 2. Create main window in background + win.mainWindow = createMainWindow(); + + // 3. When main window finishes loading, wait a minimum time then transition + let mainReady = false; + let splashMinTimeDone = false; + + const tryTransition = () => { + if (mainReady && splashMinTimeDone) { + if (win.mainWindow && !win.mainWindow.isDestroyed()) { + win.mainWindow.show(); + win.mainWindow.focus(); + } + if (win.splashWindow && !win.splashWindow.isDestroyed()) { + win.splashWindow.close(); + win.splashWindow = null; + } + } + }; + + win.mainWindow.once('ready-to-show', () => { + mainReady = true; + tryTransition(); + }); + + // Minimum splash display time (1.5s) + setTimeout(() => { + splashMinTimeDone = true; + tryTransition(); + }, 1500); +}); + +app.on('window-all-closed', () => { + app.quit(); +}); + +app.on('activate', () => { + if (electron.BrowserWindow.getAllWindows().length === 0) { + win.mainWindow = createMainWindow(); + } +}); diff --git a/electron/preload.ts b/electron/preload.ts new file mode 100644 index 0000000..56e9513 --- /dev/null +++ b/electron/preload.ts @@ -0,0 +1,31 @@ +import electron from 'electron'; +const { contextBridge, ipcRenderer } = electron; + +contextBridge.exposeInMainWorld('electronAPI', { + // Generic IPC + invoke: (channel: string, ...args: unknown[]) => + ipcRenderer.invoke(channel, ...args), + + on: (channel: string, callback: (...args: unknown[]) => void) => { + const handler = (_event: Electron.IpcRendererEvent, ...args: unknown[]) => callback(...args); + ipcRenderer.on(channel, handler); + return () => ipcRenderer.removeListener(channel, handler); + }, + + send: (channel: string, ...args: unknown[]) => + ipcRenderer.send(channel, ...args), + + // Window controls + minimize: () => ipcRenderer.invoke('window:minimize'), + maximize: () => ipcRenderer.invoke('window:maximize'), + close: () => ipcRenderer.invoke('window:close'), + isMaximized: () => ipcRenderer.invoke('window:isMaximized'), + onResized: (callback: () => void) => { + const handler = () => callback(); + ipcRenderer.on('window:resized', handler); + return () => ipcRenderer.removeListener('window:resized', handler); + }, + + // Theme + getTheme: () => ipcRenderer.invoke('window:getTheme'), +}); diff --git a/index.html b/index.html index ff93803..ffbdde2 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - Tauri + React + Typescript + Koring Launcher diff --git a/opencode.json b/opencode.json new file mode 100644 index 0000000..b4f91be --- /dev/null +++ b/opencode.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "shadcn": { + "type": "local", + "command": [ + "npx", + "shadcn@latest", + "mcp" + ], + "enabled": true + } + } +} diff --git a/package.json b/package.json index 8c616bf..bc6ffc0 100644 --- a/package.json +++ b/package.json @@ -1,53 +1,65 @@ { "name": "koring-launcher", "private": true, - "version": "0.1.0", - "type": "module", + "version": "1.0.0", + "description": "Koring Launcher - Minecraft launcher built with Electron + React", + "author": "Lingke Koring Studio", + "main": "electron/main.js", "scripts": { + "dev:renderer": "vite --mode development", + "dev:main": "tsc -p tsconfig.electron.json && electron .", + "dev": "pnpm build:main && concurrently \"pnpm dev:renderer\" \"electron .\"", + "build:renderer": "vite build --mode production", + "build:main": "tsc -p tsconfig.electron.json", + "build": "pnpm build:renderer && pnpm build:main", + "preview": "vite preview", "icon:dev": "node scripts/switch-icon.js dev", "icon:beta": "node scripts/switch-icon.js beta", "icon:run": "node scripts/switch-icon.js run", - "dev": "node scripts/switch-icon.js dev && vite --mode development", - "build": "node scripts/switch-icon.js run && tsc && vite build --mode production", - "build:beta": "node scripts/switch-icon.js beta && tsc && vite build --mode beta", - "preview": "vite preview", - "tauri": "tauri", - "dev:t": "node scripts/switch-icon.js dev && tauri dev", - "dev:vs": "./dev-vs.cmd", - "build:vs": "./build-vs.cmd", - "build:beta:vs": "./build-vs.cmd --mode beta" + "pack": "electron-builder --dir", + "dist": "electron-builder", + "dist:win": "electron-builder --win", + "dist:mac": "electron-builder --mac", + "dist:linux": "electron-builder --linux", + "dist:dev": "pnpm icon:dev && electron-builder --win", + "dist:beta": "pnpm icon:beta && electron-builder --win", + "dist:run": "pnpm icon:run && electron-builder --win" }, "dependencies": { "@base-ui/react": "^1.6.0", "@fontsource-variable/geist": "^5.2.9", "@fontsource-variable/inter": "^5.2.8", "@react-three/fiber": "^9.6.1", - "@tauri-apps/api": "^2", - "@tauri-apps/plugin-dialog": "^2.7.1", - "@tauri-apps/plugin-fs": "^2.5.1", - "@tauri-apps/plugin-opener": "^2", - "@tauri-apps/plugin-process": "^2.3.1", - "@tauri-apps/plugin-shell": "^2.3.5", - "@tauri-apps/plugin-updater": "^2.10.1", "@types/three": "^0.184.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "js-yaml": "^4.1.0", "lucide-react": "^1.21.0", "react": "^19.1.0", "react-dom": "^19.1.0", - "shadcn": "^4.11.0", "tailwind-merge": "^3.6.0", "three": "^0.184.0", "tw-animate-css": "^1.4.0", "zustand": "^5.0.14" }, + "pnpm": { + "onlyBuiltDependencies": [ + "electron", + "esbuild" + ] + }, "devDependencies": { "@tailwindcss/vite": "^4.3.1", - "@tauri-apps/cli": "^2", + "@types/js-yaml": "^4.0.9", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", "@vitejs/plugin-react": "^4.6.0", + "concurrently": "^9.1.0", + "electron": "^33.0.0", + "electron-builder": "^25.1.8", + "shadcn": "^4.11.0", "tailwindcss": "^4.3.1", + "tsx": "^4.19.0", "typescript": "~5.8.3", "vite": "^7.0.4" } diff --git a/plans/tauri-to-electron.md b/plans/tauri-to-electron.md new file mode 100644 index 0000000..15a2135 --- /dev/null +++ b/plans/tauri-to-electron.md @@ -0,0 +1,419 @@ +# 迁移计划:Tauri 2 → Electron + +## 概述 + +将 koring-launcher 从 Tauri 2(Rust 后端 + Node.js sidecar)迁移到 Electron(Node.js 主进程)。sidecar 的 @xmcl/* 包直接集成到 Electron 主进程中,不再需要独立的 sidecar 二进制文件和 stdin/stdout IPC。 + +--- + +## 架构变更 + +### 迁移前(Tauri) +``` +前端 (React) ←→ Rust (Tauri) ←→ Sidecar (Node.js/@xmcl) + ↕ invoke() ↕ spawn stdin/stdout + ↕ listen events ↕ emit events +``` + +### 迁移后(Electron) +``` +前端 (React) ←→ Electron 主进程 (Node.js/@xmcl) + ↕ ipcRenderer.invoke() ↕ ipcMain.handle() + ↕ ipcRenderer.on() ↕ webContents.send() +``` + +Rust 后端和 sidecar **完全移除**。所有功能都在 Electron 主进程中以 `ipcMain.handle()` 处理器的形式存在。 + +--- + +## 阶段一:项目初始化 + +### 1.1 初始化 Electron + +- [ ] 在项目根目录创建 `electron/` 目录 +- [ ] 创建 `electron/main.ts`(Electron 主进程入口) +- [ ] 创建 `electron/preload.ts`(context bridge 用于 IPC) +- [ ] 更新根目录 `package.json`: + - 移除 `@tauri-apps/api`、`@tauri-apps/plugin-*` + - 添加 `electron`、`electron-builder`、`electron-vite` + - 添加 `electron-store`(用于配置/认证持久化) + - 添加 `electron-updater`(用于自动更新) + - 更新脚本:`dev`、`build`、`build:win`、`build:mac`、`build:linux` +- [ ] 创建 `electron-builder.yml` 用于打包配置 +- [ ] 更新 `vite.config.ts` 兼容 Electron(移除 Tauri 相关配置) + +### 1.2 清理 Tauri 相关文件 + +- [ ] 完全删除 `src-tauri/` 目录 +- [ ] 完全删除 `sidecar/` 目录 +- [ ] 删除 `.tauri/` 签名密钥 +- [ ] 删除 `build-all.cmd`、`build-arch.cmd`、`build-vs.cmd`、`dev-vs.cmd` +- [ ] 删除 `scripts/switch-icon.js` +- [ ] 清理 `package.json` 脚本(移除所有 tauri 相关脚本) +- [ ] 更新 `.gitignore` 移除 Tauri 相关条目 + +--- + +## 阶段二:Electron 主进程 + +### 2.1 主进程入口(`electron/main.ts`) + +```typescript +import { app, BrowserWindow, ipcMain, dialog } from 'electron'; +import path from 'path'; + +// 窗口管理 +// Splash → Main 过渡(4秒计时器) +// 单实例锁定 +// 应用生命周期事件 +``` + +核心职责: +- 创建 splash 窗口(480x320,透明,无边框) +- 创建主窗口(1000x700,透明,无边框,初始隐藏) +- 4秒后关闭 splash,显示主窗口 +- 处理应用退出(终止所有运行中的 MC 进程) + +### 2.2 IPC 处理器 + +将所有 16 个 Tauri 命令替换为 `ipcMain.handle()`: + +| Tauri 命令 | Electron IPC 频道 | 说明 | +|---|---|---| +| `sidecar_request` | ❌ **已移除** | 不再需要,直接调用具体处理器 | +| `install_minecraft` | `install:minecraft` | 直接使用 @xmcl/installer | +| `install_mod_loader` | `install:mod-loader` | 直接使用 @xmcl/installer | +| `get_version_list` | `install:version-list` | 直接使用 @xmcl/installer | +| `launch_game` | `launch:launch` | 直接使用 @xmcl/core | +| `offline_login` | `auth:offline-login` | 直接使用 @xmcl/user | +| `search_mods` | `mods:search` | 直接使用 @xmcl/modrinth | +| `install_mod` | `mods:install` | 直接使用 @xmcl/modrinth | +| `create_instance` | `instance:create` | 直接文件 I/O | +| `list_instances` | `instance:list` | 直接文件 I/O | +| `get_config` | `config:get` | electron-store 或 YAML 文件 | +| `save_config` | `config:save` | electron-store 或 YAML 文件 | +| `get_auth` | `auth:get` | electron-store(替代注册表) | +| `save_auth` | `auth:save` | electron-store(替代注册表) | +| `delete_auth_cmd` | `auth:delete` | electron-store | +| `get_system_info` | `system:info` | `process.versions`、`os` 模块 | + +**新增频道**(替代 sidecar 事件转发): +- `install:progress` → `webContents.send('install:progress', data)` +- `install:complete` → `webContents.send('install:complete', data)` +- `launch:events` → `webContents.send('launch:events', data)` +- `task:progress` → `webContents.send('task:progress', data)` +- `task:completed` → `webContents.send('task:completed', data)` + +### 2.3 配置系统(`electron/config.ts`) + +从 Rust `config.rs` 迁移到 Node.js: +- 保持 YAML 格式(使用 `js-yaml` 库) +- 保持稀疏保存逻辑(与默认值做 diff,只保存非默认值) +- 存储路径:打包后使用 `app.getPath('exe')` 父目录 + +### 2.4 认证系统(`electron/auth.ts`) + +从 Windows 注册表迁移到 `electron-store`: +- 使用 `electron-store` 存储认证数据(跨平台 JSON) +- 可选使用 `safeStorage` 加密 + +### 2.5 Sidecar → 主进程集成 + +将所有 sidecar 模块直接移入主进程: +- `electron/core/auth.ts` ← `sidecar/src/core/auth.ts`(Microsoft OAuth、离线登录) +- `electron/core/installer.ts` ← `sidecar/src/core/installer.ts`(@xmcl/installer) +- `electron/core/launcher.ts` ← `sidecar/src/core/launcher.ts`(@xmcl/core) +- `electron/core/modrinth.ts` ← `sidecar/src/core/modrinth.ts`(Mod API) +- `electron/handlers/` ← `sidecar/src/handlers/`(将 stdin/stdout 改为 IPC) +- `electron/utils/paths.ts` ← `sidecar/src/utils/paths.ts` + +**关键变更**:sidecar 使用 `sendResult(id, data)` / `sendProgress(id, data)` 通过 stdout 发送。现在改用 `webContents.send(channel, data)` 直接发送。 + +### 2.6 窗口管理 + +替换 Tauri 窗口 API: +- `@tauri-apps/api/window` → Electron `BrowserWindow` 方法 +- 自定义标题栏:移除 `data-tauri-drag-region`,改用 CSS `-webkit-app-region: drag` 实现无边框窗口拖拽 +- 窗口控制按钮:`ipcRenderer.invoke('window:minimize')`、`ipcRenderer.invoke('window:maximize')`、`ipcRenderer.invoke('window:close')` + +--- + +## 阶段三:前端迁移 + +### 3.1 API 层重写 + +**`src/api/sidecar.ts`** → `src/api/ipc.ts`: +- 替换 `invoke("sidecar_request", ...)` 为 `window.electronAPI.invoke('channel', payload)` +- 替换 `listen("sidecar-response", ...)` 为 `window.electronAPI.on('channel', callback)` +- 移除基于 requestId 的事件过滤(每个 IPC 频道是独立的) + +**`src/api/config.ts`**: +- `invoke("get_config")` → `window.electronAPI.invoke('config:get')` +- `invoke("save_config", { cfg })` → `window.electronAPI.invoke('config:save', config)` + +**`src/api/auth-registry.ts`**: +- `invoke("get_auth")` → `window.electronAPI.invoke('auth:get')` +- `invoke("save_auth", { auth })` → `window.electronAPI.invoke('auth:save', auth)` +- `invoke("delete_auth_cmd")` → `window.electronAPI.invoke('auth:delete')` + +**`src/api/update.ts`**: +- 替换 `@tauri-apps/plugin-updater` → `electron-updater` +- `checkForUpdates()` → `window.electronAPI.invoke('update:check')` +- `downloadAndInstall()` → `window.electronAPI.invoke('update:install')` +- `relaunchApp()` → `window.electronAPI.invoke('app:relaunch')` + +**`src/api/system.ts`**: +- `invoke("get_system_info")` → `window.electronAPI.invoke('system:info')` + +### 3.2 移除 Tauri 导入 + +需要更新的文件(移除所有 `@tauri-apps/*` 导入): + +| 文件 | Tauri 导入 | 替换为 | +|---|---|---| +| `src/api/sidecar.ts` | `@tauri-apps/api/core`, `@tauri-apps/api/event` | `window.electronAPI` | +| `src/api/config.ts` | `@tauri-apps/api/core` | `window.electronAPI` | +| `src/api/auth-registry.ts` | `@tauri-apps/api/core` | `window.electronAPI` | +| `src/api/update.ts` | `@tauri-apps/plugin-updater`, `@tauri-apps/plugin-process` | `window.electronAPI` | +| `src/api/system.ts` | `@tauri-apps/api/core` | `window.electronAPI` | +| `src/hooks/useTheme.ts` | `@tauri-apps/api/window` | `window.electronAPI` | +| `src/components/system/WindowControls.tsx` | `@tauri-apps/api/window` | `window.electronAPI` | +| `src/components/system/TitleBar.tsx` | `@tauri-apps/api/window` | `window.electronAPI` | +| `src/components/system/SystemLayer.tsx` | `@tauri-apps/api/window` | `window.electronAPI` | + +### 3.3 Preload 脚本 / Context Bridge + +创建 `electron/preload.ts`: +```typescript +import { contextBridge, ipcRenderer } from 'electron'; + +contextBridge.exposeInMainWorld('electronAPI', { + invoke: (channel: string, ...args: unknown[]) => + ipcRenderer.invoke(channel, ...args), + on: (channel: string, callback: (...args: unknown[]) => void) => { + ipcRenderer.on(channel, (_event, ...args) => callback(...args)); + return () => ipcRenderer.removeListener(channel, callback); + }, + send: (channel: string, ...args: unknown[]) => + ipcRenderer.send(channel, ...args), + + // 窗口控制 + minimize: () => ipcRenderer.invoke('window:minimize'), + maximize: () => ipcRenderer.invoke('window:maximize'), + close: () => ipcRenderer.invoke('window:close'), + isMaximized: () => ipcRenderer.invoke('window:isMaximized'), + onResized: (callback: () => void) => { + ipcRenderer.on('window:resized', callback); + return () => ipcRenderer.removeListener('window:resized', callback); + }, + + // 主题 + getTheme: () => ipcRenderer.invoke('window:getTheme'), +}); +``` + +在 `src/types/electron.d.ts` 中添加 TypeScript 类型声明。 + +### 3.4 窗口控制更新 + +**`src/components/system/WindowControls.tsx`**: +- 移除 `getCurrentWindow()` from `@tauri-apps/api/window` +- 使用 `window.electronAPI.minimize()`、`.maximize()`、`.close()` +- 使用 `window.electronAPI.isMaximized()` 和 `window.electronAPI.onResized()` + +**`src/components/system/TitleBar.tsx`**: +- 移除 `getCurrentWindow()` 拖拽区域 +- 使用 CSS `-webkit-app-region: drag` 实现无边框窗口拖拽 +- 移除 `appWindow.startDragging()` 调用 + +**`src/hooks/useTheme.ts`**: +- 移除 `getCurrentWindow().theme()` from `@tauri-apps/api/window` +- 使用 `window.electronAPI.getTheme()` 替代 +- 保留 `matchMedia` 回退方案 + +### 3.5 Splash 屏幕 + +**`splash.html`**:无需更改(纯 HTML/CSS) +**`src/components/splash/Splash.tsx`**:无需更改(纯 React) + +### 3.6 Vite 配置更新 + +更新 `vite.config.ts`: +- 移除 `ignore` 中的 `src-tauri/` +- 如果使用 `electron-vite`,添加 Electron 特定配置 +- 确保 `base: './'` 以支持 Electron 的 file:// 协议 + +--- + +## 阶段四:构建与打包 + +### 4.1 Electron Builder 配置 + +创建 `electron-builder.yml`: +```yaml +appId: com.lingke.koring.launcher +productName: Koring Launcher +directories: + output: dist-electron +files: + - dist/** # Vite 构建输出 + - electron/** # 主进程代码 +win: + target: nsis + icon: public/run.ico +mac: + target: dmg + icon: public/run.png +linux: + target: AppImage +nsis: + oneClick: false + allowToChangeInstallationDirectory: true +``` + +### 4.2 开发脚本 + +```bash +# 开发 +pnpm dev:renderer # Vite 开发服务器 +pnpm dev:main # electron-vite 启动 Electron +pnpm dev # 同时运行两个(concurrently) + +# 构建 +pnpm build # Vite 构建 + Electron 打包 +pnpm build:win # Windows 安装程序 +``` + +### 4.3 构建模式(dev/beta/run) + +- 保留 `VITE_BUILD_MODE` 环境变量 +- 使用 `electron-builder` 不同配置: + - `electron-builder.dev.yml` — 不签名,不更新 + - `electron-builder.beta.yml` — beta 更新通道 + - `electron-builder.yml` — 正式版 + +--- + +## 阶段五:自动更新 + +将 `@tauri-apps/plugin-updater` 替换为 `electron-updater`: + +### 5.1 主进程 + +```typescript +import { autoUpdater } from 'electron-updater'; + +ipcMain.handle('update:check', async () => { + return autoUpdater.checkForUpdates(); +}); + +ipcMain.handle('update:install', async () => { + autoUpdater.downloadUpdate(); +}); + +autoUpdater.on('update-available', (info) => { + mainWindow.webContents.send('update:available', info); +}); + +autoUpdater.on('download-progress', (progress) => { + mainWindow.webContents.send('update:progress', progress); +}); +``` + +### 5.2 前端 + +```typescript +// src/api/update.ts +export async function checkForUpdates() { + return window.electronAPI.invoke('update:check'); +} + +export function onUpdateAvailable(callback: (info: any) => void) { + return window.electronAPI.on('update:available', callback); +} + +export function onUpdateProgress(callback: (progress: any) => void) { + return window.electronAPI.on('update:progress', callback); +} +``` + +--- + +## 阶段六:测试与清理 + +### 6.1 测试清单 + +- [ ] Splash 屏幕显示 4 秒后主窗口出现 +- [ ] 自定义标题栏正常工作(最小化/最大化/关闭) +- [ ] 无边框窗口拖拽正常 +- [ ] 暗色模式跟随系统同步 +- [ ] 配置正确加载/保存(Koring.yml) +- [ ] 认证正确存储/加载(electron-store) +- [ ] Microsoft OAuth 流程正常(打开浏览器 → 回调) +- [ ] 离线登录正常 +- [ ] Minecraft 安装带进度条正常 +- [ ] 游戏启动带事件流正常 +- [ ] Mod 搜索/安装正常(Modrinth/CurseForge) +- [ ] 实例 创建/列表/删除 正常 +- [ ] 自动更新 检查/下载 正常 +- [ ] 任务队列正常(进度、取消、重试) +- [ ] 构建模式(dev/beta/run)显示正确的图标/徽章 +- [ ] NSIS 安装程序正确构建 +- [ ] 打包后应用正常运行 + +### 6.2 文件清理 + +- [ ] 删除 `src-tauri/` 目录 +- [ ] 删除 `sidecar/` 目录 +- [ ] 删除 `.tauri/` 目录 +- [ ] 删除 `*.cmd` 构建脚本 +- [ ] 删除 `scripts/` 目录 +- [ ] 移除 `.vscode/extensions.json` 中的 `src-tauri` 引用 +- [ ] 更新 `AGENTS.md` 为新的 Electron 架构 +- [ ] 更新 `DEV.md` 为 Electron 开发说明 +- [ ] 更新 `README.md` + +### 6.3 新文件结构 + +``` +koring-launcher/ +├── electron/ # Electron 主进程 +│ ├── main.ts # 主入口 +│ ├── preload.ts # Context bridge +│ ├── config.ts # 配置(YAML)管理 +│ ├── auth.ts # 认证(electron-store)管理 +│ ├── core/ # 从 sidecar 迁移 +│ │ ├── auth.ts # @xmcl/user 认证 +│ │ ├── installer.ts # @xmcl/installer 安装 +│ │ ├── launcher.ts # @xmcl/core 启动 +│ │ └── modrinth.ts # @xmcl/modrinth Mod API +│ ├── handlers/ # IPC 处理器 +│ │ ├── install.ts +│ │ ├── launch.ts +│ │ ├── auth.ts +│ │ ├── mods.ts +│ │ ├── instance.ts +│ │ ├── background.ts +│ │ └── task.ts +│ └── utils/ +│ └── paths.ts +├── src/ # 前端(基本不变) +├── dist/ # Vite 构建输出 +├── electron-builder.yml +├── vite.config.ts +├── package.json +└── index.html +``` + +--- + +## 迁移顺序 + +1. **阶段一** — 项目初始化(Electron 脚手架、移除 Tauri 依赖) +2. **阶段二** — 主进程(IPC 处理器、配置、认证、sidecar 集成) +3. **阶段三** — 前端迁移(API 层、导入、preload bridge) +4. **阶段四** — 构建与打包(electron-builder、开发脚本) +5. **阶段五** — 自动更新(electron-updater) +6. **阶段六** — 测试与清理 + +预计工作量:大规模重构。每个阶段应独立测试后再进入下一阶段。 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a991d21..46384e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,27 +20,6 @@ importers: '@react-three/fiber': specifier: ^9.6.1 version: 9.6.1(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(three@0.184.0) - '@tauri-apps/api': - specifier: ^2 - version: 2.11.1 - '@tauri-apps/plugin-dialog': - specifier: ^2.7.1 - version: 2.7.1 - '@tauri-apps/plugin-fs': - specifier: ^2.5.1 - version: 2.5.1 - '@tauri-apps/plugin-opener': - specifier: ^2 - version: 2.5.4 - '@tauri-apps/plugin-process': - specifier: ^2.3.1 - version: 2.3.1 - '@tauri-apps/plugin-shell': - specifier: ^2.3.5 - version: 2.3.5 - '@tauri-apps/plugin-updater': - specifier: ^2.10.1 - version: 2.10.1 '@types/three': specifier: ^0.184.1 version: 0.184.1 @@ -50,6 +29,9 @@ importers: clsx: specifier: ^2.1.1 version: 2.1.1 + js-yaml: + specifier: ^4.1.0 + version: 4.2.0 lucide-react: specifier: ^1.21.0 version: 1.21.0(react@19.2.7) @@ -59,9 +41,6 @@ importers: react-dom: specifier: ^19.1.0 version: 19.2.7(react@19.2.7) - shadcn: - specifier: ^4.11.0 - version: 4.11.0(typescript@5.8.3) tailwind-merge: specifier: ^3.6.0 version: 3.6.0 @@ -77,10 +56,10 @@ importers: devDependencies: '@tailwindcss/vite': specifier: ^4.3.1 - version: 4.3.1(vite@7.3.5(jiti@2.7.0)(lightningcss@1.32.0)) - '@tauri-apps/cli': - specifier: ^2 - version: 2.11.2 + version: 4.3.1(vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)) + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 '@types/react': specifier: ^19.1.8 version: 19.2.17 @@ -89,19 +68,37 @@ importers: version: 19.2.3(@types/react@19.2.17) '@vitejs/plugin-react': specifier: ^4.6.0 - version: 4.7.0(vite@7.3.5(jiti@2.7.0)(lightningcss@1.32.0)) + version: 4.7.0(vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)) + concurrently: + specifier: ^9.1.0 + version: 9.2.3 + electron: + specifier: ^33.0.0 + version: 33.4.11 + electron-builder: + specifier: ^25.1.8 + version: 25.1.8(electron-builder-squirrel-windows@25.1.8) + shadcn: + specifier: ^4.11.0 + version: 4.11.0(typescript@5.8.3) tailwindcss: specifier: ^4.3.1 version: 4.3.1 + tsx: + specifier: ^4.19.0 + version: 4.22.4 typescript: specifier: ~5.8.3 version: 5.8.3 vite: specifier: ^7.0.4 - version: 7.3.5(jiti@2.7.0)(lightningcss@1.32.0) + version: 7.3.5(@types/node@26.0.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4) packages: + 7zip-bin@5.2.0: + resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==} + '@babel/code-frame@7.29.7': resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} @@ -274,6 +271,10 @@ packages: '@types/react': optional: true + '@develar/schema-utils@2.6.5': + resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==} + engines: {node: '>= 8.9.0'} + '@dimforge/rapier3d-compat@0.12.0': resolution: {integrity: sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==} @@ -287,162 +288,345 @@ packages: peerDependencies: '@noble/ciphers': ^1.0.0 + '@electron/asar@3.4.1': + resolution: {integrity: sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==} + engines: {node: '>=10.12.0'} + hasBin: true + + '@electron/get@2.0.3': + resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==} + engines: {node: '>=12'} + + '@electron/notarize@2.5.0': + resolution: {integrity: sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==} + engines: {node: '>= 10.0.0'} + + '@electron/osx-sign@1.3.1': + resolution: {integrity: sha512-BAfviURMHpmb1Yb50YbCxnOY0wfwaLXH5KJ4+80zS0gUkzDX3ec23naTlEqKsN+PwYn+a1cCzM7BJ4Wcd3sGzw==} + engines: {node: '>=12.0.0'} + hasBin: true + + '@electron/rebuild@3.6.1': + resolution: {integrity: sha512-f6596ZHpEq/YskUd8emYvOUne89ij8mQgjYFA5ru25QwbrRO+t1SImofdDv7kKOuWCmVOuU5tvfkbgGxIl3E/w==} + engines: {node: '>=12.13.0'} + hasBin: true + + '@electron/universal@2.0.1': + resolution: {integrity: sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==} + engines: {node: '>=16.4'} + '@esbuild/aix-ppc64@0.27.7': resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.27.7': resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.27.7': resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.27.7': resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.27.7': resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.27.7': resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.27.7': resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.27.7': resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.27.7': resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.27.7': resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.27.7': resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.27.7': resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.27.7': resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.27.7': resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.27.7': resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.27.7': resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.27.7': resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.27.7': resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.27.7': resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.27.7': resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.27.7': resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.27.7': resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.27.7': resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.27.7': resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.27.7': resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.27.7': resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@floating-ui/core@1.7.5': resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} @@ -464,12 +648,19 @@ packages: '@fontsource-variable/inter@5.2.8': resolution: {integrity: sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==} + '@gar/promisify@1.1.3': + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + '@hono/node-server@1.19.14': resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -486,6 +677,14 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@malept/cross-spawn-promise@2.0.0': + resolution: {integrity: sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==} + engines: {node: '>= 12.13.0'} + + '@malept/flatpak-bundler@0.4.0': + resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} + engines: {node: '>= 10.0.0'} + '@modelcontextprotocol/sdk@1.29.0': resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} engines: {node: '>=18'} @@ -520,6 +719,19 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@npmcli/fs@2.1.2': + resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + '@npmcli/move-file@2.0.1': + resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This functionality has been moved to @npmcli/fs + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@react-three/fiber@9.6.1': resolution: {integrity: sha512-zF0rsKcVYpcJwbFEnv2HkHX9cvOEgsfQo/X8lwmR2dn13S4qEQJXir9fxf5js2LQFoXqxOY7MDkOkYx2uZ4gSg==} peerDependencies: @@ -689,10 +901,18 @@ packages: '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + '@sindresorhus/merge-streams@4.0.0': resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + '@tailwindcss/node@4.3.1': resolution: {integrity: sha512-6NDaqRoAMSXD1mr/RXu0HBvNE9a2n5tHPsxu9XHLws8o4Twes5rBM2205SUUiJ9goAtadrN6xTGX0UDEwp/N4A==} @@ -787,102 +1007,9 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 - '@tauri-apps/api@2.11.1': - resolution: {integrity: sha512-M2FPuYND2m+wh5hfW9ZpSdxMPdEJovPBWwoHJmwUpysTYNHaOkVFN419m/K0LIgjb/7KU2vBgsUepJWugQCvAA==} - - '@tauri-apps/cli-darwin-arm64@2.11.2': - resolution: {integrity: sha512-+4UZzLt+eOAEQCwgd+TqKgyUJMrvx+BgdXLLaqJYmPqzP+nE6YZr/hY6CWLYGQb8jFn99jEkmC6uA3tNvamA1w==} + '@tootallnate/once@2.0.1': + resolution: {integrity: sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ==} engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@tauri-apps/cli-darwin-x64@2.11.2': - resolution: {integrity: sha512-VjYYtZUPqDMLutSfJEyxFE3Bz+DPi7c8wC3imckgvciLDZLq4qwKJxBicg0BXGhXjJsl8vKWgWRFNMPELQ+Xyg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@tauri-apps/cli-linux-arm-gnueabihf@2.11.2': - resolution: {integrity: sha512-yMemD6f4i95AQriS8EazyOFzbE34yjnP16i3IOzpHGQvBoy2DjypFMFBq0NtPuITURv/cOGguRtHR5d79/9CSA==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - - '@tauri-apps/cli-linux-arm64-gnu@2.11.2': - resolution: {integrity: sha512-cgI91D2wL8GSgoWwZXDqt+DwnuZCP2/bz03QAE4TrhgAKIsrB4hX26W/H1EONPUUNkqrsgeCD0wU6pcNjV/5kw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@tauri-apps/cli-linux-arm64-musl@2.11.2': - resolution: {integrity: sha512-X1rm0BERqAAggtYTESSgXrS3sz4Sb/OiPiz54UqISlXW+GkR3vNIGnsy/lejNmoXGVqri3Q53BCfQiclOIyRPw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@tauri-apps/cli-linux-riscv64-gnu@2.11.2': - resolution: {integrity: sha512-usbMLJbT3KtkOrBMDVeGYNM35aTHXx38SJSzTMSqqjeUIOQ+iVPjb2yAGNAE+KqmBbAx4FOFIyMeKXx2M/JKGQ==} - engines: {node: '>= 10'} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@tauri-apps/cli-linux-x64-gnu@2.11.2': - resolution: {integrity: sha512-Ru4gwJKPG0ctVGchRGpRup4Y4lW2SSfFnrbQcyHhCliKy4g8Qz97TrUgCur4CbWyAgKxvGh3SjrkA0LDYzDGiw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@tauri-apps/cli-linux-x64-musl@2.11.2': - resolution: {integrity: sha512-eUm7T6clN1MMmNSRQ9gaWsQdyehQx2Gmn5hht/QUlqZQI/qcP2OJK5dnaxqwFzCr2HdsEo9ydxaqcS1oJzMvUw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@tauri-apps/cli-win32-arm64-msvc@2.11.2': - resolution: {integrity: sha512-HeeZW80jU+gVTOEX4X/hC6NVSAdDVXajwP5fxIZ/3z9WvUC7qrudX2GMTilYq6Dg0e0sk0XgsAJD1hZ5wPBXUA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@tauri-apps/cli-win32-ia32-msvc@2.11.2': - resolution: {integrity: sha512-YhjQNZcXfbkCLyazSv1nPnJ9iRFE1wm6kc51FDbU10/Dk09io+6PAGMLjkxnX2GdM0qMnDmTjstY8mTDVvtKeA==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - - '@tauri-apps/cli-win32-x64-msvc@2.11.2': - resolution: {integrity: sha512-d2JchlFIpZevZVReyqhQOekJmb1UH3rhZ5VX6sH3ty9ETE0TKQavpihvoScUXfKKpW6HZC0MrFGRU0ZtD+w3gA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@tauri-apps/cli@2.11.2': - resolution: {integrity: sha512-bk3HemqvGRoy+5D/dVMUQHKMYLglD0jVnMm/0iGMH6ufZ+p8r14m6BpIixwij3PBvZdvORUp1YifTD8QxVZ1Nw==} - engines: {node: '>= 10'} - hasBin: true - - '@tauri-apps/plugin-dialog@2.7.1': - resolution: {integrity: sha512-OK1UBXYt+ojcmxMktzzuyonYIFta8CmAASpX+CA+DTGK24KlHjhYI6x2iOJ/TjZF4N7/ACK1oFmEOjIY9IhzOQ==} - - '@tauri-apps/plugin-fs@2.5.1': - resolution: {integrity: sha512-9Lz+Jopp6QyeEWhlpkMx4R/+P9HgR+AVAI4vOZhlT8Xaymtz8iVI/Ov984/XTqgJz/5gz5NretqPB/XEMS3NhQ==} - - '@tauri-apps/plugin-opener@2.5.4': - resolution: {integrity: sha512-1HnPkb+AmgO29HBazm4uPLKB+r7zzcTBW1d0fyYp1uP+jwtpoiNDGKMMzz58SFp49nOIrxdE3aUJtT57lfO9CQ==} - - '@tauri-apps/plugin-process@2.3.1': - resolution: {integrity: sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==} - - '@tauri-apps/plugin-shell@2.3.5': - resolution: {integrity: sha512-jewtULhiQ7lI7+owCKAjc8tYLJr92U16bPOeAa472LHJdgaibLP83NcfAF2e+wkEcA53FxKQAZ7byDzs2eeizg==} - - '@tauri-apps/plugin-updater@2.10.1': - resolution: {integrity: sha512-NFYMg+tWOZPJdzE/PpFj2qfqwAWwNS3kXrb1tm1gnBJ9mYzZ4WDRrwy8udzWoAnfGCHLuePNLY1WVCNHnh3eRA==} '@ts-morph/common@0.27.0': resolution: {integrity: sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==} @@ -902,9 +1029,39 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/cacheable-request@6.0.3': + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/fs-extra@9.0.13': + resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} + + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} + + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@20.19.43': + resolution: {integrity: sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==} + + '@types/node@26.0.1': + resolution: {integrity: sha512-fc3KiUoBt6kie0N9bIW3E47vZsuaMf0PM2AaUpLCLT0s/LvX1nxAim6Fc049cNxODPpGm6qRAuUOB86SkRuPQw==} + + '@types/plist@3.0.5': + resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} + '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: @@ -918,6 +1075,9 @@ packages: '@types/react@19.2.17': resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + '@types/stats.js@0.17.4': resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==} @@ -927,23 +1087,48 @@ packages: '@types/validate-npm-package-name@4.0.2': resolution: {integrity: sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==} + '@types/verror@1.10.11': + resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==} + '@types/webxr@0.5.24': resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==} + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + '@vitejs/plugin-react@4.7.0': resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + '@xmldom/xmldom@0.9.10': + resolution: {integrity: sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==} + engines: {node: '>=14.6'} + + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -960,6 +1145,14 @@ packages: ajv: optional: true + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + ajv@8.20.0: resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} @@ -975,17 +1168,80 @@ packages: resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + app-builder-bin@5.0.0-alpha.10: + resolution: {integrity: sha512-Ev4jj3D7Bo+O0GPD2NMvJl+PGiBAfS7pUGawntBNpCbxtpncfUixqFj9z9Jme7V7s3LBGqsWZZP54fxBX3JKJw==} + + app-builder-lib@25.1.8: + resolution: {integrity: sha512-pCqe7dfsQFBABC1jeKZXQWhGcCPF3rPCXDdfqVKjIeWBcXzyC1iOWZdfFhGl+S9MyE/k//DFmC6FzuGAUudNDg==} + engines: {node: '>=14.0.0'} + peerDependencies: + dmg-builder: 25.1.8 + electron-builder-squirrel-windows: 25.1.8 + + aproba@2.1.0: + resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==} + + archiver-utils@2.1.0: + resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} + engines: {node: '>= 6'} + + archiver-utils@3.0.4: + resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} + engines: {node: '>= 10'} + + archiver@5.3.2: + resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} + engines: {node: '>= 10'} + + are-we-there-yet@3.0.1: + resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + ast-types@0.16.1: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + async-exit-hook@2.0.1: + resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==} + engines: {node: '>=0.12.0'} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + atomically@1.7.0: resolution: {integrity: sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==} engines: {node: '>=10.12.0'} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} @@ -998,10 +1254,29 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + bluebird-lst@1.0.9: + resolution: {integrity: sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + body-parser@2.3.0: resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} engines: {node: '>=18'} + boolean@3.2.0: + resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + brace-expansion@1.1.15: + resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} + + brace-expansion@2.1.1: + resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==} + brace-expansion@5.0.6: resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} engines: {node: 18 || 20 || >=22} @@ -1015,9 +1290,25 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + builder-util-runtime@9.2.10: + resolution: {integrity: sha512-6p/gfG1RJSQeIbz8TK5aPNkoztgY1q5TgmGFMAXcY8itsGW6Y2ld1ALsZ5UJn8rog7hKF3zHx5iQbNQ8uLcRlw==} + engines: {node: '>=12.0.0'} + + builder-util@25.1.7: + resolution: {integrity: sha512-7jPjzBwEGRbwNcep0gGNpLXG9P94VA3CPAZQCzxkFXiV2GMQKlziMbY//rXPI7WKfhsvGgFXjTcXdBEwgXw9ww==} + bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} @@ -1026,6 +1317,18 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + cacache@16.1.3: + resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + + cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -1041,13 +1344,36 @@ packages: caniuse-lite@1.0.30001799: resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + chalk@5.6.2: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + chromium-pickle-js@0.2.0: + resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + cli-cursor@5.0.0: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} engines: {node: '>=18'} @@ -1056,6 +1382,21 @@ packages: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} + cli-truncate@2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -1063,6 +1404,21 @@ packages: code-block-writer@13.0.3: resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} @@ -1071,10 +1427,36 @@ packages: resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} engines: {node: '>=20'} + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + compare-version@0.1.2: + resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==} + engines: {node: '>=0.10.0'} + + compress-commons@4.1.2: + resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} + engines: {node: '>= 10'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concurrently@9.2.3: + resolution: {integrity: sha512-ihjs0E2SxvDgq/MK418hX6YycQgKhsqxpbZuZbHo0yKfqDWdymWMjWYIpCIzqDDLLKClHlXev8whW/8WXmJ0BA==} + engines: {node: '>=18'} + hasBin: true + conf@10.2.0: resolution: {integrity: sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==} engines: {node: '>=12'} + config-file-ts@0.2.8-rc1: + resolution: {integrity: sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==} + + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + content-disposition@1.1.0: resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} engines: {node: '>=18'} @@ -1098,6 +1480,12 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.6: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} @@ -1111,6 +1499,18 @@ packages: typescript: optional: true + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@4.0.3: + resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} + engines: {node: '>= 10'} + + crc@3.8.0: + resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -1140,6 +1540,10 @@ packages: supports-color: optional: true + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dedent@1.7.2: resolution: {integrity: sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==} peerDependencies: @@ -1160,6 +1564,17 @@ packages: resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} engines: {node: '>=18'} + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + define-lazy-prop@2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} @@ -1168,6 +1583,17 @@ packages: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -1176,14 +1602,37 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + diff@8.0.4: resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} engines: {node: '>=0.3.1'} + dir-compare@4.2.0: + resolution: {integrity: sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==} + + dmg-builder@25.1.8: + resolution: {integrity: sha512-NoXo6Liy2heSklTI5OIZbCgXC1RzrDQsZkeEwXhdOro3FT1VBOvbubvscdPnjVuQ4AMwwv61oaH96AbiYg9EnQ==} + + dmg-license@1.0.11: + resolution: {integrity: sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==} + engines: {node: '>=8'} + os: [darwin] + hasBin: true + dot-prop@6.0.1: resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} engines: {node: '>=10'} + dotenv-expand@11.0.7: + resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} + engines: {node: '>=12'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + dotenv@17.4.2: resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} engines: {node: '>=12'} @@ -1192,6 +1641,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + eciesjs@0.4.18: resolution: {integrity: sha512-wG99Zcfcys9fZux7Cft8BAX/YrOJLJSZ3jyYPfhZHqN2E+Ffx+QXBDsv3gubEgPtV6dTzJMSQUwk1H98/t/0wQ==} engines: {bun: '>=1', deno: '>=2', node: '>=16'} @@ -1199,16 +1651,49 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-builder-squirrel-windows@25.1.8: + resolution: {integrity: sha512-2ntkJ+9+0GFP6nAISiMabKt6eqBB0kX1QqHNWFWAXgi0VULKGisM46luRFpIBiU3u/TDmhZMM8tzvo2Abn3ayg==} + + electron-builder@25.1.8: + resolution: {integrity: sha512-poRgAtUHHOnlzZnc9PK4nzG53xh74wj2Jy7jkTrqZ0MWPoHGh1M2+C//hGeYdA+4K8w4yiVCNYoLXF7ySj2Wig==} + engines: {node: '>=14.0.0'} + hasBin: true + + electron-publish@25.1.7: + resolution: {integrity: sha512-+jbTkR9m39eDBMP4gfbqglDd6UvBC7RLh5Y0MhFSsc6UkGHj9Vj9TWobxevHYMMqmoujL11ZLjfPpMX+Pt6YEg==} + electron-to-chromium@1.5.376: resolution: {integrity: sha512-cUVA7/RvbFTEuw/i3obUwDTRIXojaxkResf+ibByPFxjc6XK3VNtcQXV0NSbAlJ0FMjcJGgftVVB4Qo184EXvA==} + electron@33.4.11: + resolution: {integrity: sha512-xmdAs5QWRkInC7TpXGNvzo/7exojubk+72jn1oJL7keNeIlw7xNglf8TGtJtkR4rWC5FJq0oXiIXPS9BcK2Irg==} + engines: {node: '>= 12.20.55'} + hasBin: true + emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + enhanced-resolve@5.21.6: resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==} engines: {node: '>=10.13.0'} @@ -1221,6 +1706,9 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} @@ -1236,11 +1724,23 @@ packages: resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} engines: {node: '>= 0.4'} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es6-error@4.1.1: + resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + esbuild@0.27.7: resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} engines: {node: '>=18'} hasBin: true + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1248,6 +1748,10 @@ packages: escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} @@ -1273,6 +1777,9 @@ packages: resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} engines: {node: ^18.19.0 || >=20.5.0} + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + express-rate-limit@8.5.2: resolution: {integrity: sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==} engines: {node: '>= 16'} @@ -1283,6 +1790,15 @@ packages: resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + + extsprintf@1.4.1: + resolution: {integrity: sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==} + engines: {'0': node >=0.6.0} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1290,12 +1806,18 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-uri@3.1.2: resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1316,6 +1838,9 @@ packages: resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} engines: {node: '>=18'} + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1328,6 +1853,14 @@ packages: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} + engines: {node: '>= 6'} + formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -1340,10 +1873,32 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + fs-extra@11.3.5: resolution: {integrity: sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==} engines: {node: '>=14.14'} + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1355,10 +1910,19 @@ packages: fuzzysort@3.1.0: resolution: {integrity: sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==} + gauge@4.0.4: + resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.6.0: resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} @@ -1375,6 +1939,10 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -1387,17 +1955,56 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + global-agent@3.0.0: + resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} + engines: {node: '>=10.0'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + hasown@2.0.4: resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} @@ -1406,10 +2013,33 @@ packages: resolution: {integrity: sha512-uyZtpnYxM9CmQ7QsQknM4zN8EftNqhON1qYeIKM0Se67CCEe2c44xyGURwB0axX2fBDu1dqHrHAc1hmNT8ITkw==} engines: {node: '>=16.9.0'} + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + http-errors@2.0.1: resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -1422,6 +2052,18 @@ packages: resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} engines: {node: '>=18.18.0'} + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + iconv-corefoundation@1.1.7: + resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==} + engines: {node: ^8.11.2 || >=10} + os: [darwin] + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + iconv-lite@0.7.2: resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} engines: {node: '>=0.10.0'} @@ -1437,6 +2079,21 @@ packages: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + infer-owner@1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1451,6 +2108,10 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} @@ -1465,6 +2126,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -1478,10 +2143,17 @@ packages: engines: {node: '>=14.16'} hasBin: true + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + is-interactive@2.0.0: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} + is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -1513,6 +2185,10 @@ packages: resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} engines: {node: '>=18'} + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + is-unicode-supported@1.3.0: resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} engines: {node: '>=12'} @@ -1529,6 +2205,17 @@ packages: resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} engines: {node: '>=16'} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isbinaryfile@4.0.10: + resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} + engines: {node: '>= 8.0.0'} + + isbinaryfile@5.0.7: + resolution: {integrity: sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==} + engines: {node: '>= 18.0.0'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -1541,6 +2228,14 @@ packages: peerDependencies: react: ^19.0.0 + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + engines: {node: '>=10'} + hasBin: true + jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true @@ -1560,9 +2255,15 @@ packages: engines: {node: '>=6'} hasBin: true + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} @@ -1572,14 +2273,23 @@ packages: json-schema-typed@8.0.2: resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.2.1: resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -1588,6 +2298,13 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} + lazy-val@1.0.5: + resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==} + + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -1669,13 +2386,50 @@ packages: resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} engines: {node: '>=6'} + lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + + lodash.difference@4.5.0: + resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + + lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + log-symbols@6.0.0: resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} engines: {node: '>=18'} + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + lucide-react@1.21.0: resolution: {integrity: sha512-reEZMXq8Qdd5jg5XYkQ5TR1fB/GiQ7ih4vcrthYDtgjSDwh0i6/YLiGjsWsIwgN49gpAnd4J2elSNzncMEEUUQ==} peerDependencies: @@ -1684,6 +2438,14 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + make-fetch-happen@10.2.1: + resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + matcher@3.0.0: + resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} + engines: {node: '>=10'} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -1710,14 +2472,27 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mime-types@3.0.2: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -1730,13 +2505,73 @@ packages: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + minimatch@10.2.5: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + + minipass-fetch@2.1.2: + resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + minipass-flush@1.0.7: + resolution: {integrity: sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==} + engines: {node: '>= 8'} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1745,10 +2580,24 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + negotiator@1.0.0: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} + node-abi@3.92.0: + resolution: {integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==} + engines: {node: '>=10'} + + node-addon-api@1.7.2: + resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} + + node-api-version@0.2.1: + resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -1758,10 +2607,28 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-gyp@9.4.1: + resolution: {integrity: sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==} + engines: {node: ^12.13 || ^14.13 || >=16} + hasBin: true + node-releases@2.0.48: resolution: {integrity: sha512-1uz8041X6LoI6ZSdZacM9lVY28vuzDlSKitnpbSNK0RfKoIJkX29NBPVEFXhnuSuEOA9Ww0xnPJ+ILWbGAv8DA==} engines: {node: '>=18'} + nopt@6.0.0: + resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -1770,6 +2637,11 @@ packages: resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} engines: {node: '>=18'} + npmlog@6.0.2: + resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -1778,6 +2650,10 @@ packages: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + object-treeify@1.1.33: resolution: {integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==} engines: {node: '>= 10'} @@ -1805,22 +2681,41 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} + ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + ora@8.2.0: resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} engines: {node: '>=18'} + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + p-locate@3.0.0: resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} engines: {node: '>=6'} + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -1844,6 +2739,10 @@ packages: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -1852,9 +2751,20 @@ packages: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@8.4.2: resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + pe-library@0.4.1: + resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==} + engines: {node: '>=12', npm: '>=6'} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1874,6 +2784,10 @@ packages: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} + plist@3.1.1: + resolution: {integrity: sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==} + engines: {node: '>=10.4.0'} + postcss-selector-parser@7.1.4: resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==} engines: {node: '>=4'} @@ -1890,6 +2804,25 @@ packages: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -1898,6 +2831,13 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + qs@6.15.2: resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} engines: {node: '>=0.6'} @@ -1905,6 +2845,10 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -1935,29 +2879,74 @@ packages: resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} engines: {node: '>=0.10.0'} + read-binary-file-arch@1.0.6: + resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} + hasBin: true + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + recast@0.23.11: resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + resedit@1.7.2: + resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==} + engines: {node: '>=12', npm: '>=6'} + reselect@5.2.0: resolution: {integrity: sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==} + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + restore-cursor@5.1.0: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + roarr@2.15.4: + resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} + engines: {node: '>=8.0'} + rollup@4.62.0: resolution: {integrity: sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -1974,12 +2963,31 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sanitize-filename@1.6.4: + resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==} + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -1993,10 +3001,17 @@ packages: resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} + serialize-error@7.0.1: + resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} + engines: {node: '>=10'} + serve-static@2.2.1: resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} engines: {node: '>= 18'} + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -2012,6 +3027,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shell-quote@1.8.4: + resolution: {integrity: sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==} + engines: {node: '>= 0.4'} + side-channel-list@1.0.1: resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} engines: {node: '>= 0.4'} @@ -2035,17 +3054,51 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + slice-ansi@3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@7.0.0: + resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} + engines: {node: '>= 10'} + + socks@2.8.9: + resolution: {integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + ssri@9.0.1: + resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + stat-mode@1.0.0: + resolution: {integrity: sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==} + engines: {node: '>= 6'} + statuses@2.0.2: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} @@ -2054,10 +3107,24 @@ packages: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-object@5.0.0: resolution: {integrity: sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==} engines: {node: '>=14.16'} @@ -2082,6 +3149,18 @@ packages: resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} engines: {node: '>=18'} + sumchecker@3.0.1: + resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} + engines: {node: '>= 8.0'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + suspend-react@0.1.3: resolution: {integrity: sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==} peerDependencies: @@ -2103,6 +3182,17 @@ packages: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + temp-file@3.4.0: + resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==} + three@0.184.0: resolution: {integrity: sha512-wtTRjG92pM5eUg/KuUnHsqSAlPM296brTOcLgMRqEeylYTh/CdtvKUvCyyCQTzFuStieWxvZb8mVTMvdPyUpxg==} @@ -2113,6 +3203,13 @@ packages: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} + tmp-promise@3.0.3: + resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} + + tmp@0.2.7: + resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} + engines: {node: '>=14.14'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -2121,6 +3218,13 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + truncate-utf8-bytes@1.0.2: + resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} + ts-morph@26.0.0: resolution: {integrity: sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==} @@ -2131,9 +3235,18 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.22.4: + resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==} + engines: {node: '>=18.0.0'} + hasBin: true + tw-animate-css@1.4.0: resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} + type-fest@0.13.1: + resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} + engines: {node: '>=10'} + type-is@2.1.0: resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} engines: {node: '>= 18'} @@ -2143,6 +3256,12 @@ packages: engines: {node: '>=14.17'} hasBin: true + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + undici@7.28.0: resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} engines: {node: '>=20.18.1'} @@ -2151,6 +3270,18 @@ packages: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} + unique-filename@2.0.1: + resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + unique-slug@3.0.0: + resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -2165,11 +3296,17 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-sync-external-store@1.6.0: resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + utf8-byte-length@1.0.5: + resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -2181,6 +3318,10 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + verror@1.10.1: + resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==} + engines: {node: '>=0.6.0'} + vite@7.3.5: resolution: {integrity: sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2221,6 +3362,9 @@ packages: yaml: optional: true + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} @@ -2235,6 +3379,17 @@ packages: engines: {node: ^16.13.0 || >=18.0.0} hasBin: true + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -2242,9 +3397,39 @@ packages: resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} engines: {node: '>=20'} + xmlbuilder@15.1.1: + resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} + engines: {node: '>=8.0'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yargs@17.7.3: + resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} + engines: {node: '>=12'} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + yocto-spinner@1.2.0: resolution: {integrity: sha512-Yw0hUB6UA3o4YUgKy3oSe9a4cxoaZ9sBfYDw+JSxo6Id0KoJGoxzPA24qqUXYKBWABs/zDSGTz9kww7t3F0XGw==} engines: {node: '>=18.19'} @@ -2253,6 +3438,10 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + zip-stream@4.1.1: + resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} + engines: {node: '>= 10'} + zod-to-json-schema@3.25.2: resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} peerDependencies: @@ -2281,6 +3470,8 @@ packages: snapshots: + 7zip-bin@5.2.0: {} + '@babel/code-frame@7.29.7': dependencies: '@babel/helper-validator-identifier': 7.29.7 @@ -2502,6 +3693,11 @@ snapshots: optionalDependencies: '@types/react': 19.2.17 + '@develar/schema-utils@2.6.5': + dependencies: + ajv: 6.15.0 + ajv-keywords: 3.5.2(ajv@6.15.0) + '@dimforge/rapier3d-compat@0.12.0': {} '@dotenvx/dotenvx@1.74.2': @@ -2527,84 +3723,233 @@ snapshots: dependencies: '@noble/ciphers': 1.3.0 + '@electron/asar@3.4.1': + dependencies: + commander: 5.1.0 + glob: 7.2.3 + minimatch: 3.1.5 + + '@electron/get@2.0.3': + dependencies: + debug: 4.4.3 + env-paths: 2.2.1 + fs-extra: 8.1.0 + got: 11.8.6 + progress: 2.0.3 + semver: 6.3.1 + sumchecker: 3.0.1 + optionalDependencies: + global-agent: 3.0.0 + transitivePeerDependencies: + - supports-color + + '@electron/notarize@2.5.0': + dependencies: + debug: 4.4.3 + fs-extra: 9.1.0 + promise-retry: 2.0.1 + transitivePeerDependencies: + - supports-color + + '@electron/osx-sign@1.3.1': + dependencies: + compare-version: 0.1.2 + debug: 4.4.3 + fs-extra: 10.1.0 + isbinaryfile: 4.0.10 + minimist: 1.2.8 + plist: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@electron/rebuild@3.6.1': + dependencies: + '@malept/cross-spawn-promise': 2.0.0 + chalk: 4.1.2 + debug: 4.4.3 + detect-libc: 2.1.2 + fs-extra: 10.1.0 + got: 11.8.6 + node-abi: 3.92.0 + node-api-version: 0.2.1 + node-gyp: 9.4.1 + ora: 5.4.1 + read-binary-file-arch: 1.0.6 + semver: 7.8.4 + tar: 6.2.1 + yargs: 17.7.3 + transitivePeerDependencies: + - bluebird + - supports-color + + '@electron/universal@2.0.1': + dependencies: + '@electron/asar': 3.4.1 + '@malept/cross-spawn-promise': 2.0.0 + debug: 4.4.3 + dir-compare: 4.2.0 + fs-extra: 11.3.5 + minimatch: 9.0.9 + plist: 3.1.1 + transitivePeerDependencies: + - supports-color + '@esbuild/aix-ppc64@0.27.7': optional: true + '@esbuild/aix-ppc64@0.28.1': + optional: true + '@esbuild/android-arm64@0.27.7': optional: true + '@esbuild/android-arm64@0.28.1': + optional: true + '@esbuild/android-arm@0.27.7': optional: true + '@esbuild/android-arm@0.28.1': + optional: true + '@esbuild/android-x64@0.27.7': optional: true + '@esbuild/android-x64@0.28.1': + optional: true + '@esbuild/darwin-arm64@0.27.7': optional: true + '@esbuild/darwin-arm64@0.28.1': + optional: true + '@esbuild/darwin-x64@0.27.7': optional: true + '@esbuild/darwin-x64@0.28.1': + optional: true + '@esbuild/freebsd-arm64@0.27.7': optional: true + '@esbuild/freebsd-arm64@0.28.1': + optional: true + '@esbuild/freebsd-x64@0.27.7': optional: true + '@esbuild/freebsd-x64@0.28.1': + optional: true + '@esbuild/linux-arm64@0.27.7': optional: true + '@esbuild/linux-arm64@0.28.1': + optional: true + '@esbuild/linux-arm@0.27.7': optional: true + '@esbuild/linux-arm@0.28.1': + optional: true + '@esbuild/linux-ia32@0.27.7': optional: true + '@esbuild/linux-ia32@0.28.1': + optional: true + '@esbuild/linux-loong64@0.27.7': optional: true + '@esbuild/linux-loong64@0.28.1': + optional: true + '@esbuild/linux-mips64el@0.27.7': optional: true + '@esbuild/linux-mips64el@0.28.1': + optional: true + '@esbuild/linux-ppc64@0.27.7': optional: true + '@esbuild/linux-ppc64@0.28.1': + optional: true + '@esbuild/linux-riscv64@0.27.7': optional: true + '@esbuild/linux-riscv64@0.28.1': + optional: true + '@esbuild/linux-s390x@0.27.7': optional: true + '@esbuild/linux-s390x@0.28.1': + optional: true + '@esbuild/linux-x64@0.27.7': optional: true + '@esbuild/linux-x64@0.28.1': + optional: true + '@esbuild/netbsd-arm64@0.27.7': optional: true + '@esbuild/netbsd-arm64@0.28.1': + optional: true + '@esbuild/netbsd-x64@0.27.7': optional: true + '@esbuild/netbsd-x64@0.28.1': + optional: true + '@esbuild/openbsd-arm64@0.27.7': optional: true + '@esbuild/openbsd-arm64@0.28.1': + optional: true + '@esbuild/openbsd-x64@0.27.7': optional: true + '@esbuild/openbsd-x64@0.28.1': + optional: true + '@esbuild/openharmony-arm64@0.27.7': optional: true + '@esbuild/openharmony-arm64@0.28.1': + optional: true + '@esbuild/sunos-x64@0.27.7': optional: true + '@esbuild/sunos-x64@0.28.1': + optional: true + '@esbuild/win32-arm64@0.27.7': optional: true + '@esbuild/win32-arm64@0.28.1': + optional: true + '@esbuild/win32-ia32@0.27.7': optional: true + '@esbuild/win32-ia32@0.28.1': + optional: true + '@esbuild/win32-x64@0.27.7': optional: true + '@esbuild/win32-x64@0.28.1': + optional: true + '@floating-ui/core@1.7.5': dependencies: '@floating-ui/utils': 0.2.11 @@ -2626,10 +3971,21 @@ snapshots: '@fontsource-variable/inter@5.2.8': {} + '@gar/promisify@1.1.3': {} + '@hono/node-server@1.19.14(hono@4.12.26)': dependencies: hono: 4.12.26 + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -2649,6 +4005,19 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@malept/cross-spawn-promise@2.0.0': + dependencies: + cross-spawn: 7.0.6 + + '@malept/flatpak-bundler@0.4.0': + dependencies: + debug: 4.4.3 + fs-extra: 9.1.0 + lodash: 4.18.1 + tmp-promise: 3.0.3 + transitivePeerDependencies: + - supports-color + '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)': dependencies: '@hono/node-server': 1.19.14(hono@4.12.26) @@ -2691,6 +4060,19 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 + '@npmcli/fs@2.1.2': + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.8.4 + + '@npmcli/move-file@2.0.1': + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + + '@pkgjs/parseargs@0.11.0': + optional: true + '@react-three/fiber@9.6.1(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(three@0.184.0)': dependencies: '@babel/runtime': 7.29.7 @@ -2790,8 +4172,14 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} + '@sindresorhus/is@4.6.0': {} + '@sindresorhus/merge-streams@4.0.0': {} + '@szmarczak/http-timer@4.0.6': + dependencies: + defer-to-connect: 2.0.1 + '@tailwindcss/node@4.3.1': dependencies: '@jridgewell/remapping': 2.3.5 @@ -2853,85 +4241,14 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.3.1 '@tailwindcss/oxide-win32-x64-msvc': 4.3.1 - '@tailwindcss/vite@4.3.1(vite@7.3.5(jiti@2.7.0)(lightningcss@1.32.0))': + '@tailwindcss/vite@4.3.1(vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4))': dependencies: '@tailwindcss/node': 4.3.1 '@tailwindcss/oxide': 4.3.1 tailwindcss: 4.3.1 - vite: 7.3.5(jiti@2.7.0)(lightningcss@1.32.0) + vite: 7.3.5(@types/node@26.0.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4) - '@tauri-apps/api@2.11.1': {} - - '@tauri-apps/cli-darwin-arm64@2.11.2': - optional: true - - '@tauri-apps/cli-darwin-x64@2.11.2': - optional: true - - '@tauri-apps/cli-linux-arm-gnueabihf@2.11.2': - optional: true - - '@tauri-apps/cli-linux-arm64-gnu@2.11.2': - optional: true - - '@tauri-apps/cli-linux-arm64-musl@2.11.2': - optional: true - - '@tauri-apps/cli-linux-riscv64-gnu@2.11.2': - optional: true - - '@tauri-apps/cli-linux-x64-gnu@2.11.2': - optional: true - - '@tauri-apps/cli-linux-x64-musl@2.11.2': - optional: true - - '@tauri-apps/cli-win32-arm64-msvc@2.11.2': - optional: true - - '@tauri-apps/cli-win32-ia32-msvc@2.11.2': - optional: true - - '@tauri-apps/cli-win32-x64-msvc@2.11.2': - optional: true - - '@tauri-apps/cli@2.11.2': - optionalDependencies: - '@tauri-apps/cli-darwin-arm64': 2.11.2 - '@tauri-apps/cli-darwin-x64': 2.11.2 - '@tauri-apps/cli-linux-arm-gnueabihf': 2.11.2 - '@tauri-apps/cli-linux-arm64-gnu': 2.11.2 - '@tauri-apps/cli-linux-arm64-musl': 2.11.2 - '@tauri-apps/cli-linux-riscv64-gnu': 2.11.2 - '@tauri-apps/cli-linux-x64-gnu': 2.11.2 - '@tauri-apps/cli-linux-x64-musl': 2.11.2 - '@tauri-apps/cli-win32-arm64-msvc': 2.11.2 - '@tauri-apps/cli-win32-ia32-msvc': 2.11.2 - '@tauri-apps/cli-win32-x64-msvc': 2.11.2 - - '@tauri-apps/plugin-dialog@2.7.1': - dependencies: - '@tauri-apps/api': 2.11.1 - - '@tauri-apps/plugin-fs@2.5.1': - dependencies: - '@tauri-apps/api': 2.11.1 - - '@tauri-apps/plugin-opener@2.5.4': - dependencies: - '@tauri-apps/api': 2.11.1 - - '@tauri-apps/plugin-process@2.3.1': - dependencies: - '@tauri-apps/api': 2.11.1 - - '@tauri-apps/plugin-shell@2.3.5': - dependencies: - '@tauri-apps/api': 2.11.1 - - '@tauri-apps/plugin-updater@2.10.1': - dependencies: - '@tauri-apps/api': 2.11.1 + '@tootallnate/once@2.0.1': {} '@ts-morph/common@0.27.0': dependencies: @@ -2962,8 +4279,47 @@ snapshots: dependencies: '@babel/types': 7.29.7 + '@types/cacheable-request@6.0.3': + dependencies: + '@types/http-cache-semantics': 4.2.0 + '@types/keyv': 3.1.4 + '@types/node': 26.0.1 + '@types/responselike': 1.0.3 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/estree@1.0.9': {} + '@types/fs-extra@9.0.13': + dependencies: + '@types/node': 26.0.1 + + '@types/http-cache-semantics@4.2.0': {} + + '@types/js-yaml@4.0.9': {} + + '@types/keyv@3.1.4': + dependencies: + '@types/node': 26.0.1 + + '@types/ms@2.1.0': {} + + '@types/node@20.19.43': + dependencies: + undici-types: 6.21.0 + + '@types/node@26.0.1': + dependencies: + undici-types: 8.3.0 + + '@types/plist@3.0.5': + dependencies: + '@types/node': 26.0.1 + xmlbuilder: 15.1.1 + optional: true + '@types/react-dom@19.2.3(@types/react@19.2.17)': dependencies: '@types/react': 19.2.17 @@ -2976,6 +4332,10 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/responselike@1.0.3': + dependencies: + '@types/node': 26.0.1 + '@types/stats.js@0.17.4': {} '@types/three@0.184.1': @@ -2989,9 +4349,17 @@ snapshots: '@types/validate-npm-package-name@4.0.2': {} + '@types/verror@1.10.11': + optional: true + '@types/webxr@0.5.24': {} - '@vitejs/plugin-react@4.7.0(vite@7.3.5(jiti@2.7.0)(lightningcss@1.32.0))': + '@types/yauzl@2.10.3': + dependencies: + '@types/node': 20.19.43 + optional: true + + '@vitejs/plugin-react@4.7.0(vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-transform-react-jsx-self': 7.29.7(@babel/core@7.29.7) @@ -2999,17 +4367,36 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 7.3.5(jiti@2.7.0)(lightningcss@1.32.0) + vite: 7.3.5(@types/node@26.0.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4) transitivePeerDependencies: - supports-color + '@xmldom/xmldom@0.9.10': {} + + abbrev@1.1.1: {} + accepts@2.0.0: dependencies: mime-types: 3.0.2 negotiator: 1.0.0 + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + agent-base@7.1.4: {} + agentkeepalive@4.6.0: + dependencies: + humanize-ms: 1.2.1 + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + ajv-formats@2.1.1(ajv@8.20.0): optionalDependencies: ajv: 8.20.0 @@ -3018,6 +4405,17 @@ snapshots: optionalDependencies: ajv: 8.20.0 + ajv-keywords@3.5.2(ajv@6.15.0): + dependencies: + ajv: 6.15.0 + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 @@ -3031,20 +4429,139 @@ snapshots: ansi-regex@6.2.2: {} + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + app-builder-bin@5.0.0-alpha.10: {} + + app-builder-lib@25.1.8(dmg-builder@25.1.8)(electron-builder-squirrel-windows@25.1.8): + 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.4.3 + dmg-builder: 25.1.8(electron-builder-squirrel-windows@25.1.8) + dotenv: 16.6.1 + dotenv-expand: 11.0.7 + ejs: 3.1.10 + electron-builder-squirrel-windows: 25.1.8(dmg-builder@25.1.8) + electron-publish: 25.1.7 + form-data: 4.0.6 + fs-extra: 10.1.0 + hosted-git-info: 4.1.0 + is-ci: 3.0.1 + isbinaryfile: 5.0.7 + js-yaml: 4.2.0 + json5: 2.2.3 + lazy-val: 1.0.5 + minimatch: 10.2.5 + resedit: 1.7.2 + sanitize-filename: 1.6.4 + semver: 7.8.4 + tar: 6.2.1 + temp-file: 3.4.0 + transitivePeerDependencies: + - bluebird + - supports-color + + aproba@2.1.0: {} + + archiver-utils@2.1.0: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + 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.3.8 + + archiver-utils@3.0.4: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + 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.2 + + archiver@5.3.2: + dependencies: + archiver-utils: 2.1.0 + async: 3.2.6 + buffer-crc32: 0.2.13 + readable-stream: 3.6.2 + readdir-glob: 1.1.3 + tar-stream: 2.2.0 + zip-stream: 4.1.1 + + are-we-there-yet@3.0.1: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + argparse@2.0.1: {} + assert-plus@1.0.0: + optional: true + ast-types@0.16.1: dependencies: tslib: 2.8.1 + astral-regex@2.0.0: + optional: true + + async-exit-hook@2.0.1: {} + + async@3.2.6: {} + + asynckit@0.4.0: {} + + at-least-node@1.0.0: {} + atomically@1.7.0: {} + balanced-match@1.0.2: {} + balanced-match@4.0.4: {} base64-js@1.5.1: {} baseline-browser-mapping@2.10.38: {} + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + bluebird-lst@1.0.9: + dependencies: + bluebird: 3.7.2 + + bluebird@3.7.2: {} + body-parser@2.3.0: dependencies: bytes: 3.1.2 @@ -3059,6 +4576,18 @@ snapshots: transitivePeerDependencies: - supports-color + boolean@3.2.0: + optional: true + + brace-expansion@1.1.15: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.1.1: + dependencies: + balanced-match: 1.0.2 + brace-expansion@5.0.6: dependencies: balanced-match: 4.0.4 @@ -3075,17 +4604,89 @@ snapshots: node-releases: 2.0.48 update-browserslist-db: 1.2.3(browserslist@4.28.2) + buffer-crc32@0.2.13: {} + + buffer-from@1.1.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + buffer@6.0.3: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 + builder-util-runtime@9.2.10: + dependencies: + debug: 4.4.3 + sax: 1.6.0 + transitivePeerDependencies: + - supports-color + + builder-util@25.1.7: + dependencies: + 7zip-bin: 5.2.0 + '@types/debug': 4.1.13 + 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.6 + debug: 4.4.3 + fs-extra: 10.1.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-ci: 3.0.1 + js-yaml: 4.2.0 + source-map-support: 0.5.21 + stat-mode: 1.0.0 + temp-file: 3.4.0 + transitivePeerDependencies: + - supports-color + bundle-name@4.1.0: dependencies: run-applescript: 7.1.0 bytes@3.1.2: {} + cacache@16.1.3: + dependencies: + '@npmcli/fs': 2.1.2 + '@npmcli/move-file': 2.0.1 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 8.1.0 + infer-owner: 1.0.4 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.7 + 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.1 + tar: 6.2.1 + unique-filename: 2.0.1 + transitivePeerDependencies: + - bluebird + + cacheable-lookup@5.0.4: {} + + cacheable-request@7.0.4: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -3100,26 +4701,95 @@ snapshots: caniuse-lite@1.0.30001799: {} + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chalk@5.6.2: {} + chownr@2.0.0: {} + + chromium-pickle-js@0.2.0: {} + + ci-info@3.9.0: {} + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 + clean-stack@2.2.0: {} + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + cli-cursor@5.0.0: dependencies: restore-cursor: 5.1.0 cli-spinners@2.9.2: {} + cli-truncate@2.1.0: + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + optional: true + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + + clone@1.0.4: {} + clsx@2.1.1: {} code-block-writer@13.0.3: {} + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + color-support@1.1.3: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + commander@11.1.0: {} commander@14.0.3: {} + commander@5.1.0: {} + + compare-version@0.1.2: {} + + compress-commons@4.1.2: + dependencies: + buffer-crc32: 0.2.13 + crc32-stream: 4.0.3 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + + concat-map@0.0.1: {} + + concurrently@9.2.3: + dependencies: + chalk: 4.1.2 + rxjs: 7.8.2 + shell-quote: 1.8.4 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 + conf@10.2.0: dependencies: ajv: 8.20.0 @@ -3133,6 +4803,13 @@ snapshots: pkg-up: 3.1.0 semver: 7.8.4 + config-file-ts@0.2.8-rc1: + dependencies: + glob: 10.4.5 + typescript: 5.8.3 + + console-control-strings@1.1.0: {} + content-disposition@1.1.0: {} content-type@1.0.5: {} @@ -3145,6 +4822,11 @@ snapshots: cookie@0.7.2: {} + core-util-is@1.0.2: + optional: true + + core-util-is@1.0.3: {} + cors@2.8.6: dependencies: object-assign: 4.1.1 @@ -3159,6 +4841,18 @@ snapshots: optionalDependencies: typescript: 5.8.3 + crc-32@1.2.2: {} + + crc32-stream@4.0.3: + dependencies: + crc-32: 1.2.2 + readable-stream: 3.6.2 + + crc@3.8.0: + dependencies: + buffer: 5.7.1 + optional: true + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -3179,6 +4873,10 @@ snapshots: dependencies: ms: 2.1.3 + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + dedent@1.7.2: {} deepmerge@4.3.1: {} @@ -3190,20 +4888,85 @@ snapshots: bundle-name: 4.1.0 default-browser-id: 5.0.1 + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + defer-to-connect@2.0.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + optional: true + define-lazy-prop@2.0.0: {} define-lazy-prop@3.0.0: {} + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + optional: true + + delayed-stream@1.0.0: {} + + delegates@1.0.0: {} + depd@2.0.0: {} detect-libc@2.1.2: {} + detect-node@2.1.0: + optional: true + diff@8.0.4: {} + dir-compare@4.2.0: + dependencies: + minimatch: 3.1.5 + p-limit: 3.1.0 + + dmg-builder@25.1.8(electron-builder-squirrel-windows@25.1.8): + dependencies: + app-builder-lib: 25.1.8(dmg-builder@25.1.8)(electron-builder-squirrel-windows@25.1.8) + builder-util: 25.1.7 + builder-util-runtime: 9.2.10 + fs-extra: 10.1.0 + iconv-lite: 0.6.3 + js-yaml: 4.2.0 + optionalDependencies: + dmg-license: 1.0.11 + transitivePeerDependencies: + - bluebird + - electron-builder-squirrel-windows + - supports-color + + dmg-license@1.0.11: + dependencies: + '@types/plist': 3.0.5 + '@types/verror': 1.10.11 + ajv: 6.15.0 + crc: 3.8.0 + iconv-corefoundation: 1.1.7 + plist: 3.1.1 + smart-buffer: 4.2.0 + verror: 1.10.1 + optional: true + dot-prop@6.0.1: dependencies: is-obj: 2.0.0 + dotenv-expand@11.0.7: + dependencies: + dotenv: 16.6.1 + + dotenv@16.6.1: {} + dotenv@17.4.2: {} dunder-proto@1.0.1: @@ -3212,6 +4975,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + eastasianwidth@0.2.0: {} + eciesjs@0.4.18: dependencies: '@ecies/ciphers': 0.2.6(@noble/ciphers@1.3.0) @@ -3221,12 +4986,77 @@ snapshots: ee-first@1.1.1: {} + ejs@3.1.10: + dependencies: + jake: 10.9.4 + + electron-builder-squirrel-windows@25.1.8(dmg-builder@25.1.8): + dependencies: + app-builder-lib: 25.1.8(dmg-builder@25.1.8)(electron-builder-squirrel-windows@25.1.8) + archiver: 5.3.2 + builder-util: 25.1.7 + fs-extra: 10.1.0 + transitivePeerDependencies: + - bluebird + - dmg-builder + - supports-color + + electron-builder@25.1.8(electron-builder-squirrel-windows@25.1.8): + dependencies: + app-builder-lib: 25.1.8(dmg-builder@25.1.8)(electron-builder-squirrel-windows@25.1.8) + builder-util: 25.1.7 + builder-util-runtime: 9.2.10 + chalk: 4.1.2 + dmg-builder: 25.1.8(electron-builder-squirrel-windows@25.1.8) + fs-extra: 10.1.0 + is-ci: 3.0.1 + lazy-val: 1.0.5 + simple-update-notifier: 2.0.0 + yargs: 17.7.3 + transitivePeerDependencies: + - bluebird + - electron-builder-squirrel-windows + - supports-color + + electron-publish@25.1.7: + dependencies: + '@types/fs-extra': 9.0.13 + 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.6.0 + transitivePeerDependencies: + - supports-color + electron-to-chromium@1.5.376: {} + electron@33.4.11: + dependencies: + '@electron/get': 2.0.3 + '@types/node': 20.19.43 + extract-zip: 2.0.1 + transitivePeerDependencies: + - supports-color + emoji-regex@10.6.0: {} + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + encodeurl@2.0.0: {} + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + enhanced-resolve@5.21.6: dependencies: graceful-fs: 4.2.11 @@ -3239,6 +5069,8 @@ snapshots: env-paths@2.2.1: {} + err-code@2.0.3: {} + error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 @@ -3251,6 +5083,16 @@ snapshots: dependencies: es-errors: 1.3.0 + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + es6-error@4.1.1: + optional: true + esbuild@0.27.7: optionalDependencies: '@esbuild/aix-ppc64': 0.27.7 @@ -3280,10 +5122,42 @@ snapshots: '@esbuild/win32-ia32': 0.27.7 '@esbuild/win32-x64': 0.27.7 + esbuild@0.28.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 + escalade@3.2.0: {} escape-html@1.0.3: {} + escape-string-regexp@4.0.0: + optional: true + esprima@4.0.1: {} etag@1.8.1: {} @@ -3321,6 +5195,8 @@ snapshots: strip-final-newline: 4.0.0 yoctocolors: 2.1.2 + exponential-backoff@3.1.3: {} + express-rate-limit@8.5.2(express@5.2.1): dependencies: express: 5.2.1 @@ -3359,6 +5235,19 @@ snapshots: transitivePeerDependencies: - supports-color + extract-zip@2.0.1: + dependencies: + debug: 4.4.3 + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + + extsprintf@1.4.1: + optional: true + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -3369,12 +5258,18 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} + fast-uri@3.1.2: {} fastq@1.20.1: dependencies: reusify: 1.1.0 + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: picomatch: 4.0.4 @@ -3390,6 +5285,10 @@ snapshots: dependencies: is-unicode-supported: 2.1.0 + filelist@1.0.6: + dependencies: + minimatch: 5.1.9 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -3409,6 +5308,19 @@ snapshots: dependencies: locate-path: 3.0.0 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data@4.0.6: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.4 + mime-types: 2.1.35 + formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 @@ -3417,12 +5329,39 @@ snapshots: fresh@2.0.0: {} + fs-constants@1.0.0: {} + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + fs-extra@11.3.5: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.1 universalify: 2.0.1 + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true @@ -3430,8 +5369,21 @@ snapshots: fuzzysort@3.1.0: {} + gauge@4.0.4: + dependencies: + aproba: 2.1.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 + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + get-east-asian-width@1.6.0: {} get-intrinsic@1.3.0: @@ -3454,6 +5406,10 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.2 + get-stream@5.2.0: + dependencies: + pump: 3.0.4 + get-stream@6.0.1: {} get-stream@9.0.1: @@ -3465,18 +5421,93 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.9 + once: 1.4.0 + + global-agent@3.0.0: + dependencies: + boolean: 3.2.0 + es6-error: 4.1.1 + matcher: 3.0.0 + roarr: 2.15.4 + semver: 7.8.4 + serialize-error: 7.0.1 + optional: true + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + optional: true + gopd@1.2.0: {} + got@11.8.6: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + graceful-fs@4.2.11: {} + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + optional: true + has-symbols@1.1.0: {} + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + has-unicode@2.0.1: {} + hasown@2.0.4: dependencies: function-bind: 1.1.2 hono@4.12.26: {} + hosted-git-info@4.1.0: + dependencies: + lru-cache: 6.0.0 + + http-cache-semantics@4.2.0: {} + http-errors@2.0.1: dependencies: depd: 2.0.0 @@ -3485,6 +5516,33 @@ snapshots: statuses: 2.0.2 toidentifier: 1.0.1 + http-proxy-agent@5.0.0: + dependencies: + '@tootallnate/once': 2.0.1 + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + http2-wrapper@1.0.3: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 @@ -3496,6 +5554,20 @@ snapshots: human-signals@8.0.1: {} + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + iconv-corefoundation@1.1.7: + dependencies: + cli-truncate: 2.1.0 + node-addon-api: 1.7.2 + optional: true + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + iconv-lite@0.7.2: dependencies: safer-buffer: 2.1.2 @@ -3509,6 +5581,17 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + infer-owner@1.0.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + inherits@2.0.4: {} ip-address@10.2.0: {} @@ -3517,12 +5600,18 @@ snapshots: is-arrayish@0.2.1: {} + is-ci@3.0.1: + dependencies: + ci-info: 3.9.0 + is-docker@2.2.1: {} is-docker@3.0.0: {} is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -3533,8 +5622,12 @@ snapshots: dependencies: is-docker: 3.0.0 + is-interactive@1.0.0: {} + is-interactive@2.0.0: {} + is-lambda@1.0.1: {} + is-number@7.0.0: {} is-obj@2.0.0: {} @@ -3551,6 +5644,8 @@ snapshots: is-stream@4.0.1: {} + is-unicode-supported@0.1.0: {} + is-unicode-supported@1.3.0: {} is-unicode-supported@2.1.0: {} @@ -3563,6 +5658,12 @@ snapshots: dependencies: is-inside-container: 1.0.0 + isarray@1.0.0: {} + + isbinaryfile@4.0.10: {} + + isbinaryfile@5.0.7: {} + isexe@2.0.0: {} isexe@3.1.5: {} @@ -3574,6 +5675,18 @@ snapshots: transitivePeerDependencies: - '@types/react' + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jake@10.9.4: + dependencies: + async: 3.2.6 + filelist: 1.0.6 + picocolors: 1.1.1 + jiti@2.7.0: {} jose@6.2.3: {} @@ -3586,26 +5699,47 @@ snapshots: jsesc@3.1.0: {} + json-buffer@3.0.1: {} + json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} json-schema-typed@7.0.3: {} json-schema-typed@8.0.2: {} + json-stringify-safe@5.0.1: + optional: true + json5@2.2.3: {} + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + jsonfile@6.2.1: dependencies: universalify: 2.0.1 optionalDependencies: graceful-fs: 4.2.11 + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + kleur@3.0.3: {} kleur@4.1.5: {} + lazy-val@1.0.5: {} + + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + lightningcss-android-arm64@1.32.0: optional: true @@ -3662,15 +5796,42 @@ snapshots: p-locate: 3.0.0 path-exists: 3.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: {} + + lodash@4.18.1: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + log-symbols@6.0.0: dependencies: chalk: 5.6.2 is-unicode-supported: 1.3.0 + lowercase-keys@2.0.0: {} + + lru-cache@10.4.3: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru-cache@7.18.3: {} + lucide-react@1.21.0(react@19.2.7): dependencies: react: 19.2.7 @@ -3679,6 +5840,33 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + make-fetch-happen@10.2.1: + dependencies: + agentkeepalive: 4.6.0 + cacache: 16.1.3 + http-cache-semantics: 4.2.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-fetch: 2.1.2 + minipass-flush: 1.0.7 + minipass-pipeline: 1.2.4 + negotiator: 0.6.4 + promise-retry: 2.0.1 + socks-proxy-agent: 7.0.0 + ssri: 9.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + matcher@3.0.0: + dependencies: + escape-string-regexp: 4.0.0 + optional: true + math-intrinsics@1.1.0: {} media-typer@1.1.0: {} @@ -3696,30 +5884,106 @@ snapshots: braces: 3.0.3 picomatch: 2.3.2 + mime-db@1.52.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mime-types@3.0.2: dependencies: mime-db: 1.54.0 + mime@2.6.0: {} + mimic-fn@2.1.0: {} mimic-fn@3.1.0: {} mimic-function@5.0.1: {} + mimic-response@1.0.1: {} + + mimic-response@3.1.0: {} + minimatch@10.2.5: dependencies: brace-expansion: 5.0.6 + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.15 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.1.1 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.1.1 + minimist@1.2.8: {} + minipass-collect@1.0.2: + dependencies: + minipass: 3.3.6 + + minipass-fetch@2.1.2: + dependencies: + minipass: 3.3.6 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.7: + dependencies: + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minipass@7.1.3: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mkdirp@1.0.4: {} + ms@2.1.3: {} nanoid@3.3.13: {} + negotiator@0.6.4: {} + negotiator@1.0.0: {} + node-abi@3.92.0: + dependencies: + semver: 7.8.4 + + node-addon-api@1.7.2: + optional: true + + node-api-version@0.2.1: + dependencies: + semver: 7.8.4 + node-domexception@1.0.0: {} node-fetch@3.3.2: @@ -3728,8 +5992,33 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + node-gyp@9.4.1: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + glob: 7.2.3 + graceful-fs: 4.2.11 + make-fetch-happen: 10.2.1 + nopt: 6.0.0 + npmlog: 6.0.2 + rimraf: 3.0.2 + semver: 7.8.4 + tar: 6.2.1 + which: 2.0.2 + transitivePeerDependencies: + - bluebird + - supports-color + node-releases@2.0.48: {} + nopt@6.0.0: + dependencies: + abbrev: 1.1.1 + + normalize-path@3.0.0: {} + + normalize-url@6.1.0: {} + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -3739,10 +6028,20 @@ snapshots: path-key: 4.0.0 unicorn-magic: 0.3.0 + npmlog@6.0.2: + dependencies: + are-we-there-yet: 3.0.1 + console-control-strings: 1.1.0 + gauge: 4.0.4 + set-blocking: 2.0.0 + object-assign@4.1.1: {} object-inspect@1.13.4: {} + object-keys@1.1.1: + optional: true + object-treeify@1.1.33: {} on-finished@2.4.1: @@ -3776,6 +6075,18 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 + ora@5.4.1: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + ora@8.2.0: dependencies: chalk: 5.6.2 @@ -3788,16 +6099,28 @@ snapshots: string-width: 7.2.0 strip-ansi: 7.2.0 + p-cancelable@2.1.1: {} + p-limit@2.3.0: dependencies: p-try: 2.2.0 + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + p-locate@3.0.0: dependencies: p-limit: 2.3.0 + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + p-try@2.2.0: {} + package-json-from-dist@1.0.1: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -3817,12 +6140,23 @@ snapshots: path-exists@3.0.0: {} + path-is-absolute@1.0.1: {} + path-key@3.1.1: {} path-key@4.0.0: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + path-to-regexp@8.4.2: {} + pe-library@0.4.1: {} + + pend@1.2.0: {} + picocolors@1.1.1: {} picomatch@2.3.2: {} @@ -3835,6 +6169,12 @@ snapshots: dependencies: find-up: 3.0.0 + plist@3.1.1: + dependencies: + '@xmldom/xmldom': 0.9.10 + base64-js: 1.5.1 + xmlbuilder: 15.1.1 + postcss-selector-parser@7.1.4: dependencies: cssesc: 3.0.0 @@ -3852,6 +6192,17 @@ snapshots: dependencies: parse-ms: 4.0.0 + process-nextick-args@2.0.1: {} + + progress@2.0.3: {} + + promise-inflight@1.0.1: {} + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -3862,12 +6213,21 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + punycode@2.3.1: {} + qs@6.15.2: dependencies: side-channel: 1.1.1 queue-microtask@1.2.3: {} + quick-lru@5.1.1: {} + range-parser@1.2.1: {} raw-body@3.0.2: @@ -3892,6 +6252,32 @@ snapshots: react@19.2.7: {} + read-binary-file-arch@1.0.6: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.9 + recast@0.23.11: dependencies: ast-types: 0.16.1 @@ -3900,19 +6286,52 @@ snapshots: tiny-invariant: 1.3.3 tslib: 2.8.1 + require-directory@2.1.1: {} + require-from-string@2.0.2: {} + resedit@1.7.2: + dependencies: + pe-library: 0.4.1 + reselect@5.2.0: {} + resolve-alpn@1.2.1: {} + resolve-from@4.0.0: {} + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + restore-cursor@5.1.0: dependencies: onetime: 7.0.0 signal-exit: 4.1.0 + retry@0.12.0: {} + reusify@1.1.0: {} + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + roarr@2.15.4: + dependencies: + boolean: 3.2.0 + detect-node: 2.1.0 + globalthis: 1.0.4 + json-stringify-safe: 5.0.1 + semver-compare: 1.0.0 + sprintf-js: 1.1.3 + optional: true + rollup@4.62.0: dependencies: '@types/estree': 1.0.9 @@ -3960,10 +6379,27 @@ snapshots: dependencies: queue-microtask: 1.2.3 + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + safer-buffer@2.1.2: {} + sanitize-filename@1.6.4: + dependencies: + truncate-utf8-bytes: 1.0.2 + + sax@1.6.0: {} + scheduler@0.27.0: {} + semver-compare@1.0.0: + optional: true + semver@6.3.1: {} semver@7.8.4: {} @@ -3984,6 +6420,11 @@ snapshots: transitivePeerDependencies: - supports-color + serialize-error@7.0.1: + dependencies: + type-fest: 0.13.1 + optional: true + serve-static@2.2.1: dependencies: encodeurl: 2.0.0 @@ -3993,6 +6434,8 @@ snapshots: transitivePeerDependencies: - supports-color + set-blocking@2.0.0: {} + setprototypeof@1.2.0: {} shadcn@4.11.0(typescript@5.8.3): @@ -4042,6 +6485,8 @@ snapshots: shebang-regex@3.0.0: {} + shell-quote@1.8.4: {} + side-channel-list@1.0.1: dependencies: es-errors: 1.3.0 @@ -4074,22 +6519,82 @@ snapshots: signal-exit@4.1.0: {} + simple-update-notifier@2.0.0: + dependencies: + semver: 7.8.4 + sisteransi@1.0.5: {} + slice-ansi@3.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + optional: true + + smart-buffer@4.2.0: {} + + socks-proxy-agent@7.0.0: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + socks: 2.8.9 + transitivePeerDependencies: + - supports-color + + socks@2.8.9: + dependencies: + ip-address: 10.2.0 + smart-buffer: 4.2.0 + source-map-js@1.2.1: {} + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + source-map@0.6.1: {} + sprintf-js@1.1.3: + optional: true + + ssri@9.0.1: + dependencies: + minipass: 3.3.6 + + stat-mode@1.0.0: {} + statuses@2.0.2: {} stdin-discarder@0.2.2: {} + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + string-width@7.2.0: dependencies: emoji-regex: 10.6.0 get-east-asian-width: 1.6.0 strip-ansi: 7.2.0 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + stringify-object@5.0.0: dependencies: get-own-enumerable-keys: 1.0.0 @@ -4110,6 +6615,20 @@ snapshots: strip-final-newline@4.0.0: {} + sumchecker@3.0.1: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + suspend-react@0.1.3(react@19.2.7): dependencies: react: 19.2.7 @@ -4122,6 +6641,28 @@ snapshots: tapable@2.3.3: {} + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + temp-file@3.4.0: + dependencies: + async-exit-hook: 2.0.1 + fs-extra: 10.1.0 + three@0.184.0: {} tiny-invariant@1.3.3: {} @@ -4131,12 +6672,24 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 + tmp-promise@3.0.3: + dependencies: + tmp: 0.2.7 + + tmp@0.2.7: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 toidentifier@1.0.1: {} + tree-kill@1.2.2: {} + + truncate-utf8-bytes@1.0.2: + dependencies: + utf8-byte-length: 1.0.5 + ts-morph@26.0.0: dependencies: '@ts-morph/common': 0.27.0 @@ -4150,8 +6703,17 @@ snapshots: tslib@2.8.1: {} + tsx@4.22.4: + dependencies: + esbuild: 0.28.1 + optionalDependencies: + fsevents: 2.3.3 + tw-animate-css@1.4.0: {} + type-fest@0.13.1: + optional: true + type-is@2.1.0: dependencies: content-type: 2.0.0 @@ -4160,10 +6722,24 @@ snapshots: typescript@5.8.3: {} + undici-types@6.21.0: {} + + undici-types@8.3.0: {} + undici@7.28.0: {} unicorn-magic@0.3.0: {} + unique-filename@2.0.1: + dependencies: + unique-slug: 3.0.0 + + unique-slug@3.0.0: + dependencies: + imurmurhash: 0.1.4 + + universalify@0.1.2: {} + universalify@2.0.1: {} unpipe@1.0.0: {} @@ -4174,17 +6750,30 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + use-sync-external-store@1.6.0(react@19.2.7): dependencies: react: 19.2.7 + utf8-byte-length@1.0.5: {} + util-deprecate@1.0.2: {} validate-npm-package-name@7.0.2: {} vary@1.1.2: {} - vite@7.3.5(jiti@2.7.0)(lightningcss@1.32.0): + verror@1.10.1: + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.4.1 + optional: true + + vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) @@ -4193,9 +6782,15 @@ snapshots: rollup: 4.62.0 tinyglobby: 0.2.17 optionalDependencies: + '@types/node': 26.0.1 fsevents: 2.3.3 jiti: 2.7.0 lightningcss: 1.32.0 + tsx: 4.22.4 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 web-streams-polyfill@3.3.3: {} @@ -4207,6 +6802,22 @@ snapshots: dependencies: isexe: 3.1.5 + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + wrappy@1.0.2: {} wsl-utils@0.3.1: @@ -4214,14 +6825,55 @@ snapshots: is-wsl: 3.1.1 powershell-utils: 0.1.0 + xmlbuilder@15.1.1: {} + + y18n@5.0.8: {} + yallist@3.1.1: {} + yallist@4.0.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yargs@17.7.3: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + + yocto-queue@0.1.0: {} + yocto-spinner@1.2.0: dependencies: yoctocolors: 2.1.2 yoctocolors@2.1.2: {} + zip-stream@4.1.1: + dependencies: + archiver-utils: 3.0.4 + compress-commons: 4.1.2 + readable-stream: 3.6.2 + zod-to-json-schema@3.25.2(zod@3.25.76): dependencies: zod: 3.25.76 diff --git a/public/icon.ico b/public/icon.ico new file mode 100644 index 0000000..188e183 Binary files /dev/null and b/public/icon.ico differ diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 0000000..a634d68 Binary files /dev/null and b/public/icon.png differ diff --git a/scripts/switch-icon.js b/scripts/switch-icon.js index 211fea1..1963c9e 100644 --- a/scripts/switch-icon.js +++ b/scripts/switch-icon.js @@ -1,17 +1,16 @@ -import { cpSync, existsSync } from "fs"; -import { join } from "path"; +const { cpSync, existsSync } = require('fs'); +const { join } = require('path'); const mode = process.argv[2]; -const validModes = ["dev", "beta", "run"]; +const validModes = ['dev', 'beta', 'run']; if (!mode || !validModes.includes(mode)) { - console.error(`Usage: node scripts/switch-icon.js <${validModes.join("|")}>`); + console.error(`Usage: node scripts/switch-icon.js <${validModes.join('|')}>`); process.exit(1); } -const root = join(import.meta.dirname, ".."); -const publicDir = join(root, "public"); -const iconsDir = join(root, "src-tauri", "icons"); +const root = join(__dirname, '..'); +const publicDir = join(root, 'public'); const png = join(publicDir, `${mode}.png`); const ico = join(publicDir, `${mode}.ico`); @@ -25,9 +24,7 @@ if (!existsSync(ico)) { process.exit(1); } -// Tauri 2 only needs icon.png (source) + icon.ico -// It auto-generates 32x32, 128x128, 128x128@2x, icns from icon.png during build -cpSync(png, join(iconsDir, "icon.png"), { overwrite: true }); -cpSync(ico, join(iconsDir, "icon.ico"), { overwrite: true }); +cpSync(png, join(publicDir, 'icon.png'), { overwrite: true }); +cpSync(ico, join(publicDir, 'icon.ico'), { overwrite: true }); console.log(`[switch-icon] Mode: ${mode} → icon.png + icon.ico updated`); diff --git a/sidecar/package.json b/sidecar/package.json deleted file mode 100644 index b04e1e0..0000000 --- a/sidecar/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "koring-sidecar", - "version": "0.1.0", - "private": true, - "type": "module", - "main": "dist/index.js", - "bin": { - "koring-sidecar": "dist/index.js" - }, - "scripts": { - "dev": "tsx src/index.ts", - "build": "tsc", - "compile": "bun build --compile --target=bun-windows-arm64 src/index.ts --outfile bin/koring-sidecar-aarch64-pc-windows-msvc.exe", - "compile:x64": "bun build --compile --target=bun-windows-x64 src/index.ts --outfile bin/koring-sidecar-x86_64-pc-windows-msvc.exe" - }, - "dependencies": { - "@xmcl/core": "^2.15.1", - "@xmcl/installer": "^6.1.2", - "@xmcl/user": "^4.3.0", - "@xmcl/modrinth": "^2.5.0", - "@xmcl/curseforge": "^2.2.0", - "@xmcl/nbt": "^3.0.2", - "@xmcl/system": "^2.2.9", - "uuid": "^11.1.0" - }, - "devDependencies": { - "@types/node": "^22.0.0", - "@types/uuid": "^10.0.0", - "tsx": "^4.19.0", - "typescript": "~5.8.3" - } -} diff --git a/sidecar/pnpm-lock.yaml b/sidecar/pnpm-lock.yaml deleted file mode 100644 index d3edfec..0000000 --- a/sidecar/pnpm-lock.yaml +++ /dev/null @@ -1,718 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@xmcl/core': - specifier: ^2.15.1 - version: 2.15.1(yauzl@2.10.0) - '@xmcl/curseforge': - specifier: ^2.2.0 - version: 2.2.0 - '@xmcl/installer': - specifier: ^6.1.2 - version: 6.1.2 - '@xmcl/modrinth': - specifier: ^2.5.0 - version: 2.5.0 - '@xmcl/nbt': - specifier: ^3.0.2 - version: 3.0.2 - '@xmcl/system': - specifier: ^2.2.9 - version: 2.2.9 - '@xmcl/user': - specifier: ^4.3.0 - version: 4.3.0 - uuid: - specifier: ^11.1.0 - version: 11.1.1 - devDependencies: - '@types/node': - specifier: ^22.0.0 - version: 22.19.21 - '@types/uuid': - specifier: ^10.0.0 - version: 10.0.0 - tsx: - specifier: ^4.19.0 - version: 4.22.4 - typescript: - specifier: ~5.8.3 - version: 5.8.3 - -packages: - - '@esbuild/aix-ppc64@0.28.1': - resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.28.1': - resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.28.1': - resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.28.1': - resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.28.1': - resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.28.1': - resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.28.1': - resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.28.1': - resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.28.1': - resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.28.1': - resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.28.1': - resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.28.1': - resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.28.1': - resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.28.1': - resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.28.1': - resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.28.1': - resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.28.1': - resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.28.1': - resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.28.1': - resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.28.1': - resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.28.1': - resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.28.1': - resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.28.1': - resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.28.1': - resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.28.1': - resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.28.1': - resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@types/http-cache-semantics@4.2.0': - resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} - - '@types/node@22.19.21': - resolution: {integrity: sha512-VMeFBSCKQKmm2swI2kW51SFusDqekC6q9trBCvJ/JliDchFSuoYYKN7yVNjPthP1HKZcx3U1gI/wTcEBjEFKTA==} - - '@types/uuid@10.0.0': - resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} - - '@types/yauzl@2.10.3': - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - - '@xmcl/asm@1.0.1': - resolution: {integrity: sha512-7vCVgm1E1IZ2cujiitFk9550Vgu2XAOn1ff90di638fMmTK0XkFMXKsSR/nGZmYKt+XiTMI/0B3TvreqbVjOug==} - engines: {node: '>=16'} - - '@xmcl/bytebuffer@0.1.1': - resolution: {integrity: sha512-Mja7XzIjXgXX/mDNqkVO6X3yltIYo18RYTo3J4UA8Di2TMZp90NRbLJ8PFRWAyDo/R+kNyErvfXMge2eB/q9pg==} - engines: {node: '>=16'} - - '@xmcl/core@2.15.1': - resolution: {integrity: sha512-ldVWtFGRTnQ836oRnex3YiwCogQmy2XdKfdYz9uAoEbXofMrH/Yq/uEK593iQ9iVJa8Rlfik+LjzGAfsYzR1SQ==} - engines: {node: '>=20'} - - '@xmcl/curseforge@2.2.0': - resolution: {integrity: sha512-W1b92Z1IYItIyplq2poWP1NL47buE4LOHWEU+duHCj0xWHI5y4ya2pIyXQhNzsBCSJ+ZZBXzPx/27hBl2PUwcA==} - engines: {node: '>=16.4'} - - '@xmcl/file-transfer@2.0.3': - resolution: {integrity: sha512-IzS1EsmirFF7fHQyJ3Otpu8W7l1vD4qzAlJtFDpkCrMRhfG99smgTiprhlfPzK8XklPe3cq8qKoiEO3v11VI9w==} - engines: {node: '>=20'} - - '@xmcl/forge-site-parser@2.0.9': - resolution: {integrity: sha512-OHKG2KYE+F6TSeOQmymuGoqEifxbJb3w3X/hmxMNeqtewiYukJldPmKO559ZFnZnOuMQEnr+X0dMbTQwWs5dFg==} - engines: {node: '>=16'} - - '@xmcl/installer@6.1.2': - resolution: {integrity: sha512-q0meO1I4oyL0jCd8mfRD8D92ODgTbg+sQvkfilWwG1115EBd1KNBzqFRKYXzkmEGwjrcCdhbA5Q4ECpJ87Ro0Q==} - engines: {node: '>=20'} - - '@xmcl/modrinth@2.5.0': - resolution: {integrity: sha512-OpPpBemZ/yYvphgLVXGV+jESR9n8OceEsMaMvxuFZrIpi9LdYTa2oyVlnZHD7Dte+S+ttD8Y2AUncSJUNFRgNg==} - engines: {node: '>=16.4'} - - '@xmcl/nbt@3.0.2': - resolution: {integrity: sha512-RLv3bkre7wKHZzzaHYn3VUEa4B2HT1wYiP6gqaoxws/4CYT4IUGFO5YJAU/1IKVTUd7wMNQDXorJ9U/LGERPgQ==} - engines: {node: '>=16.4'} - - '@xmcl/system@2.2.9': - resolution: {integrity: sha512-dY9G3SB0G9XYDT6ie/6sdYTMCuSlfTWUDkNOwfrYE8LIh3Cii2u+IcQ8bAT9XAxIcSG6qoe8KP0WOUC/Vn5HjA==} - engines: {node: '>=20'} - - '@xmcl/task@4.1.1': - resolution: {integrity: sha512-UdTf37uBG26hx3UW8oDM5TFTodV0CMTgUKOQu5XGMc2iVEKXuC5rUgVMf6Av7aDAxbgb5LedK/5Ik1lDP9CRRA==} - - '@xmcl/unzip@2.1.2': - resolution: {integrity: sha512-Lm/eg/e0/p+sfj/RT2QDpsBAf39DZqQ3+XvX1JXZPb64wnjwOf8CGU1WPv6BseEcJ5CMOpm0s2NyrEQD04y0UQ==} - engines: {node: '>=16'} - peerDependencies: - yauzl: ^2.10.0 - - '@xmcl/user@4.3.0': - resolution: {integrity: sha512-SHUI86qipZ+Eva1bO2xyKZFelQ8vO/e7Gatu6lEIPc8pkfGRfuAQuC+w+NmxYFUk3uNeDEKzkq6lP+DNJqUcEQ==} - engines: {node: '>=20'} - - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - - core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - - css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} - - css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} - engines: {node: '>= 6'} - - dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - - domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - - domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - - domutils@3.2.2: - resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - esbuild@0.28.1: - resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} - engines: {node: '>=18'} - hasBin: true - - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - - http-cache-semantics@4.2.0: - resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} - - immediate@3.0.6: - resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - - jszip@3.10.1: - resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} - - lie@3.3.0: - resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - - node-html-parser@6.1.13: - resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} - - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - - pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - - pako@2.1.0: - resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} - - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - - setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - - tsx@4.22.4: - resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==} - engines: {node: '>=18.0.0'} - hasBin: true - - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - undici@7.1.1: - resolution: {integrity: sha512-WZkQ6eH9f5ZT93gaIffsbUaDpBwjbpvmMbfaEhOnbdUneurTESeRxwPGwjI28mRFESH3W3e8Togijh37ptOQqA==} - engines: {node: '>=20.18.1'} - - undici@7.2.3: - resolution: {integrity: sha512-2oSLHaDalSt2/O/wHA9M+/ZPAOcU2yrSP/cdBYJ+YxZskiPYDSqHbysLSlD7gq3JMqOoJI5O31RVU3BxX/MnAA==} - engines: {node: '>=20.18.1'} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - uuid@11.1.1: - resolution: {integrity: sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==} - hasBin: true - - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - - yazl@2.5.1: - resolution: {integrity: sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==} - -snapshots: - - '@esbuild/aix-ppc64@0.28.1': - optional: true - - '@esbuild/android-arm64@0.28.1': - optional: true - - '@esbuild/android-arm@0.28.1': - optional: true - - '@esbuild/android-x64@0.28.1': - optional: true - - '@esbuild/darwin-arm64@0.28.1': - optional: true - - '@esbuild/darwin-x64@0.28.1': - optional: true - - '@esbuild/freebsd-arm64@0.28.1': - optional: true - - '@esbuild/freebsd-x64@0.28.1': - optional: true - - '@esbuild/linux-arm64@0.28.1': - optional: true - - '@esbuild/linux-arm@0.28.1': - optional: true - - '@esbuild/linux-ia32@0.28.1': - optional: true - - '@esbuild/linux-loong64@0.28.1': - optional: true - - '@esbuild/linux-mips64el@0.28.1': - optional: true - - '@esbuild/linux-ppc64@0.28.1': - optional: true - - '@esbuild/linux-riscv64@0.28.1': - optional: true - - '@esbuild/linux-s390x@0.28.1': - optional: true - - '@esbuild/linux-x64@0.28.1': - optional: true - - '@esbuild/netbsd-arm64@0.28.1': - optional: true - - '@esbuild/netbsd-x64@0.28.1': - optional: true - - '@esbuild/openbsd-arm64@0.28.1': - optional: true - - '@esbuild/openbsd-x64@0.28.1': - optional: true - - '@esbuild/openharmony-arm64@0.28.1': - optional: true - - '@esbuild/sunos-x64@0.28.1': - optional: true - - '@esbuild/win32-arm64@0.28.1': - optional: true - - '@esbuild/win32-ia32@0.28.1': - optional: true - - '@esbuild/win32-x64@0.28.1': - optional: true - - '@types/http-cache-semantics@4.2.0': {} - - '@types/node@22.19.21': - dependencies: - undici-types: 6.21.0 - - '@types/uuid@10.0.0': {} - - '@types/yauzl@2.10.3': - dependencies: - '@types/node': 22.19.21 - - '@xmcl/asm@1.0.1': {} - - '@xmcl/bytebuffer@0.1.1': {} - - '@xmcl/core@2.15.1(yauzl@2.10.0)': - dependencies: - '@xmcl/unzip': 2.1.2(yauzl@2.10.0) - transitivePeerDependencies: - - yauzl - - '@xmcl/curseforge@2.2.0': - dependencies: - undici: 7.1.1 - - '@xmcl/file-transfer@2.0.3': - dependencies: - '@types/http-cache-semantics': 4.2.0 - http-cache-semantics: 4.2.0 - undici: 7.2.3 - - '@xmcl/forge-site-parser@2.0.9': - dependencies: - node-html-parser: 6.1.13 - - '@xmcl/installer@6.1.2': - dependencies: - '@xmcl/asm': 1.0.1 - '@xmcl/core': 2.15.1(yauzl@2.10.0) - '@xmcl/file-transfer': 2.0.3 - '@xmcl/forge-site-parser': 2.0.9 - '@xmcl/task': 4.1.1 - '@xmcl/unzip': 2.1.2(yauzl@2.10.0) - undici: 7.2.3 - yauzl: 2.10.0 - yazl: 2.5.1 - - '@xmcl/modrinth@2.5.0': - dependencies: - undici: 7.2.3 - - '@xmcl/nbt@3.0.2': - dependencies: - '@xmcl/bytebuffer': 0.1.1 - pako: 2.1.0 - - '@xmcl/system@2.2.9': - dependencies: - '@xmcl/unzip': 2.1.2(yauzl@2.10.0) - jszip: 3.10.1 - yauzl: 2.10.0 - - '@xmcl/task@4.1.1': {} - - '@xmcl/unzip@2.1.2(yauzl@2.10.0)': - dependencies: - '@types/yauzl': 2.10.3 - yauzl: 2.10.0 - - '@xmcl/user@4.3.0': - dependencies: - undici: 7.2.3 - uuid: 9.0.1 - - boolbase@1.0.0: {} - - buffer-crc32@0.2.13: {} - - core-util-is@1.0.3: {} - - css-select@5.2.2: - dependencies: - boolbase: 1.0.0 - css-what: 6.2.2 - domhandler: 5.0.3 - domutils: 3.2.2 - nth-check: 2.1.1 - - css-what@6.2.2: {} - - dom-serializer@2.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - - domelementtype@2.3.0: {} - - domhandler@5.0.3: - dependencies: - domelementtype: 2.3.0 - - domutils@3.2.2: - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - - entities@4.5.0: {} - - esbuild@0.28.1: - optionalDependencies: - '@esbuild/aix-ppc64': 0.28.1 - '@esbuild/android-arm': 0.28.1 - '@esbuild/android-arm64': 0.28.1 - '@esbuild/android-x64': 0.28.1 - '@esbuild/darwin-arm64': 0.28.1 - '@esbuild/darwin-x64': 0.28.1 - '@esbuild/freebsd-arm64': 0.28.1 - '@esbuild/freebsd-x64': 0.28.1 - '@esbuild/linux-arm': 0.28.1 - '@esbuild/linux-arm64': 0.28.1 - '@esbuild/linux-ia32': 0.28.1 - '@esbuild/linux-loong64': 0.28.1 - '@esbuild/linux-mips64el': 0.28.1 - '@esbuild/linux-ppc64': 0.28.1 - '@esbuild/linux-riscv64': 0.28.1 - '@esbuild/linux-s390x': 0.28.1 - '@esbuild/linux-x64': 0.28.1 - '@esbuild/netbsd-arm64': 0.28.1 - '@esbuild/netbsd-x64': 0.28.1 - '@esbuild/openbsd-arm64': 0.28.1 - '@esbuild/openbsd-x64': 0.28.1 - '@esbuild/openharmony-arm64': 0.28.1 - '@esbuild/sunos-x64': 0.28.1 - '@esbuild/win32-arm64': 0.28.1 - '@esbuild/win32-ia32': 0.28.1 - '@esbuild/win32-x64': 0.28.1 - - fd-slicer@1.1.0: - dependencies: - pend: 1.2.0 - - fsevents@2.3.3: - optional: true - - he@1.2.0: {} - - http-cache-semantics@4.2.0: {} - - immediate@3.0.6: {} - - inherits@2.0.4: {} - - isarray@1.0.0: {} - - jszip@3.10.1: - dependencies: - lie: 3.3.0 - pako: 1.0.11 - readable-stream: 2.3.8 - setimmediate: 1.0.5 - - lie@3.3.0: - dependencies: - immediate: 3.0.6 - - node-html-parser@6.1.13: - dependencies: - css-select: 5.2.2 - he: 1.2.0 - - nth-check@2.1.1: - dependencies: - boolbase: 1.0.0 - - pako@1.0.11: {} - - pako@2.1.0: {} - - pend@1.2.0: {} - - process-nextick-args@2.0.1: {} - - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - - safe-buffer@5.1.2: {} - - setimmediate@1.0.5: {} - - string_decoder@1.1.1: - dependencies: - safe-buffer: 5.1.2 - - tsx@4.22.4: - dependencies: - esbuild: 0.28.1 - optionalDependencies: - fsevents: 2.3.3 - - typescript@5.8.3: {} - - undici-types@6.21.0: {} - - undici@7.1.1: {} - - undici@7.2.3: {} - - util-deprecate@1.0.2: {} - - uuid@11.1.1: {} - - uuid@9.0.1: {} - - yauzl@2.10.0: - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - - yazl@2.5.1: - dependencies: - buffer-crc32: 0.2.13 diff --git a/sidecar/src/core/auth.ts b/sidecar/src/core/auth.ts deleted file mode 100644 index ff3bdd3..0000000 --- a/sidecar/src/core/auth.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { MicrosoftAuthenticator, offline } from "@xmcl/user"; - -export interface AuthResult { - username: string; - uuid: string; - accessToken: string; - expiresAt?: number; - xboxProfile?: { - gamertag: string; - displayPicRaw: string; - }; -} - -export async function microsoftLoginStart(clientId: string, redirectUri?: string) { - const state = Math.random().toString(36).substring(2, 15); - const scope = "XboxLive.signin offline_access"; - const redirect = redirectUri || "https://login.live.com/oauth20_desktop.srf"; - - const authUrl = `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?` + - `client_id=${clientId}` + - `&response_type=code` + - `&scope=${encodeURIComponent(scope)}` + - `&state=${state}` + - `&redirect_uri=${encodeURIComponent(redirect)}`; - - return { state, authUrl }; -} - -export async function microsoftLoginCallback( - code: string, - clientId: string, - redirectUri?: string -): Promise { - const redirect = redirectUri || "https://login.live.com/oauth20_desktop.srf"; - - // Step 1: Exchange code for MS access token - const tokenResponse = await fetch( - "https://login.microsoftonline.com/common/oauth2/v2.0/token", - { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: new URLSearchParams({ - client_id: clientId, - code, - grant_type: "authorization_code", - redirect_uri: redirect, - }), - } - ); - - if (!tokenResponse.ok) { - const err = await tokenResponse.text(); - throw new Error(`MS token exchange failed: ${err}`); - } - - const tokenData = await tokenResponse.json() as { access_token: string }; - const msAccessToken = tokenData.access_token; - - // Step 2+3: Xbox + Minecraft auth - const authenticator = new MicrosoftAuthenticator({ fetch }); - const { liveXstsResponse, minecraftXstsResponse } = - await authenticator.acquireXBoxToken(msAccessToken); - - const mcResponse = await authenticator.loginMinecraftWithXBox( - minecraftXstsResponse.DisplayClaims.xui[0].uhs, - minecraftXstsResponse.Token - ); - - // Get Xbox profile - let xboxProfile; - try { - const profile = await authenticator.getXboxGameProfile( - liveXstsResponse.DisplayClaims.xui[0].xid, - liveXstsResponse.DisplayClaims.xui[0].uhs, - liveXstsResponse.Token - ); - const settings = profile.profileUsers[0]?.settings; - if (settings) { - xboxProfile = { - gamertag: settings.find(s => s.id === "Gamertag")?.value || "", - displayPicRaw: settings.find(s => s.id === "PublicGamerpic")?.value || "", - }; - } - } catch { - // Xbox profile is optional - } - - return { - username: mcResponse.username, - uuid: mcResponse.username, - accessToken: mcResponse.access_token, - expiresAt: mcResponse.expires_in - ? Date.now() + mcResponse.expires_in * 1000 - : undefined, - xboxProfile, - }; -} - -export function offlineLogin(username: string, uuid?: string): AuthResult { - const user = offline(username, uuid); - return { - username: user.selectedProfile.name, - uuid: user.selectedProfile.id, - accessToken: user.accessToken, - }; -} - -export async function validateMinecraftToken(accessToken: string): Promise { - try { - const response = await fetch( - "https://api.minecraftservices.com/minecraft/profile", - { - headers: { - Authorization: `Bearer ${accessToken}`, - }, - } - ); - return response.ok; - } catch { - return false; - } -} - -export async function refreshMicrosoftToken( - refreshToken: string, - clientId: string -) { - const response = await fetch( - "https://login.microsoftonline.com/common/oauth2/v2.0/token", - { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: new URLSearchParams({ - client_id: clientId, - refresh_token: refreshToken, - grant_type: "refresh_token", - }), - } - ); - - if (!response.ok) { - throw new Error("Failed to refresh MS token"); - } - - return response.json(); -} diff --git a/sidecar/src/core/installer.ts b/sidecar/src/core/installer.ts deleted file mode 100644 index 9046952..0000000 --- a/sidecar/src/core/installer.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { - getVersionList, - install, - installForge, - installFabric, - installDependencies, - getForgeVersionList, - getFabricLoaders, - getQuiltLoaders, - installQuiltVersion, -} from "@xmcl/installer"; -import { sendProgress } from "../protocol/transport.js"; - -function progressCallback(requestId: string) { - return (total: number, cur: number, message?: string) => { - sendProgress(requestId, { - stage: message || "downloading", - current: cur, - total, - }); - }; -} - -export async function getVersionListAsync(type: string = "all") { - const manifest = await getVersionList(); - if (type === "all") return manifest; - const filtered = manifest.versions.filter((v) => v.type === type); - return { latest: manifest.latest, versions: filtered }; -} - -export async function installMinecraft( - requestId: string, - version: string, - gamePath: string, - javaPath?: string, - _downloadThreads?: number -) { - await install({ id: version, url: "" }, gamePath, { - java: javaPath, - progress: progressCallback(requestId), - } as any); - - return { version, gamePath }; -} - -export async function installForgeLoader( - requestId: string, - mcVersion: string, - gamePath: string, - javaPath?: string, - forgeVersion?: string -) { - const version = forgeVersion || mcVersion; - - await installForge({ - mcversion: mcVersion, - version: version, - }, gamePath, { - java: javaPath, - progress: progressCallback(requestId), - } as any); - - return { loaderType: "forge", mcVersion, forgeVersion: version }; -} - -export async function installFabricLoader( - requestId: string, - mcVersion: string, - gamePath: string, - loaderVersion?: string -) { - const loaders = await getFabricLoaders(); - const targetLoader = loaderVersion - ? loaders.find((l) => l.version === loaderVersion) - : loaders[loaders.length - 1]; - - if (!targetLoader) { - throw new Error(`Fabric loader not found: ${loaderVersion}`); - } - - await installFabric({ - mcVersion, - loaderVersion: targetLoader.version, - gamePath, - progress: progressCallback(requestId), - } as any); - - return { loaderType: "fabric", mcVersion, loaderVersion: targetLoader.version }; -} - -export async function installQuiltLoader( - requestId: string, - mcVersion: string, - gamePath: string, - loaderVersion?: string -) { - const loaders = await getQuiltLoaders(); - const targetLoader = loaderVersion - ? loaders.find((l) => l.version === loaderVersion) - : loaders[loaders.length - 1]; - - if (!targetLoader) { - throw new Error(`Quilt loader not found: ${loaderVersion}`); - } - - await installQuiltVersion({ - minecraftVersion: mcVersion, - version: targetLoader.version, - minecraft: gamePath, - }); - - return { loaderType: "quilt", mcVersion, loaderVersion: targetLoader.version }; -} - -export async function getForgeVersions(mcVersion?: string) { - const list = await getForgeVersionList(); - if (mcVersion) { - const versions = list.versions.filter((v) => v.mcversion === mcVersion); - return { mcVersion, versions }; - } - return list; -} - -export async function getFabricVersions(mcVersion?: string) { - const loaders = await getFabricLoaders(); - if (mcVersion) { - return { mcVersion, loaders }; - } - return { loaders }; -} - -export async function ensureDependencies( - requestId: string, - gamePath: string, - versionId: string -) { - const { Version } = await import("@xmcl/core"); - const resolved = await Version.parse(gamePath, versionId); - await installDependencies(resolved, { - progress: progressCallback(requestId), - } as any); - return { version: versionId }; -} diff --git a/sidecar/src/core/launcher.ts b/sidecar/src/core/launcher.ts deleted file mode 100644 index 6bfceaa..0000000 --- a/sidecar/src/core/launcher.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { - launch as xmclLaunch, - diagnose as xmclDiagnose, - createMinecraftProcessWatcher, - Version, - type LaunchOption, -} from "@xmcl/core"; -import { sendEvent } from "../protocol/transport.js"; - -export async function launchMinecraft(requestId: string, options: { - gamePath: string; - javaPath: string; - version: string; - username: string; - uuid: string; - accessToken?: string; - memory?: { min?: string; max?: string }; - jvmArgs?: string[]; - gameArgs?: string[]; - server?: { ip: string; port?: number }; - detached?: boolean; -}) { - const launchOption: LaunchOption = { - gamePath: options.gamePath, - javaPath: options.javaPath, - version: options.version, - gameProfile: { - name: options.username, - id: options.uuid, - }, - accessToken: options.accessToken || "", - extraExecOption: options.detached ? { detached: true } : undefined, - minMemory: options.memory?.min ? parseInt(options.memory.min) : undefined, - maxMemory: options.memory?.max ? parseInt(options.memory.max) : undefined, - extraJVMArgs: options.jvmArgs, - extraMCArgs: options.gameArgs, - server: options.server, - }; - - const proc = await xmclLaunch(launchOption); - - const watcher = createMinecraftProcessWatcher(proc); - - watcher.on("error", (error: any) => { - sendEvent(requestId, { event: "error", message: error.message || String(error) }); - }); - - watcher.on("minecraft-exit", (event) => { - sendEvent(requestId, { event: "exit", code: event.code, signal: event.signal }); - }); - - watcher.on("minecraft-window-ready", () => { - sendEvent(requestId, { event: "window-ready" }); - }); - - proc.on("error", (err) => { - sendEvent(requestId, { event: "process-error", message: err.message }); - }); - - return { - pid: proc.pid, - version: options.version, - username: options.username, - }; -} - -export async function diagnoseVersion(gamePath: string, versionId: string) { - const report = await xmclDiagnose(versionId, gamePath); - return report; -} - -export async function parseVersion(gamePath: string, versionId: string) { - const resolved = await Version.parse(gamePath, versionId); - return { - id: resolved.id, - type: resolved.type, - mainClass: resolved.mainClass, - }; -} diff --git a/sidecar/src/core/modrinth.ts b/sidecar/src/core/modrinth.ts deleted file mode 100644 index a9afc49..0000000 --- a/sidecar/src/core/modrinth.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { ModrinthV2Client, type SearchResultHit, type ProjectVersion, type Project } from "@xmcl/modrinth"; -import { CurseforgeV1Client } from "@xmcl/curseforge"; -import { sendProgress } from "../protocol/transport.js"; - -const modrinth = new ModrinthV2Client(); -const curseforge = new CurseforgeV1Client(""); - -export interface ModSearchResult { - id: string; - slug: string; - name: string; - description: string; - downloads: number; - iconUrl?: string; - categories?: string[]; - versions?: string[]; - loaders?: string[]; - source: "modrinth" | "curseforge"; -} - -export interface ModVersionResult { - id: string; - name: string; - versionNumber: string; - gameVersions: string[]; - loaders: string[]; - files: { - filename: string; - url: string; - size: number; - primary: boolean; - }[]; -} - -export async function searchMods( - query?: string, - gameVersion?: string, - loader?: string, - limit: number = 20, - offset: number = 0, - source: "modrinth" | "curseforge" = "modrinth" -): Promise { - if (source === "modrinth") { - const facets: string[] = []; - if (gameVersion) facets.push(`versions:${gameVersion}`); - if (loader) facets.push(`categories:${loader}`); - - const result = await modrinth.searchProjects({ - query: query || "", - limit, - offset, - facets: facets.length > 0 ? JSON.stringify([facets]) : undefined, - }); - - return result.hits.map((hit: SearchResultHit) => ({ - id: hit.project_id, - slug: hit.slug, - name: hit.title, - description: hit.description, - downloads: hit.downloads, - iconUrl: hit.icon_url, - categories: hit.categories, - versions: hit.versions, - source: "modrinth" as const, - })); - } - - // CurseForge - const result = await curseforge.searchMods({ - gameId: 432, - classId: 6, - searchFilter: query, - gameVersion, - pageSize: limit, - index: offset, - }); - - return result.data.map((mod) => ({ - id: String(mod.id), - slug: mod.slug, - name: mod.name, - description: mod.summary, - downloads: mod.downloadCount, - iconUrl: mod.logo?.thumbnailUrl, - source: "curseforge" as const, - })); -} - -export async function getModDetail( - projectId: string, - source: "modrinth" | "curseforge" -) { - if (source === "modrinth") { - const project = await modrinth.getProject(projectId); - return { - id: project.id, - slug: project.slug, - name: project.title, - description: project.description, - body: project.body, - downloads: project.downloads, - iconUrl: project.icon_url, - categories: project.categories, - versions: project.versions, - source: "modrinth" as const, - }; - } - - const mod = await curseforge.getMod(Number(projectId)); - return { - id: String(mod.id), - slug: mod.slug, - name: mod.name, - description: mod.summary, - body: mod.summary, - downloads: mod.downloadCount, - iconUrl: mod.logo?.thumbnailUrl, - source: "curseforge" as const, - }; -} - -export async function getModVersions( - projectId: string, - gameVersion?: string, - loader?: string, - source: "modrinth" | "curseforge" = "modrinth" -): Promise { - if (source === "modrinth") { - const versions = await modrinth.getProjectVersions(projectId, { - loaders: loader ? [loader] : undefined, - gameVersions: gameVersion ? [gameVersion] : undefined, - }); - - return versions.map((v: ProjectVersion) => ({ - id: v.id, - name: v.name, - versionNumber: v.version_number, - gameVersions: v.game_versions, - loaders: v.loaders, - files: v.files.map((f) => ({ - filename: f.filename, - url: f.url, - size: f.size, - primary: f.primary, - })), - })); - } - - const versions = await curseforge.getModFiles({ - modId: Number(projectId), - gameVersion, - }); - - return versions.data.map((v) => ({ - id: String(v.id), - name: v.displayName, - versionNumber: v.fileName, - gameVersions: v.gameVersions, - loaders: [], - files: [ - { - filename: v.fileName, - url: v.downloadUrl || "", - size: v.fileLength, - primary: true, - }, - ], - })); -} - -export async function installMod( - requestId: string, - projectId: string, - versionId: string | undefined, - gamePath: string, - source: "modrinth" | "curseforge" -) { - if (source === "modrinth") { - const versions = await modrinth.getProjectVersions(projectId); - const version = versionId - ? versions.find((v: ProjectVersion) => v.id === versionId) - : versions[0]; - - if (!version) { - throw new Error("No version found"); - } - - const primaryFile = version.files.find((f) => f.primary) || version.files[0]; - - if (!primaryFile) { - throw new Error("No file found in version"); - } - - // Download the mod file - const modsDir = `${gamePath}/mods`; - const { ensureDir } = await import("../utils/paths.js"); - ensureDir(modsDir); - - const response = await fetch(primaryFile.url); - if (!response.ok) { - throw new Error(`Failed to download mod: ${response.statusText}`); - } - - const buffer = Buffer.from(await response.arrayBuffer()); - const { writeFileSync } = await import("fs"); - const { join } = await import("path"); - const filePath = join(modsDir, primaryFile.filename); - writeFileSync(filePath, buffer); - - sendProgress(requestId, { - stage: "mod-installed", - current: 1, - total: 1, - message: primaryFile.filename, - }); - - return { - projectId, - versionId: version.id, - filename: primaryFile.filename, - path: filePath, - }; - } - - throw new Error("CurseForge mod install not yet implemented"); -} diff --git a/sidecar/src/handlers/auth.ts b/sidecar/src/handlers/auth.ts deleted file mode 100644 index b5fde96..0000000 --- a/sidecar/src/handlers/auth.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { sendResult, sendError } from "../protocol/transport.js"; -import type { - MicrosoftLoginStartRequest, - MicrosoftLoginCallbackRequest, - OfflineLoginRequest, - ValidateTokenRequest, -} from "../protocol/types.js"; -import * as auth from "../core/auth.js"; - -export async function handleMicrosoftLoginStart( - id: string, - payload: MicrosoftLoginStartRequest -) { - try { - const result = await auth.microsoftLoginStart( - payload.client_id, - payload.redirect_uri - ); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleMicrosoftLoginCallback( - id: string, - payload: MicrosoftLoginCallbackRequest -) { - try { - const result = await auth.microsoftLoginCallback( - payload.code, - payload.client_id - ); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleOfflineLogin(id: string, payload: OfflineLoginRequest) { - try { - const result = auth.offlineLogin(payload.username); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleValidateToken(id: string, payload: ValidateTokenRequest) { - try { - const valid = await auth.validateMinecraftToken(payload.accessToken); - sendResult(id, { valid }); - } catch (e: any) { - sendError(id, e.message); - } -} diff --git a/sidecar/src/handlers/background.ts b/sidecar/src/handlers/background.ts deleted file mode 100644 index 01568ca..0000000 --- a/sidecar/src/handlers/background.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { sendResult, sendError } from "../protocol/transport.js"; -import type { - SetBackgroundImageRequest, - SetBackgroundColorRequest, - SetBackgroundBlurRequest, - SetBackgroundOpacityRequest, - SetBackgroundAnimationRequest, - SetBackgroundThemeRequest, - BackgroundConfig, -} from "../protocol/types.js"; - -// In-memory background config (persisted to config file in production) -let config: BackgroundConfig = { - type: "color", - color: "#1a1a2e", - blur: 0, - opacity: 1, - animation: "none", - animationSpeed: 1, - theme: "dark", -}; - -export async function handleSetBackgroundImage(id: string, payload: SetBackgroundImageRequest) { - try { - config.type = "image"; - config.image = payload.url; - if (payload.blur !== undefined) config.blur = payload.blur; - if (payload.opacity !== undefined) config.opacity = payload.opacity; - sendResult(id, config); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleSetBackgroundColor(id: string, payload: SetBackgroundColorRequest) { - try { - config.type = "color"; - config.color = payload.color; - sendResult(id, config); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleSetBackgroundBlur(id: string, payload: SetBackgroundBlurRequest) { - try { - config.blur = Math.max(0, Math.min(20, payload.blur)); - sendResult(id, config); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleSetBackgroundOpacity(id: string, payload: SetBackgroundOpacityRequest) { - try { - config.opacity = Math.max(0, Math.min(1, payload.opacity)); - sendResult(id, config); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleSetBackgroundAnimation(id: string, payload: SetBackgroundAnimationRequest) { - try { - config.animation = payload.type; - if (payload.speed !== undefined) config.animationSpeed = payload.speed; - if (payload.type === "gradient" || payload.type === "particles") { - config.type = payload.type; - } - sendResult(id, config); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleGetBackground(id: string) { - try { - sendResult(id, config); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleSetBackgroundTheme(id: string, payload: SetBackgroundThemeRequest) { - try { - config.theme = payload.theme; - sendResult(id, config); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleResetBackground(id: string) { - try { - config = { - type: "color", - color: "#1a1a2e", - blur: 0, - opacity: 1, - animation: "none", - animationSpeed: 1, - theme: "dark", - }; - sendResult(id, config); - } catch (e: any) { - sendError(id, e.message); - } -} diff --git a/sidecar/src/handlers/install.ts b/sidecar/src/handlers/install.ts deleted file mode 100644 index 2dea0d0..0000000 --- a/sidecar/src/handlers/install.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { sendProgress, sendResult, sendError } from "../protocol/transport.js"; -import type { - InstallMinecraftRequest, - InstallModLoaderRequest, - GetVersionListRequest, - GetForgeVersionListRequest, - GetFabricVersionListRequest, -} from "../protocol/types.js"; -import * as installer from "../core/installer.js"; - -export async function handleInstallMinecraft(id: string, payload: InstallMinecraftRequest) { - try { - sendProgress(id, { stage: "starting", current: 0, total: 1 }); - const result = await installer.installMinecraft( - id, - payload.version, - payload.gamePath, - payload.javaPath, - payload.downloadThreads - ); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleInstallModLoader(id: string, payload: InstallModLoaderRequest) { - try { - sendProgress(id, { stage: "starting", current: 0, total: 1 }); - let result; - - switch (payload.loaderType) { - case "forge": - result = await installer.installForgeLoader( - id, - payload.mcVersion, - payload.gamePath, - payload.javaPath, - payload.loaderVersion - ); - break; - case "fabric": - result = await installer.installFabricLoader( - id, - payload.mcVersion, - payload.gamePath, - payload.loaderVersion - ); - break; - case "quilt": - result = await installer.installQuiltLoader( - id, - payload.mcVersion, - payload.gamePath, - payload.loaderVersion - ); - break; - case "neoforge": - throw new Error("NeoForge not yet supported"); - default: - throw new Error(`Unknown loader type: ${payload.loaderType}`); - } - - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleGetVersionList(id: string, payload: GetVersionListRequest) { - try { - const result = await installer.getVersionListAsync(payload.type || "all"); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleGetForgeVersionList(id: string, payload: GetForgeVersionListRequest) { - try { - const result = await installer.getForgeVersions(payload.mcVersion); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleGetFabricVersionList(id: string, payload: GetFabricVersionListRequest) { - try { - const result = await installer.getFabricVersions(payload.mcVersion); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} diff --git a/sidecar/src/handlers/instance.ts b/sidecar/src/handlers/instance.ts deleted file mode 100644 index 1eae945..0000000 --- a/sidecar/src/handlers/instance.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { existsSync, readdirSync, rmSync } from "fs"; -import { join } from "path"; -import { sendResult, sendError } from "../protocol/transport.js"; -import type { - CreateInstanceRequest, - ListInstancesRequest, - DeleteInstanceRequest, - GetInstanceInfoRequest, -} from "../protocol/types.js"; -import { - ensureDir, - getInstancePath, - readInstanceConfig, - writeInstanceConfig, - type InstanceConfig, -} from "../utils/paths.js"; - -export async function handleCreateInstance(id: string, payload: CreateInstanceRequest) { - try { - const instancePath = getInstancePath(payload.instancesPath, payload.name); - - if (existsSync(instancePath)) { - throw new Error(`Instance "${payload.name}" already exists`); - } - - ensureDir(instancePath); - - const config: InstanceConfig = { - name: payload.name, - mcVersion: payload.mcVersion, - loaderType: payload.loaderType, - loaderVersion: payload.loaderVersion, - javaPath: payload.javaPath, - memory: payload.memory, - createdAt: new Date().toISOString(), - }; - - writeInstanceConfig(instancePath, config); - - // Create standard directories - ensureDir(join(instancePath, "mods")); - ensureDir(join(instancePath, "resourcepacks")); - ensureDir(join(instancePath, "saves")); - ensureDir(join(instancePath, "config")); - - sendResult(id, { - name: payload.name, - path: instancePath, - config, - }); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleListInstances(id: string, payload: ListInstancesRequest) { - try { - const instancesPath = payload.instancesPath; - - if (!existsSync(instancesPath)) { - ensureDir(instancesPath); - sendResult(id, []); - return; - } - - const entries = readdirSync(instancesPath, { withFileTypes: true }); - const instances = entries - .filter((e) => e.isDirectory()) - .map((e) => { - const config = readInstanceConfig(join(instancesPath, e.name)); - return { - name: e.name, - path: join(instancesPath, e.name), - config, - }; - }) - .filter((i) => i.config !== null); - - sendResult(id, instances); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleDeleteInstance(id: string, payload: DeleteInstanceRequest) { - try { - const instancePath = getInstancePath(payload.instancesPath, payload.name); - - if (!existsSync(instancePath)) { - throw new Error(`Instance "${payload.name}" not found`); - } - - rmSync(instancePath, { recursive: true, force: true }); - - sendResult(id, { deleted: payload.name }); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleGetInstanceInfo(id: string, payload: GetInstanceInfoRequest) { - try { - const instancePath = getInstancePath(payload.instancesPath, payload.name); - - if (!existsSync(instancePath)) { - throw new Error(`Instance "${payload.name}" not found`); - } - - const config = readInstanceConfig(instancePath); - if (!config) { - throw new Error(`Instance "${payload.name}" has no config`); - } - - // Count mods - const modsPath = join(instancePath, "mods"); - let modCount = 0; - if (existsSync(modsPath)) { - modCount = readdirSync(modsPath).filter((f) => f.endsWith(".jar")).length; - } - - sendResult(id, { - name: payload.name, - path: instancePath, - config, - modCount, - }); - } catch (e: any) { - sendError(id, e.message); - } -} diff --git a/sidecar/src/handlers/launch.ts b/sidecar/src/handlers/launch.ts deleted file mode 100644 index 153d83c..0000000 --- a/sidecar/src/handlers/launch.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { sendResult, sendError } from "../protocol/transport.js"; -import type { LaunchRequest, DiagnoseRequest } from "../protocol/types.js"; -import * as launcher from "../core/launcher.js"; - -export async function handleLaunch(id: string, payload: LaunchRequest) { - try { - const result = await launcher.launchMinecraft(id, payload); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleDiagnose(id: string, payload: DiagnoseRequest) { - try { - const result = await launcher.diagnoseVersion(payload.gamePath, payload.version); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} diff --git a/sidecar/src/handlers/mods.ts b/sidecar/src/handlers/mods.ts deleted file mode 100644 index 533bb3e..0000000 --- a/sidecar/src/handlers/mods.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { sendResult, sendError } from "../protocol/transport.js"; -import type { - SearchModsRequest, - GetModDetailRequest, - GetModVersionsRequest, - InstallModRequest, -} from "../protocol/types.js"; -import * as modrinth from "../core/modrinth.js"; - -export async function handleSearchMods(id: string, payload: SearchModsRequest) { - try { - const result = await modrinth.searchMods( - payload.query, - payload.gameVersion, - payload.loader, - payload.limit, - payload.offset, - payload.source - ); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleGetModDetail(id: string, payload: GetModDetailRequest) { - try { - const result = await modrinth.getModDetail(payload.projectId, payload.source); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleGetModVersions(id: string, payload: GetModVersionsRequest) { - try { - const result = await modrinth.getModVersions( - payload.projectId, - payload.gameVersion, - payload.loader, - payload.source - ); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} - -export async function handleInstallMod(id: string, payload: InstallModRequest) { - try { - const result = await modrinth.installMod( - id, - payload.projectId, - payload.versionId, - payload.gamePath, - payload.source - ); - sendResult(id, result); - } catch (e: any) { - sendError(id, e.message); - } -} diff --git a/sidecar/src/index.ts b/sidecar/src/index.ts deleted file mode 100644 index 968f51b..0000000 --- a/sidecar/src/index.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { startTransport, sendError, sendEvent } from "./protocol/transport.js"; -import type { Request } from "./protocol/types.js"; - -import { - handleInstallMinecraft, - handleInstallModLoader, - handleGetVersionList, - handleGetForgeVersionList, - handleGetFabricVersionList, -} from "./handlers/install.js"; - -import { - handleLaunch, - handleDiagnose, -} from "./handlers/launch.js"; - -import { - handleMicrosoftLoginStart, - handleMicrosoftLoginCallback, - handleOfflineLogin, - handleValidateToken, -} from "./handlers/auth.js"; - -import { - handleSearchMods, - handleGetModDetail, - handleGetModVersions, - handleInstallMod, -} from "./handlers/mods.js"; - -import { - handleCreateInstance, - handleListInstances, - handleDeleteInstance, - handleGetInstanceInfo, -} from "./handlers/instance.js"; - -import { - handleSetBackgroundImage, - handleSetBackgroundColor, - handleSetBackgroundBlur, - handleSetBackgroundOpacity, - handleSetBackgroundAnimation, - handleGetBackground, - handleSetBackgroundTheme, - handleResetBackground, -} from "./handlers/background.js"; - -const handlers: Record Promise> = { - // Install - "install:minecraft": handleInstallMinecraft, - "install:mod-loader": handleInstallModLoader, - "install:version-list": handleGetVersionList, - "install:forge-version-list": handleGetForgeVersionList, - "install:fabric-version-list": handleGetFabricVersionList, - - // Launch - "launch:launch": handleLaunch, - "launch:diagnose": handleDiagnose, - - // Auth - "auth:microsoft-login-start": handleMicrosoftLoginStart, - "auth:microsoft-login-callback": handleMicrosoftLoginCallback, - "auth:offline-login": handleOfflineLogin, - "auth:validate-token": handleValidateToken, - - // Mods - "mods:search": handleSearchMods, - "mods:detail": handleGetModDetail, - "mods:versions": handleGetModVersions, - "mods:install": handleInstallMod, - - // Instance - "instance:create": handleCreateInstance, - "instance:list": handleListInstances, - "instance:delete": handleDeleteInstance, - "instance:info": handleGetInstanceInfo, - - // Background - "background:set-image": handleSetBackgroundImage, - "background:set-color": handleSetBackgroundColor, - "background:set-blur": handleSetBackgroundBlur, - "background:set-opacity": handleSetBackgroundOpacity, - "background:set-animation": handleSetBackgroundAnimation, - "background:get": handleGetBackground, - "background:set-theme": handleSetBackgroundTheme, - "background:reset": handleResetBackground, -}; - -async function onMessage(msg: Request) { - const handler = handlers[msg.type]; - if (!handler) { - sendError(msg.id, `Unknown handler: ${msg.type}`); - return; - } - - try { - await handler(msg.id, msg.payload); - } catch (e: any) { - sendError(msg.id, e.message || "Internal error"); - } -} - -process.stderr.write("[koring-sidecar] starting\n"); -startTransport(onMessage); diff --git a/sidecar/src/protocol/transport.ts b/sidecar/src/protocol/transport.ts deleted file mode 100644 index 7f53040..0000000 --- a/sidecar/src/protocol/transport.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Request, Response, ProgressPayload, ResultPayload } from "./types.js"; -import { randomUUID } from "crypto"; - -type MessageHandler = (msg: Request) => void; - -let buffer = ""; - -function sendResponse(id: string, type: Response["type"], payload: T) { - const msg: Response = { id, type, payload }; - process.stdout.write(JSON.stringify(msg) + "\n"); -} - -export function sendProgress(id: string, progress: ProgressPayload) { - sendResponse(id, "progress", progress); -} - -export function sendResult(id: string, data: T) { - sendResponse>(id, "result", { success: true, data }); -} - -export function sendError(id: string, error: string) { - sendResponse(id, "result", { success: false, error }); -} - -export function sendEvent(id: string, event: T) { - sendResponse(id, "event", event); -} - -export function startTransport(onMessage: MessageHandler) { - process.stdin.setEncoding("utf-8"); - - process.stdin.on("data", (chunk: string) => { - buffer += chunk; - const lines = buffer.split("\n"); - buffer = lines.pop() || ""; - - for (const line of lines) { - const trimmed = line.trim(); - if (!trimmed) continue; - try { - const msg: Request = JSON.parse(trimmed); - onMessage(msg); - } catch (e) { - process.stderr.write(`[transport] parse error: ${e}\n`); - } - } - }); - - process.stdin.on("end", () => { - process.exit(0); - }); - - process.stderr.write("[transport] ready\n"); -} - -export function createRequestId(): string { - return randomUUID(); -} diff --git a/sidecar/src/protocol/types.ts b/sidecar/src/protocol/types.ts deleted file mode 100644 index ed8ed55..0000000 --- a/sidecar/src/protocol/types.ts +++ /dev/null @@ -1,239 +0,0 @@ -export interface Request { - id: string; - type: string; - payload: T; -} - -export interface Response { - id: string; - type: "result" | "error" | "progress" | "event"; - payload: T; -} - -export interface ProgressPayload { - stage: string; - current: number; - total: number; - message?: string; -} - -export interface ResultPayload { - success: boolean; - data?: T; - error?: string; -} - -// === Install === - -export interface InstallMinecraftRequest { - version: string; - gamePath: string; - javaPath?: string; - downloadThreads?: number; -} - -export interface InstallModLoaderRequest { - gamePath: string; - javaPath?: string; - mcVersion: string; - loaderType: "forge" | "fabric" | "quilt" | "neoforge"; - loaderVersion?: string; -} - -export interface GetVersionListRequest { - type?: "release" | "snapshot" | "all"; -} - -export interface GetForgeVersionListRequest { - mcVersion?: string; -} - -export interface GetFabricVersionListRequest { - mcVersion?: string; -} - -// === Launch === - -export interface LaunchRequest { - gamePath: string; - javaPath: string; - version: string; - username: string; - uuid: string; - accessToken?: string; - memory?: { min?: string; max?: string }; - jvmArgs?: string[]; - gameArgs?: string[]; - server?: { ip: string; port?: number }; - detached?: boolean; -} - -export interface DiagnoseRequest { - gamePath: string; - version: string; -} - -// === Auth === - -export interface MicrosoftLoginStartRequest { - client_id: string; - redirect_uri?: string; -} - -export interface MicrosoftLoginCallbackRequest { - state: string; - code: string; - client_id: string; -} - -export interface OfflineLoginRequest { - username: string; -} - -export interface ValidateTokenRequest { - accessToken: string; - clientToken?: string; -} - -// === Mods === - -export interface SearchModsRequest { - query?: string; - gameVersion?: string; - loader?: string; - limit?: number; - offset?: number; - source: "modrinth" | "curseforge"; -} - -export interface GetModDetailRequest { - projectId: string; - source: "modrinth" | "curseforge"; -} - -export interface GetModVersionsRequest { - projectId: string; - gameVersion?: string; - loader?: string; - source: "modrinth" | "curseforge"; -} - -export interface InstallModRequest { - projectId: string; - versionId?: string; - gamePath: string; - source: "modrinth" | "curseforge"; -} - -// === Instance === - -export interface CreateInstanceRequest { - name: string; - instancesPath: string; - gamePath: string; - mcVersion: string; - loaderType?: string; - loaderVersion?: string; - javaPath?: string; - memory?: { min?: string; max?: string }; -} - -export interface ListInstancesRequest { - instancesPath: string; -} - -export interface DeleteInstanceRequest { - name: string; - instancesPath: string; -} - -export interface GetInstanceInfoRequest { - name: string; - instancesPath: string; -} - -// === Background === - -export type AnimationType = "none" | "gradient" | "particles"; -export type Theme = "light" | "dark" | "system"; - -export interface BackgroundConfig { - type: "image" | "color" | "gradient" | "particles"; - image?: string; - color?: string; - blur: number; - opacity: number; - animation: AnimationType; - animationSpeed: number; - theme: Theme; -} - -export interface SetBackgroundImageRequest { - url: string; - blur?: number; - opacity?: number; -} - -export interface SetBackgroundColorRequest { - color: string; -} - -export interface SetBackgroundBlurRequest { - blur: number; -} - -export interface SetBackgroundOpacityRequest { - opacity: number; -} - -export interface SetBackgroundAnimationRequest { - type: AnimationType; - speed?: number; -} - -export interface SetBackgroundThemeRequest { - theme: Theme; -} - -// === Handler Map === - -export type HandlerMap = { - // Install - "install:minecraft": InstallMinecraftRequest; - "install:mod-loader": InstallModLoaderRequest; - "install:version-list": GetVersionListRequest; - "install:forge-version-list": GetForgeVersionListRequest; - "install:fabric-version-list": GetFabricVersionListRequest; - - // Launch - "launch:launch": LaunchRequest; - "launch:diagnose": DiagnoseRequest; - - // Auth - "auth:microsoft-login-start": MicrosoftLoginStartRequest; - "auth:microsoft-login-callback": MicrosoftLoginCallbackRequest; - "auth:offline-login": OfflineLoginRequest; - "auth:validate-token": ValidateTokenRequest; - - // Mods - "mods:search": SearchModsRequest; - "mods:detail": GetModDetailRequest; - "mods:versions": GetModVersionsRequest; - "mods:install": InstallModRequest; - - // Instance - "instance:create": CreateInstanceRequest; - "instance:list": ListInstancesRequest; - "instance:delete": DeleteInstanceRequest; - "instance:info": GetInstanceInfoRequest; - - // Background - "background:set-image": SetBackgroundImageRequest; - "background:set-color": SetBackgroundColorRequest; - "background:set-blur": SetBackgroundBlurRequest; - "background:set-opacity": SetBackgroundOpacityRequest; - "background:set-animation": SetBackgroundAnimationRequest; - "background:get": never; - "background:set-theme": SetBackgroundThemeRequest; - "background:reset": never; -}; diff --git a/sidecar/src/utils/paths.ts b/sidecar/src/utils/paths.ts deleted file mode 100644 index 135ed4e..0000000 --- a/sidecar/src/utils/paths.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { join } from "path"; -import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"; - -export function ensureDir(dir: string) { - if (!existsSync(dir)) { - mkdirSync(dir, { recursive: true }); - } -} - -export function getMinecraftPath(gamePath: string) { - return gamePath; -} - -export function getVersionPath(gamePath: string, versionId: string) { - return join(gamePath, "versions", versionId); -} - -export function getVersionJsonPath(gamePath: string, versionId: string) { - return join(getVersionPath(gamePath, versionId), `${versionId}.json`); -} - -export function getLibrariesPath(gamePath: string) { - return join(gamePath, "libraries"); -} - -export function getAssetsPath(gamePath: string) { - return join(gamePath, "assets"); -} - -export function getInstancesPath(instancesPath: string) { - return instancesPath; -} - -export function getInstancePath(instancesPath: string, name: string) { - return join(instancesPath, name); -} - -export interface InstanceConfig { - name: string; - mcVersion: string; - loaderType?: string; - loaderVersion?: string; - javaPath?: string; - memory?: { min?: string; max?: string }; - createdAt: string; -} - -export function readInstanceConfig(instancePath: string): InstanceConfig | null { - const configPath = join(instancePath, "koring-instance.json"); - if (!existsSync(configPath)) return null; - try { - return JSON.parse(readFileSync(configPath, "utf-8")); - } catch { - return null; - } -} - -export function writeInstanceConfig(instancePath: string, config: InstanceConfig) { - const configPath = join(instancePath, "koring-instance.json"); - writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8"); -} diff --git a/sidecar/tsconfig.json b/sidecar/tsconfig.json deleted file mode 100644 index 84d2f7a..0000000 --- a/sidecar/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2022", - "module": "ESNext", - "moduleResolution": "bundler", - "lib": ["ES2022"], - "outDir": "dist", - "rootDir": "src", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true - }, - "include": ["src"], - "exclude": ["node_modules", "dist", "bin"] -} diff --git a/splash.html b/splash.html index 49efe0c..ef33f9d 100644 --- a/splash.html +++ b/splash.html @@ -22,7 +22,7 @@
- Koring Launcher + Koring Launcher
Provided by Koring Studio diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore deleted file mode 100644 index b21bd68..0000000 --- a/src-tauri/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# Generated by Cargo -# will have compiled files and executables -/target/ - -# Generated by Tauri -# will have schema files for capabilities auto-completion -/gen/schemas diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock deleted file mode 100644 index 433f65a..0000000 --- a/src-tauri/Cargo.lock +++ /dev/null @@ -1,5497 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anyhow" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - -[[package]] -name = "arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" -dependencies = [ - "derive_arbitrary", -] - -[[package]] -name = "async-broadcast" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" -dependencies = [ - "event-listener", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-channel" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-io" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" -dependencies = [ - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix", - "slab", - "windows-sys 0.61.2", -] - -[[package]] -name = "async-lock" -version = "3.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-process" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" -dependencies = [ - "async-channel", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix", -] - -[[package]] -name = "async-recursion" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "async-signal" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix", - "signal-hook-registry", - "slab", - "windows-sys 0.61.2", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "atk" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" -dependencies = [ - "atk-sys", - "glib", - "libc", -] - -[[package]] -name = "atk-sys" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" -dependencies = [ - "serde_core", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" -dependencies = [ - "objc2", -] - -[[package]] -name = "blocking" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[package]] -name = "brotli" -version = "8.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "5.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "bumpalo" -version = "3.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" - -[[package]] -name = "bytemuck" -version = "1.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" -dependencies = [ - "serde", -] - -[[package]] -name = "cairo-rs" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" -dependencies = [ - "bitflags 2.13.0", - "cairo-sys-rs", - "glib", - "libc", - "once_cell", - "thiserror 1.0.69", -] - -[[package]] -name = "cairo-sys-rs" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" -dependencies = [ - "glib-sys", - "libc", - "system-deps", -] - -[[package]] -name = "camino" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce8d3bd5823c7504d3f579f13e7b2f3da252fcb938c594d5680ee508bf846f" -dependencies = [ - "serde_core", -] - -[[package]] -name = "cargo-platform" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror 2.0.18", -] - -[[package]] -name = "cargo_toml" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" -dependencies = [ - "serde", - "toml 0.9.12+spec-1.1.0", -] - -[[package]] -name = "cc" -version = "1.2.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cfb" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" -dependencies = [ - "byteorder", - "fnv", - "uuid", -] - -[[package]] -name = "cfg-expr" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" -dependencies = [ - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "chrono" -version = "0.4.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" -dependencies = [ - "iana-time-zone", - "num-traits", - "serde", - "windows-link 0.2.1", -] - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "cookie" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" -dependencies = [ - "time", - "version_check", -] - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core-graphics" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" -dependencies = [ - "bitflags 2.13.0", - "core-foundation", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" -dependencies = [ - "bitflags 2.13.0", - "core-foundation", - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "cssparser" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dae61cf9c0abb83bd659dab65b7e4e38d8236824c85f0f804f173567bda257d2" -dependencies = [ - "cssparser-macros", - "dtoa-short", - "itoa", - "phf", - "smallvec", -] - -[[package]] -name = "cssparser-macros" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" -dependencies = [ - "quote", - "syn 2.0.118", -] - -[[package]] -name = "ctor" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98" -dependencies = [ - "ctor-proc-macro", - "dtor", -] - -[[package]] -name = "ctor-proc-macro" -version = "0.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" - -[[package]] -name = "darling" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" -dependencies = [ - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.118", -] - -[[package]] -name = "darling_macro" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "dbus" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b942602992bb7acfd1f51c49811c58a610ef9181b6e66f3e519d79b540a3bf73" -dependencies = [ - "libc", - "libdbus-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "deranged" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" -dependencies = [ - "serde_core", -] - -[[package]] -name = "derive_arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "derive_more" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" -dependencies = [ - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.118", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "dirs" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.61.2", -] - -[[package]] -name = "dispatch2" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" -dependencies = [ - "bitflags 2.13.0", - "block2", - "libc", - "objc2", -] - -[[package]] -name = "displaydoc" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "dlopen2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e2c5bd4158e66d1e215c49b837e11d62f3267b30c92f1d171c4d3105e3dc4d4" -dependencies = [ - "dlopen2_derive", - "libc", - "once_cell", - "winapi", -] - -[[package]] -name = "dlopen2_derive" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "dom_query" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89" -dependencies = [ - "bit-set", - "cssparser", - "foldhash", - "html5ever", - "precomputed-hash", - "selectors", - "tendril", -] - -[[package]] -name = "dpi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" -dependencies = [ - "serde", -] - -[[package]] -name = "dtoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" - -[[package]] -name = "dtoa-short" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" -dependencies = [ - "dtoa", -] - -[[package]] -name = "dtor" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1057d6c64987086ff8ed0fd3fbf377a6b7d205cc7715868cd401705f715cbe4" -dependencies = [ - "dtor-proc-macro", -] - -[[package]] -name = "dtor-proc-macro" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "dyn-clone" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" - -[[package]] -name = "embed-resource" -version = "3.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a88c8d26de40ed18fe748c547845aa39de1db3afd958f8cb91579f3644bcb" -dependencies = [ - "cc", - "memchr", - "rustc_version", - "toml 1.1.2+spec-1.1.0", - "vswhom", - "winreg", -] - -[[package]] -name = "embed_plist" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "endi" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" - -[[package]] -name = "enumflags2" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" -dependencies = [ - "enumflags2_derive", - "serde", -] - -[[package]] -name = "enumflags2_derive" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "erased-serde" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" -dependencies = [ - "serde", - "serde_core", - "typeid", -] - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "event-listener" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "fastrand" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" - -[[package]] -name = "fdeflate" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "field-offset" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" -dependencies = [ - "memoffset", - "rustc_version", -] - -[[package]] -name = "filetime" -version = "0.2.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" -dependencies = [ - "cfg-if", - "libc", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "flate2" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" - -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures-channel" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" - -[[package]] -name = "futures-executor" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" - -[[package]] -name = "futures-lite" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "futures-sink" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" - -[[package]] -name = "futures-task" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" - -[[package]] -name = "futures-util" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" -dependencies = [ - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "slab", -] - -[[package]] -name = "gdk" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" -dependencies = [ - "cairo-rs", - "gdk-pixbuf", - "gdk-sys", - "gio", - "glib", - "libc", - "pango", -] - -[[package]] -name = "gdk-pixbuf" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" -dependencies = [ - "gdk-pixbuf-sys", - "gio", - "glib", - "libc", - "once_cell", -] - -[[package]] -name = "gdk-pixbuf-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" -dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "gdk-sys" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" -dependencies = [ - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "pkg-config", - "system-deps", -] - -[[package]] -name = "gdkwayland-sys" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" -dependencies = [ - "gdk-sys", - "glib-sys", - "gobject-sys", - "libc", - "pkg-config", - "system-deps", -] - -[[package]] -name = "gdkx11" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" -dependencies = [ - "gdk", - "gdkx11-sys", - "gio", - "glib", - "libc", - "x11", -] - -[[package]] -name = "gdkx11-sys" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" -dependencies = [ - "gdk-sys", - "glib-sys", - "libc", - "system-deps", - "x11", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi 5.3.0", - "wasip2", -] - -[[package]] -name = "getrandom" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" -dependencies = [ - "cfg-if", - "libc", - "r-efi 6.0.0", -] - -[[package]] -name = "gio" -version = "0.18.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-util", - "gio-sys", - "glib", - "libc", - "once_cell", - "pin-project-lite", - "smallvec", - "thiserror 1.0.69", -] - -[[package]] -name = "gio-sys" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", - "winapi", -] - -[[package]] -name = "glib" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" -dependencies = [ - "bitflags 2.13.0", - "futures-channel", - "futures-core", - "futures-executor", - "futures-task", - "futures-util", - "gio-sys", - "glib-macros", - "glib-sys", - "gobject-sys", - "libc", - "memchr", - "once_cell", - "smallvec", - "thiserror 1.0.69", -] - -[[package]] -name = "glib-macros" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" -dependencies = [ - "heck 0.4.1", - "proc-macro-crate 2.0.2", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "glib-sys" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" -dependencies = [ - "libc", - "system-deps", -] - -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "gobject-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" -dependencies = [ - "glib-sys", - "libc", - "system-deps", -] - -[[package]] -name = "gtk" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" -dependencies = [ - "atk", - "cairo-rs", - "field-offset", - "futures-channel", - "gdk", - "gdk-pixbuf", - "gio", - "glib", - "gtk-sys", - "gtk3-macros", - "libc", - "pango", - "pkg-config", -] - -[[package]] -name = "gtk-sys" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" -dependencies = [ - "atk-sys", - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "system-deps", -] - -[[package]] -name = "gtk3-macros" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "html5ever" -version = "0.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1054432bae2f14e0061e33d23402fbaa67a921d319d56adc6bcf887ddad1cbc2" -dependencies = [ - "log", - "markup5ever", -] - -[[package]] -name = "http" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" -dependencies = [ - "bytes", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "hyper" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" -dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core 0.62.2", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ico" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" -dependencies = [ - "byteorder", - "png 0.17.16", -] - -[[package]] -name = "icu_collections" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" -dependencies = [ - "displaydoc", - "potential_utf", - "utf8_iter", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" - -[[package]] -name = "icu_properties" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" - -[[package]] -name = "icu_provider" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" -dependencies = [ - "equivalent", - "hashbrown 0.17.1", - "serde", - "serde_core", -] - -[[package]] -name = "infer" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" -dependencies = [ - "cfb", -] - -[[package]] -name = "ipnet" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" - -[[package]] -name = "is-docker" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" -dependencies = [ - "once_cell", -] - -[[package]] -name = "is-wsl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" -dependencies = [ - "is-docker", - "once_cell", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - -[[package]] -name = "javascriptcore-rs" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" -dependencies = [ - "bitflags 1.3.2", - "glib", - "javascriptcore-rs-sys", -] - -[[package]] -name = "javascriptcore-rs-sys" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys 0.3.1", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" -dependencies = [ - "cfg-if", - "combine", - "jni-macros", - "jni-sys 0.4.1", - "log", - "simd_cesu8", - "thiserror 2.0.18", - "walkdir", - "windows-link 0.2.1", -] - -[[package]] -name = "jni-macros" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" -dependencies = [ - "proc-macro2", - "quote", - "rustc_version", - "simd_cesu8", - "syn 2.0.118", -] - -[[package]] -name = "jni-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" -dependencies = [ - "jni-sys 0.4.1", -] - -[[package]] -name = "jni-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" -dependencies = [ - "jni-sys-macros", -] - -[[package]] -name = "jni-sys-macros" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" -dependencies = [ - "quote", - "syn 2.0.118", -] - -[[package]] -name = "js-sys" -version = "0.3.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" -dependencies = [ - "cfg-if", - "futures-util", - "wasm-bindgen", -] - -[[package]] -name = "json-patch" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" -dependencies = [ - "jsonptr", - "serde", - "serde_json", - "thiserror 1.0.69", -] - -[[package]] -name = "jsonptr" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "keyboard-types" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" -dependencies = [ - "bitflags 2.13.0", - "serde", - "unicode-segmentation", -] - -[[package]] -name = "koring-launcher" -version = "0.1.0" -dependencies = [ - "serde", - "serde_json", - "tauri", - "tauri-build", - "tauri-plugin-dialog", - "tauri-plugin-opener", - "tauri-plugin-process", - "tauri-plugin-shell", - "tauri-plugin-updater", - "tokio", - "uuid", -] - -[[package]] -name = "libappindicator" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" -dependencies = [ - "glib", - "gtk", - "gtk-sys", - "libappindicator-sys", - "log", -] - -[[package]] -name = "libappindicator-sys" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" -dependencies = [ - "gtk-sys", - "libloading", - "once_cell", -] - -[[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "libdbus-sys" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043" -dependencies = [ - "pkg-config", -] - -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "libredox" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" -dependencies = [ - "libc", -] - -[[package]] -name = "linux-raw-sys" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" - -[[package]] -name = "litemap" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" - -[[package]] -name = "markup5ever" -version = "0.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8983d30f2915feeaaab2d6babdd6bc7e9ed1a00b66b5e6d74df19aa9c0e91862" -dependencies = [ - "log", - "tendril", - "web_atoms", -] - -[[package]] -name = "memchr" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minisign-verify" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22f9645cb765ea72b8111f36c522475d2daa0d22c957a9826437e97534bc4e9e" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "muda" -version = "0.19.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd04e60bc0b07438a6771710ee1698f98f6ebbc7f89b61264af1563b8aeb878" -dependencies = [ - "crossbeam-channel", - "dpi", - "gtk", - "keyboard-types", - "objc2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation", - "once_cell", - "png 0.18.1", - "serde", - "thiserror 2.0.18", - "windows-sys 0.61.2", -] - -[[package]] -name = "ndk" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" -dependencies = [ - "bitflags 2.13.0", - "jni-sys 0.3.1", - "log", - "ndk-sys", - "num_enum", - "raw-window-handle", - "thiserror 1.0.69", -] - -[[package]] -name = "ndk-sys" -version = "0.6.0+11769913" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" -dependencies = [ - "jni-sys 0.3.1", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - -[[package]] -name = "num-conv" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_enum" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" -dependencies = [ - "num_enum_derive", - "rustversion", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" -dependencies = [ - "proc-macro-crate 3.5.0", - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "objc2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" -dependencies = [ - "objc2-encode", - "objc2-exception-helper", -] - -[[package]] -name = "objc2-app-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" -dependencies = [ - "bitflags 2.13.0", - "block2", - "objc2", - "objc2-core-foundation", - "objc2-foundation", -] - -[[package]] -name = "objc2-cloud-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" -dependencies = [ - "bitflags 2.13.0", - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-data" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" -dependencies = [ - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" -dependencies = [ - "bitflags 2.13.0", - "dispatch2", - "objc2", -] - -[[package]] -name = "objc2-core-graphics" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" -dependencies = [ - "bitflags 2.13.0", - "dispatch2", - "objc2", - "objc2-core-foundation", - "objc2-io-surface", -] - -[[package]] -name = "objc2-core-image" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" -dependencies = [ - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-location" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009" -dependencies = [ - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-text" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" -dependencies = [ - "bitflags 2.13.0", - "objc2", - "objc2-core-foundation", - "objc2-core-graphics", -] - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "objc2-exception-helper" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" -dependencies = [ - "cc", -] - -[[package]] -name = "objc2-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" -dependencies = [ - "bitflags 2.13.0", - "block2", - "libc", - "objc2", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-io-surface" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" -dependencies = [ - "bitflags 2.13.0", - "objc2", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-osa-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f112d1746737b0da274ef79a23aac283376f335f4095a083a267a082f21db0c0" -dependencies = [ - "bitflags 2.13.0", - "objc2", - "objc2-app-kit", - "objc2-foundation", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" -dependencies = [ - "bitflags 2.13.0", - "objc2", - "objc2-core-foundation", - "objc2-foundation", -] - -[[package]] -name = "objc2-ui-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" -dependencies = [ - "bitflags 2.13.0", - "block2", - "objc2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-core-image", - "objc2-core-location", - "objc2-core-text", - "objc2-foundation", - "objc2-quartz-core", - "objc2-user-notifications", -] - -[[package]] -name = "objc2-user-notifications" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" -dependencies = [ - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-web-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" -dependencies = [ - "bitflags 2.13.0", - "block2", - "objc2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation", -] - -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - -[[package]] -name = "open" -version = "5.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fbaa89d2ddc8473c78a3adf69eea8cffa28c483b8e02a971ef31527cd0fc92c" -dependencies = [ - "dunce", - "is-wsl", - "libc", - "pathdiff", -] - -[[package]] -name = "openssl-probe" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "ordered-stream" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "os_pipe" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "osakit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b" -dependencies = [ - "objc2", - "objc2-foundation", - "objc2-osa-kit", - "serde", - "serde_json", - "thiserror 2.0.18", -] - -[[package]] -name = "pango" -version = "0.18.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" -dependencies = [ - "gio", - "glib", - "libc", - "once_cell", - "pango-sys", -] - -[[package]] -name = "pango-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link 0.2.1", -] - -[[package]] -name = "pathdiff" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "phf" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" -dependencies = [ - "phf_macros", - "phf_shared", - "serde", -] - -[[package]] -name = "phf_codegen" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" -dependencies = [ - "phf_generator", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" -dependencies = [ - "fastrand", - "phf_shared", -] - -[[package]] -name = "phf_macros" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "phf_shared" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" - -[[package]] -name = "piper" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkg-config" -version = "0.3.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" - -[[package]] -name = "plist" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092791278e026273c1b65bbdcfbba3a300f2994c896bd01ab01da613c29c46f1" -dependencies = [ - "base64 0.22.1", - "indexmap 2.14.0", - "quick-xml", - "serde", - "time", -] - -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "png" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" -dependencies = [ - "bitflags 2.13.0", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "polling" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix", - "windows-sys 0.61.2", -] - -[[package]] -name = "potential_utf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" -dependencies = [ - "toml_datetime 0.6.3", - "toml_edit 0.20.2", -] - -[[package]] -name = "proc-macro-crate" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" -dependencies = [ - "toml_edit 0.25.12+spec-1.1.0", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quick-xml" -version = "0.39.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" -dependencies = [ - "memchr", -] - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "r-efi" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" - -[[package]] -name = "raw-window-handle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags 2.13.0", -] - -[[package]] -name = "redox_users" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" -dependencies = [ - "getrandom 0.2.17", - "libredox", - "thiserror 2.0.18", -] - -[[package]] -name = "ref-cast" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "regex" -version = "1.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" - -[[package]] -name = "reqwest" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-pki-types", - "rustls-platform-verifier", - "serde", - "serde_json", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tokio-util", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", -] - -[[package]] -name = "rfd" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672" -dependencies = [ - "block2", - "dispatch2", - "glib-sys", - "gobject-sys", - "gtk-sys", - "js-sys", - "log", - "objc2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation", - "raw-window-handle", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-sys 0.60.2", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" -dependencies = [ - "bitflags 2.13.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls" -version = "0.23.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" -dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-native-certs" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" -dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pki-types" -version = "1.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" -dependencies = [ - "zeroize", -] - -[[package]] -name = "rustls-platform-verifier" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" -dependencies = [ - "core-foundation", - "core-foundation-sys", - "jni 0.22.4", - "log", - "once_cell", - "rustls", - "rustls-native-certs", - "rustls-platform-verifier-android", - "rustls-webpki", - "security-framework", - "security-framework-sys", - "webpki-root-certs", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls-platform-verifier-android" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" - -[[package]] -name = "rustls-webpki" -version = "0.103.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "schemars" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" -dependencies = [ - "dyn-clone", - "indexmap 1.9.3", - "schemars_derive", - "serde", - "serde_json", - "url", - "uuid", -] - -[[package]] -name = "schemars" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" -dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", -] - -[[package]] -name = "schemars" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" -dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.118", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" -dependencies = [ - "bitflags 2.13.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "selectors" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" -dependencies = [ - "bitflags 2.13.0", - "cssparser", - "derive_more", - "log", - "new_debug_unreachable", - "phf", - "phf_codegen", - "precomputed-hash", - "rustc-hash", - "servo_arc", - "smallvec", -] - -[[package]] -name = "semver" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" -dependencies = [ - "serde", - "serde_core", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde-untagged" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" -dependencies = [ - "erased-serde", - "serde", - "serde_core", - "typeid", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "serde_json" -version = "1.0.150" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "serde_repr" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_spanned" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" -dependencies = [ - "serde_core", -] - -[[package]] -name = "serde_with" -version = "3.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c" -dependencies = [ - "base64 0.22.1", - "bs58", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.14.0", - "schemars 0.9.0", - "schemars 1.2.1", - "serde_core", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "serialize-to-javascript" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5" -dependencies = [ - "serde", - "serde_json", - "serialize-to-javascript-impl", -] - -[[package]] -name = "serialize-to-javascript-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "servo_arc" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170fb83ab34de17dc69aa7c67482b22218ddb85da56546f9bd6b929e32a05930" -dependencies = [ - "stable_deref_trait", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "shared_child" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7" -dependencies = [ - "libc", - "sigchld", - "windows-sys 0.60.2", -] - -[[package]] -name = "shlex" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" - -[[package]] -name = "sigchld" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1" -dependencies = [ - "libc", - "os_pipe", - "signal-hook", -] - -[[package]] -name = "signal-hook" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" -dependencies = [ - "errno", - "libc", -] - -[[package]] -name = "simd-adler32" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" - -[[package]] -name = "simd_cesu8" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" -dependencies = [ - "rustc_version", - "simdutf8", -] - -[[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - -[[package]] -name = "siphasher" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - -[[package]] -name = "smallvec" -version = "1.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" - -[[package]] -name = "socket2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "softbuffer" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aac18da81ebbf05109ab275b157c22a653bb3c12cf884450179942f81bcbf6c3" -dependencies = [ - "bytemuck", - "js-sys", - "ndk", - "objc2", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-foundation", - "objc2-quartz-core", - "raw-window-handle", - "redox_syscall", - "tracing", - "wasm-bindgen", - "web-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "soup3" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" -dependencies = [ - "futures-channel", - "gio", - "glib", - "libc", - "soup3-sys", -] - -[[package]] -name = "soup3-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" -dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "string_cache" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared", - "precomputed-hash", -] - -[[package]] -name = "string_cache_codegen" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "swift-rs" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7" -dependencies = [ - "base64 0.21.7", - "serde", - "serde_json", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "system-deps" -version = "6.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" -dependencies = [ - "cfg-expr", - "heck 0.5.0", - "pkg-config", - "toml 0.8.2", - "version-compare", -] - -[[package]] -name = "tao" -version = "0.35.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1c93047acf68669466a34690ac58cca7010bd1b201e1ec86f1fd0a75d3dd4a9" -dependencies = [ - "bitflags 2.13.0", - "block2", - "core-foundation", - "core-graphics", - "crossbeam-channel", - "dbus", - "dispatch2", - "dlopen2", - "dpi", - "gdkwayland-sys", - "gdkx11-sys", - "gtk", - "jni 0.21.1", - "libc", - "log", - "ndk", - "ndk-sys", - "objc2", - "objc2-app-kit", - "objc2-foundation", - "objc2-ui-kit", - "once_cell", - "parking_lot", - "percent-encoding", - "raw-window-handle", - "tao-macros", - "unicode-segmentation", - "url", - "windows", - "windows-core 0.61.2", - "windows-version", - "x11-dl", -] - -[[package]] -name = "tao-macros" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "tar" -version = "0.4.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" -dependencies = [ - "filetime", - "libc", - "xattr", -] - -[[package]] -name = "target-lexicon" -version = "0.12.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" - -[[package]] -name = "tauri" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2616f96cb644bf2c5c456d9de4d5d5100e592d7424c74d8b55c5cb96e359e93" -dependencies = [ - "anyhow", - "bytes", - "cookie", - "dirs", - "dunce", - "embed_plist", - "getrandom 0.3.4", - "glob", - "gtk", - "heck 0.5.0", - "http", - "jni 0.21.1", - "libc", - "log", - "mime", - "muda", - "objc2", - "objc2-app-kit", - "objc2-foundation", - "objc2-ui-kit", - "objc2-web-kit", - "percent-encoding", - "plist", - "raw-window-handle", - "reqwest", - "serde", - "serde_json", - "serde_repr", - "serialize-to-javascript", - "swift-rs", - "tauri-build", - "tauri-macros", - "tauri-runtime", - "tauri-runtime-wry", - "tauri-utils", - "thiserror 2.0.18", - "tokio", - "tray-icon", - "url", - "webkit2gtk", - "webview2-com", - "window-vibrancy", - "windows", -] - -[[package]] -name = "tauri-build" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc9ce40b16101cb6ea63d3e221567affd1c3a9205f95d7bc574941a10636b632" -dependencies = [ - "anyhow", - "cargo_toml", - "dirs", - "glob", - "heck 0.5.0", - "json-patch", - "schemars 0.8.22", - "semver", - "serde", - "serde_json", - "tauri-utils", - "tauri-winres", - "walkdir", -] - -[[package]] -name = "tauri-codegen" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08279169ff42f8fc45a1dbc9dcae888893ba95288142e5880c59b93a26d2cfc5" -dependencies = [ - "base64 0.22.1", - "brotli", - "ico", - "json-patch", - "plist", - "png 0.17.16", - "proc-macro2", - "quote", - "semver", - "serde", - "serde_json", - "sha2", - "syn 2.0.118", - "tauri-utils", - "thiserror 2.0.18", - "time", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "tauri-macros" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b394794f399a421811d06966343e7933fcae92d59f5180b9388d1174497a45" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.118", - "tauri-codegen", - "tauri-utils", -] - -[[package]] -name = "tauri-plugin" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74be5dd4bed9afbd145e5716b5fa2ec28cbc29c34ffa61c258c9273d896c8020" -dependencies = [ - "anyhow", - "glob", - "plist", - "schemars 0.8.22", - "serde", - "serde_json", - "tauri-utils", - "walkdir", -] - -[[package]] -name = "tauri-plugin-dialog" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65981abb771e74e571a38196c3baa11c459379164791eba0e67abc1a5fac9884" -dependencies = [ - "log", - "raw-window-handle", - "rfd", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "tauri-plugin-fs", - "thiserror 2.0.18", - "url", -] - -[[package]] -name = "tauri-plugin-fs" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ecc274121aca0c036a2b42d1cbe83d368d348f54e0bb8a735c2b1548e8f371" -dependencies = [ - "anyhow", - "dunce", - "glob", - "log", - "objc2-foundation", - "percent-encoding", - "schemars 0.8.22", - "serde", - "serde_json", - "serde_repr", - "tauri", - "tauri-plugin", - "tauri-utils", - "thiserror 2.0.18", - "toml 1.1.2+spec-1.1.0", - "url", -] - -[[package]] -name = "tauri-plugin-opener" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17e1bea14edce6b793a04e2417e3fd924b9bc4faae83cdee7d714156cceeed29" -dependencies = [ - "dunce", - "glob", - "objc2-app-kit", - "objc2-foundation", - "open", - "schemars 0.8.22", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "thiserror 2.0.18", - "url", - "windows", - "zbus", -] - -[[package]] -name = "tauri-plugin-process" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d55511a7bf6cd70c8767b02c97bf8134fa434daf3926cfc1be0a0f94132d165a" -dependencies = [ - "tauri", - "tauri-plugin", -] - -[[package]] -name = "tauri-plugin-shell" -version = "2.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8457dbf9e2bab1edd8df22bb2c20857a59a9868e79cb3eac5ed639eec4d0c73b" -dependencies = [ - "encoding_rs", - "log", - "open", - "os_pipe", - "regex", - "schemars 0.8.22", - "serde", - "serde_json", - "shared_child", - "tauri", - "tauri-plugin", - "thiserror 2.0.18", - "tokio", -] - -[[package]] -name = "tauri-plugin-updater" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806d9dac662c2e4594ff03c647a552f2c9bd544e7d0f683ec58f872f952ce4af" -dependencies = [ - "base64 0.22.1", - "dirs", - "flate2", - "futures-util", - "http", - "infer", - "log", - "minisign-verify", - "osakit", - "percent-encoding", - "reqwest", - "rustls", - "semver", - "serde", - "serde_json", - "tar", - "tauri", - "tauri-plugin", - "tempfile", - "thiserror 2.0.18", - "time", - "tokio", - "url", - "windows-sys 0.60.2", - "zip", -] - -[[package]] -name = "tauri-runtime" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b4bc95aed361b0019067d189a1174a603d460d0f6c72606512d59fc9c12ec8" -dependencies = [ - "cookie", - "dpi", - "gtk", - "http", - "jni 0.21.1", - "objc2", - "objc2-ui-kit", - "objc2-web-kit", - "raw-window-handle", - "serde", - "serde_json", - "tauri-utils", - "thiserror 2.0.18", - "url", - "webkit2gtk", - "webview2-com", - "windows", -] - -[[package]] -name = "tauri-runtime-wry" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe41e015bf8fc4d6477ff4926a0ef769dc64ff34c7b0038b6f7cacae892acb5c" -dependencies = [ - "gtk", - "http", - "jni 0.21.1", - "log", - "objc2", - "objc2-app-kit", - "once_cell", - "percent-encoding", - "raw-window-handle", - "softbuffer", - "tao", - "tauri-runtime", - "tauri-utils", - "url", - "webkit2gtk", - "webview2-com", - "windows", - "wry", -] - -[[package]] -name = "tauri-utils" -version = "2.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e176a18e67764923c4f1ce66f25ae4abe5f688384d5eb1a0fa6c77f3d90f887" -dependencies = [ - "anyhow", - "brotli", - "cargo_metadata", - "ctor", - "dom_query", - "dunce", - "glob", - "http", - "infer", - "json-patch", - "log", - "memchr", - "phf", - "plist", - "proc-macro2", - "quote", - "regex", - "schemars 0.8.22", - "semver", - "serde", - "serde-untagged", - "serde_json", - "serde_with", - "swift-rs", - "thiserror 2.0.18", - "toml 1.1.2+spec-1.1.0", - "url", - "urlpattern", - "uuid", - "walkdir", -] - -[[package]] -name = "tauri-winres" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc65d45c68858bfe420dd29e834b5d15dbecf8a07a8a16cf4d532c7b1f69d4b6" -dependencies = [ - "dunce", - "embed-resource", - "toml 1.1.2+spec-1.1.0", -] - -[[package]] -name = "tempfile" -version = "3.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" -dependencies = [ - "fastrand", - "getrandom 0.4.3", - "once_cell", - "rustix", - "windows-sys 0.61.2", -] - -[[package]] -name = "tendril" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4790fc369d5a530f4b544b094e31388b9b3a37c0f4652ade4505945f5660d24" -dependencies = [ - "new_debug_unreachable", - "utf-8", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" -dependencies = [ - "thiserror-impl 2.0.18", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "time" -version = "0.3.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711a53c2d47bbd818258c498c8dbfe186a2526c631495cfe7e078567f86b8469" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde_core", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" - -[[package]] -name = "time-macros" -version = "0.2.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c652a3727a9cbb9a02f707f530b618ce00d0ccd762009c8c23bd191df3c17d" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" -dependencies = [ - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" -dependencies = [ - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.3", - "toml_edit 0.20.2", -] - -[[package]] -name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "indexmap 2.14.0", - "serde_core", - "serde_spanned 1.1.1", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 0.7.15", -] - -[[package]] -name = "toml" -version = "1.1.2+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" -dependencies = [ - "indexmap 2.14.0", - "serde_core", - "serde_spanned 1.1.1", - "toml_datetime 1.1.1+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 1.0.3", -] - -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_datetime" -version = "1.1.1+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.14.0", - "toml_datetime 0.6.3", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" -dependencies = [ - "indexmap 2.14.0", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.3", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.25.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" -dependencies = [ - "indexmap 2.14.0", - "toml_datetime 1.1.1+spec-1.1.0", - "toml_parser", - "winnow 1.0.3", -] - -[[package]] -name = "toml_parser" -version = "1.1.2+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" -dependencies = [ - "winnow 1.0.3", -] - -[[package]] -name = "toml_writer" -version = "1.1.1+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" - -[[package]] -name = "tower" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-http" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" -dependencies = [ - "bitflags 2.13.0", - "bytes", - "futures-util", - "http", - "http-body", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", - "url", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tray-icon" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65ba1e5f6b9ef9fd87e21b9c6f351554dbd717960089168fcfdef854686961dc" -dependencies = [ - "crossbeam-channel", - "dirs", - "libappindicator", - "muda", - "objc2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-foundation", - "once_cell", - "png 0.18.1", - "serde", - "thiserror 2.0.18", - "windows-sys 0.61.2", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typeid" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" - -[[package]] -name = "typenum" -version = "1.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" - -[[package]] -name = "uds_windows" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" -dependencies = [ - "memoffset", - "tempfile", - "windows-sys 0.61.2", -] - -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-ucd-ident" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "unicode-segmentation" -version = "1.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", - "serde_derive", -] - -[[package]] -name = "urlpattern" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" -dependencies = [ - "regex", - "serde", - "unic-ucd-ident", - "url", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "uuid" -version = "1.23.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" -dependencies = [ - "getrandom 0.4.3", - "js-sys", - "serde_core", - "wasm-bindgen", -] - -[[package]] -name = "version-compare" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "vswhom" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" -dependencies = [ - "libc", - "vswhom-sys", -] - -[[package]] -name = "vswhom-sys" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.4+wasi-0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn 2.0.118", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wasm-streams" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "web-sys" -version = "0.3.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web_atoms" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "075474b12bcb3d2e3d4546580e9de478eeeead668a1761e2a8860c836b7ef297" -dependencies = [ - "phf", - "phf_codegen", - "string_cache", - "string_cache_codegen", -] - -[[package]] -name = "webkit2gtk" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793" -dependencies = [ - "bitflags 1.3.2", - "cairo-rs", - "gdk", - "gdk-sys", - "gio", - "gio-sys", - "glib", - "glib-sys", - "gobject-sys", - "gtk", - "gtk-sys", - "javascriptcore-rs", - "libc", - "once_cell", - "soup3", - "webkit2gtk-sys", -] - -[[package]] -name = "webkit2gtk-sys" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5" -dependencies = [ - "bitflags 1.3.2", - "cairo-sys-rs", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "gtk-sys", - "javascriptcore-rs-sys", - "libc", - "pkg-config", - "soup3-sys", - "system-deps", -] - -[[package]] -name = "webpki-root-certs" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "webview2-com" -version = "0.38.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7130243a7a5b33c54a444e54842e6a9e133de08b5ad7b5861cd8ed9a6a5bc96a" -dependencies = [ - "webview2-com-macros", - "webview2-com-sys", - "windows", - "windows-core 0.61.2", - "windows-implement", - "windows-interface", -] - -[[package]] -name = "webview2-com-macros" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a921c1b6914c367b2b823cd4cde6f96beec77d30a939c8199bb377cf9b9b54" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "webview2-com-sys" -version = "0.38.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "381336cfffd772377d291702245447a5251a2ffa5bad679c99e61bc48bacbf9c" -dependencies = [ - "thiserror 2.0.18", - "windows", - "windows-core 0.61.2", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "window-vibrancy" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" -dependencies = [ - "objc2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation", - "raw-window-handle", - "windows-sys 0.59.0", - "windows-version", -] - -[[package]] -name = "windows" -version = "0.61.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" -dependencies = [ - "windows-collections", - "windows-core 0.61.2", - "windows-future", - "windows-link 0.1.3", - "windows-numerics", -] - -[[package]] -name = "windows-collections" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" -dependencies = [ - "windows-core 0.61.2", -] - -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", -] - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - -[[package]] -name = "windows-future" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", - "windows-threading", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-numerics" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", -] - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link 0.2.1", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows-threading" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-version" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" -dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" - -[[package]] -name = "winnow" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.55.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" -dependencies = [ - "cfg-if", - "windows-sys 0.59.0", -] - -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - -[[package]] -name = "writeable" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" - -[[package]] -name = "wry" -version = "0.55.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186f9871daa55fd9c016578b810d149de58367113db7fb72b462d2323ce19514" -dependencies = [ - "base64 0.22.1", - "block2", - "cookie", - "crossbeam-channel", - "dirs", - "dom_query", - "dpi", - "dunce", - "gdkx11", - "gtk", - "http", - "javascriptcore-rs", - "jni 0.21.1", - "libc", - "ndk", - "objc2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation", - "objc2-ui-kit", - "objc2-web-kit", - "once_cell", - "percent-encoding", - "raw-window-handle", - "sha2", - "soup3", - "tao-macros", - "thiserror 2.0.18", - "url", - "webkit2gtk", - "webkit2gtk-sys", - "webview2-com", - "windows", - "windows-core 0.61.2", - "windows-version", - "x11-dl", -] - -[[package]] -name = "x11" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" -dependencies = [ - "libc", - "pkg-config", -] - -[[package]] -name = "x11-dl" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" -dependencies = [ - "libc", - "once_cell", - "pkg-config", -] - -[[package]] -name = "xattr" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" -dependencies = [ - "libc", - "rustix", -] - -[[package]] -name = "yoke" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", - "synstructure", -] - -[[package]] -name = "zbus" -version = "5.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee682d202a77e4a9f3b2c2bdf48a7b28af5c08c34ddf66f98c93e5e39464285" -dependencies = [ - "async-broadcast", - "async-executor", - "async-io", - "async-lock", - "async-process", - "async-recursion", - "async-task", - "async-trait", - "blocking", - "enumflags2", - "event-listener", - "futures-core", - "futures-lite", - "hex", - "libc", - "ordered-stream", - "rustix", - "serde", - "serde_repr", - "tracing", - "uds_windows", - "uuid", - "windows-sys 0.61.2", - "winnow 1.0.3", - "zbus_macros", - "zbus_names", - "zvariant", -] - -[[package]] -name = "zbus_macros" -version = "5.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adf1bd45a81a103745b1757754762a26e8cd01e4532e4d6c8ec431624b80d1d6" -dependencies = [ - "proc-macro-crate 3.5.0", - "proc-macro2", - "quote", - "syn 2.0.118", - "zbus_names", - "zvariant", - "zvariant_utils", -] - -[[package]] -name = "zbus_names" -version = "4.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d" -dependencies = [ - "serde", - "winnow 1.0.3", - "zvariant", -] - -[[package]] -name = "zerofrom" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" - -[[package]] -name = "zerotrie" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "zip" -version = "4.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1" -dependencies = [ - "arbitrary", - "crc32fast", - "indexmap 2.14.0", - "memchr", -] - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" - -[[package]] -name = "zvariant" -version = "5.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a192a0bde63360d77a7523c833d4b4ce6070a927e2c53246e4c540b1a3e27be0" -dependencies = [ - "endi", - "enumflags2", - "serde", - "winnow 1.0.3", - "zvariant_derive", - "zvariant_utils", -] - -[[package]] -name = "zvariant_derive" -version = "5.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc6cde9c01c511074be97f7ccb6c19d0da89e3f8662e812e999dcfd4638737" -dependencies = [ - "proc-macro-crate 3.5.0", - "proc-macro2", - "quote", - "syn 2.0.118", - "zvariant_utils", -] - -[[package]] -name = "zvariant_utils" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8535915cfa75547e559d8c68e8139909a4aeee076831e4ef7fc59d8172c4d6" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "syn 2.0.118", - "winnow 1.0.3", -] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml deleted file mode 100644 index 6a79bce..0000000 --- a/src-tauri/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "koring-launcher" -version = "0.1.0" -description = "A Tauri App" -authors = ["you"] -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -# The `_lib` suffix may seem redundant but it is necessary -# to make the lib name unique and wouldn't conflict with the bin name. -# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519 -name = "koring_launcher_lib" -crate-type = ["staticlib", "cdylib", "rlib"] - -[build-dependencies] -tauri-build = { version = "2", features = [] } - -[dependencies] -tauri = { version = "2", features = [] } -tauri-plugin-opener = "2" -tauri-plugin-process = "2" -tauri-plugin-dialog = "2" -tauri-plugin-shell = "2" -tauri-plugin-updater = "2" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -uuid = { version = "1", features = ["v4"] } -tokio = { version = "1", features = ["time"] } - diff --git a/src-tauri/binaries/koring-sidecar-aarch64-pc-windows-msvc.exe b/src-tauri/binaries/koring-sidecar-aarch64-pc-windows-msvc.exe deleted file mode 100644 index 1fa7c58..0000000 Binary files a/src-tauri/binaries/koring-sidecar-aarch64-pc-windows-msvc.exe and /dev/null differ diff --git a/src-tauri/binaries/koring-sidecar-x86_64-pc-windows-msvc.exe b/src-tauri/binaries/koring-sidecar-x86_64-pc-windows-msvc.exe deleted file mode 100644 index 1fa7c58..0000000 Binary files a/src-tauri/binaries/koring-sidecar-x86_64-pc-windows-msvc.exe and /dev/null differ diff --git a/src-tauri/build.rs b/src-tauri/build.rs deleted file mode 100644 index d860e1e..0000000 --- a/src-tauri/build.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - tauri_build::build() -} diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json deleted file mode 100644 index 6bd149e..0000000 --- a/src-tauri/capabilities/default.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$schema": "../gen/schemas/desktop-schema.json", - "identifier": "default", - "description": "Capability for the main window", - "windows": ["*"], - "permissions": [ - "core:default", - "core:window:default", - "core:window:allow-minimize", - "core:window:allow-maximize", - "core:window:allow-toggle-maximize", - "core:window:allow-close", - "core:window:allow-is-maximized", - "core:window:allow-start-dragging", - "core:window:allow-show", - "core:window:allow-hide", - "core:window:allow-set-focus", - "core:webview:allow-create-webview-window", - "opener:default", - "process:default", - "shell:allow-execute", - "updater:default", - "dialog:default", - { - "identifier": "shell:allow-execute", - "allow": [ - { - "name": "binaries/koring-sidecar", - "sidecar": true, - "args": true - } - ] - } - ] -} diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png deleted file mode 100644 index 7a24719..0000000 Binary files a/src-tauri/icons/128x128.png and /dev/null differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png deleted file mode 100644 index 7a24719..0000000 Binary files a/src-tauri/icons/128x128@2x.png and /dev/null differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png deleted file mode 100644 index 7a24719..0000000 Binary files a/src-tauri/icons/32x32.png and /dev/null differ diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png deleted file mode 100644 index 0ca4f27..0000000 Binary files a/src-tauri/icons/Square107x107Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png deleted file mode 100644 index b81f820..0000000 Binary files a/src-tauri/icons/Square142x142Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png deleted file mode 100644 index 624c7bf..0000000 Binary files a/src-tauri/icons/Square150x150Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png deleted file mode 100644 index c021d2b..0000000 Binary files a/src-tauri/icons/Square284x284Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png deleted file mode 100644 index 6219700..0000000 Binary files a/src-tauri/icons/Square30x30Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png deleted file mode 100644 index f9bc048..0000000 Binary files a/src-tauri/icons/Square310x310Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png deleted file mode 100644 index d5fbfb2..0000000 Binary files a/src-tauri/icons/Square44x44Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png deleted file mode 100644 index 63440d7..0000000 Binary files a/src-tauri/icons/Square71x71Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png deleted file mode 100644 index f3f705a..0000000 Binary files a/src-tauri/icons/Square89x89Logo.png and /dev/null differ diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png deleted file mode 100644 index 4556388..0000000 Binary files a/src-tauri/icons/StoreLogo.png and /dev/null differ diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns deleted file mode 100644 index 12a5bce..0000000 Binary files a/src-tauri/icons/icon.icns and /dev/null differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico deleted file mode 100644 index a0c4bf7..0000000 Binary files a/src-tauri/icons/icon.ico and /dev/null differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png deleted file mode 100644 index 704755d..0000000 Binary files a/src-tauri/icons/icon.png and /dev/null differ diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs deleted file mode 100644 index 6f46bf2..0000000 --- a/src-tauri/src/commands/mod.rs +++ /dev/null @@ -1,321 +0,0 @@ -use serde::{Deserialize, Serialize}; -use tauri::State; -use crate::sidecar::{Request, SidecarManager}; - -#[derive(Debug, Serialize, Deserialize)] -pub struct CommandResult { - pub success: bool, - pub data: Option, - pub error: Option, -} - -#[tauri::command] -pub async fn sidecar_request( - sidecar: State<'_, std::sync::Mutex>, - msg_type: String, - payload: serde_json::Value, -) -> Result { - let id = uuid::Uuid::new_v4().to_string(); - - let request = Request { - id: id.clone(), - msg_type, - payload, - }; - - let mut manager = sidecar.lock().map_err(|e| e.to_string())?; - manager.send_request(&request)?; - - Ok(CommandResult { - success: true, - data: Some(serde_json::json!({ "requestId": id })), - error: None, - }) -} - -#[tauri::command] -pub async fn install_minecraft( - sidecar: State<'_, std::sync::Mutex>, - version: String, - game_path: String, - java_path: Option, - download_threads: Option, -) -> Result { - let id = uuid::Uuid::new_v4().to_string(); - - let request = Request { - id: id.clone(), - msg_type: "install:minecraft".to_string(), - payload: serde_json::json!({ - "version": version, - "gamePath": game_path, - "javaPath": java_path, - "downloadThreads": download_threads, - }), - }; - - let mut manager = sidecar.lock().map_err(|e| e.to_string())?; - manager.send_request(&request)?; - - Ok(CommandResult { - success: true, - data: Some(serde_json::json!({ "requestId": id })), - error: None, - }) -} - -#[tauri::command] -pub async fn install_mod_loader( - sidecar: State<'_, std::sync::Mutex>, - mc_version: String, - game_path: String, - loader_type: String, - loader_version: Option, - java_path: Option, -) -> Result { - let id = uuid::Uuid::new_v4().to_string(); - - let request = Request { - id: id.clone(), - msg_type: "install:mod-loader".to_string(), - payload: serde_json::json!({ - "mcVersion": mc_version, - "gamePath": game_path, - "loaderType": loader_type, - "loaderVersion": loader_version, - "javaPath": java_path, - }), - }; - - let mut manager = sidecar.lock().map_err(|e| e.to_string())?; - manager.send_request(&request)?; - - Ok(CommandResult { - success: true, - data: Some(serde_json::json!({ "requestId": id })), - error: None, - }) -} - -#[tauri::command] -pub async fn get_version_list( - sidecar: State<'_, std::sync::Mutex>, - version_type: Option, -) -> Result { - let id = uuid::Uuid::new_v4().to_string(); - - let request = Request { - id: id.clone(), - msg_type: "install:version-list".to_string(), - payload: serde_json::json!({ - "type": version_type, - }), - }; - - let mut manager = sidecar.lock().map_err(|e| e.to_string())?; - manager.send_request(&request)?; - - Ok(CommandResult { - success: true, - data: Some(serde_json::json!({ "requestId": id })), - error: None, - }) -} - -#[tauri::command] -pub async fn launch_game( - sidecar: State<'_, std::sync::Mutex>, - game_path: String, - java_path: String, - version: String, - username: String, - uuid: String, - access_token: Option, - memory: Option, - jvm_args: Option>, - game_args: Option>, - server: Option, - detached: Option, -) -> Result { - let id = uuid::Uuid::new_v4().to_string(); - - let request = Request { - id: id.clone(), - msg_type: "launch:launch".to_string(), - payload: serde_json::json!({ - "gamePath": game_path, - "javaPath": java_path, - "version": version, - "username": username, - "uuid": uuid, - "accessToken": access_token, - "memory": memory, - "jvmArgs": jvm_args, - "gameArgs": game_args, - "server": server, - "detached": detached, - }), - }; - - let mut manager = sidecar.lock().map_err(|e| e.to_string())?; - manager.send_request(&request)?; - - Ok(CommandResult { - success: true, - data: Some(serde_json::json!({ "requestId": id })), - error: None, - }) -} - -#[tauri::command] -pub async fn offline_login( - sidecar: State<'_, std::sync::Mutex>, - username: String, -) -> Result { - let id = uuid::Uuid::new_v4().to_string(); - - let request = Request { - id: id.clone(), - msg_type: "auth:offline-login".to_string(), - payload: serde_json::json!({ - "username": username, - }), - }; - - let mut manager = sidecar.lock().map_err(|e| e.to_string())?; - manager.send_request(&request)?; - - Ok(CommandResult { - success: true, - data: Some(serde_json::json!({ "requestId": id })), - error: None, - }) -} - -#[tauri::command] -pub async fn search_mods( - sidecar: State<'_, std::sync::Mutex>, - query: Option, - game_version: Option, - loader: Option, - limit: Option, - offset: Option, - source: String, -) -> Result { - let id = uuid::Uuid::new_v4().to_string(); - - let request = Request { - id: id.clone(), - msg_type: "mods:search".to_string(), - payload: serde_json::json!({ - "query": query, - "gameVersion": game_version, - "loader": loader, - "limit": limit, - "offset": offset, - "source": source, - }), - }; - - let mut manager = sidecar.lock().map_err(|e| e.to_string())?; - manager.send_request(&request)?; - - Ok(CommandResult { - success: true, - data: Some(serde_json::json!({ "requestId": id })), - error: None, - }) -} - -#[tauri::command] -pub async fn install_mod( - sidecar: State<'_, std::sync::Mutex>, - project_id: String, - version_id: Option, - game_path: String, - source: String, -) -> Result { - let id = uuid::Uuid::new_v4().to_string(); - - let request = Request { - id: id.clone(), - msg_type: "mods:install".to_string(), - payload: serde_json::json!({ - "projectId": project_id, - "versionId": version_id, - "gamePath": game_path, - "source": source, - }), - }; - - let mut manager = sidecar.lock().map_err(|e| e.to_string())?; - manager.send_request(&request)?; - - Ok(CommandResult { - success: true, - data: Some(serde_json::json!({ "requestId": id })), - error: None, - }) -} - -#[tauri::command] -pub async fn create_instance( - sidecar: State<'_, std::sync::Mutex>, - name: String, - game_path: String, - mc_version: String, - loader_type: Option, - loader_version: Option, - java_path: Option, - memory: Option, -) -> Result { - let id = uuid::Uuid::new_v4().to_string(); - - let request = Request { - id: id.clone(), - msg_type: "instance:create".to_string(), - payload: serde_json::json!({ - "name": name, - "gamePath": game_path, - "mcVersion": mc_version, - "loaderType": loader_type, - "loaderVersion": loader_version, - "javaPath": java_path, - "memory": memory, - }), - }; - - let mut manager = sidecar.lock().map_err(|e| e.to_string())?; - manager.send_request(&request)?; - - Ok(CommandResult { - success: true, - data: Some(serde_json::json!({ "requestId": id })), - error: None, - }) -} - -#[tauri::command] -pub async fn list_instances( - sidecar: State<'_, std::sync::Mutex>, - instances_path: String, -) -> Result { - let id = uuid::Uuid::new_v4().to_string(); - - let request = Request { - id: id.clone(), - msg_type: "instance:list".to_string(), - payload: serde_json::json!({ - "instancesPath": instances_path, - }), - }; - - let mut manager = sidecar.lock().map_err(|e| e.to_string())?; - manager.send_request(&request)?; - - Ok(CommandResult { - success: true, - data: Some(serde_json::json!({ "requestId": id })), - error: None, - }) -} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs deleted file mode 100644 index 2744111..0000000 --- a/src-tauri/src/lib.rs +++ /dev/null @@ -1,76 +0,0 @@ -mod sidecar; -mod commands; - -use sidecar::SidecarManager; -use std::sync::Mutex; -use tauri::Manager; - -#[cfg_attr(mobile, tauri::mobile_entry_point)] -pub fn run() { - tauri::Builder::default() - .plugin(tauri_plugin_opener::init()) - .plugin(tauri_plugin_process::init()) - .plugin(tauri_plugin_dialog::init()) - .plugin(tauri_plugin_shell::init()) - .plugin(tauri_plugin_updater::Builder::new().build()) - .manage(Mutex::new(SidecarManager::new())) - .invoke_handler(tauri::generate_handler![ - commands::sidecar_request, - commands::install_minecraft, - commands::install_mod_loader, - commands::get_version_list, - commands::launch_game, - commands::offline_login, - commands::search_mods, - commands::install_mod, - commands::create_instance, - commands::list_instances, - ]) - .setup(|app| { - // Hide main window initially - if let Some(main) = app.get_webview_window("main") { - main.hide().ok(); - } - - // After splash animation, close splash and show main - let handle = app.handle().clone(); - tauri::async_runtime::spawn(async move { - tokio::time::sleep(std::time::Duration::from_secs(4)).await; - - // Close splash screen - if let Some(splash) = handle.get_webview_window("splashscreen") { - splash.close().ok(); - } - - // Show main window - if let Some(main) = handle.get_webview_window("main") { - main.show().ok(); - main.set_focus().ok(); - } - }); - - #[cfg(debug_assertions)] - { - eprintln!("[koring] dev mode: sidecar spawn skipped (compile sidecar first)"); - return Ok(()); - } - #[cfg(not(debug_assertions))] - { - let handle = app.handle().clone(); - let state = app.state::>(); - match state.inner().lock() { - Ok(mut sidecar) => { - if let Err(e) = sidecar.spawn(&handle) { - eprintln!("[koring] sidecar spawn failed (non-fatal): {}", e); - } - } - Err(e) => { - eprintln!("[koring] sidecar lock failed (non-fatal): {}", e); - } - } - } - Ok(()) - }) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs deleted file mode 100644 index 4d45dff..0000000 --- a/src-tauri/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Prevents additional console window on Windows in release, DO NOT REMOVE!! -#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] - -fn main() { - koring_launcher_lib::run() -} diff --git a/src-tauri/src/sidecar.rs b/src-tauri/src/sidecar.rs deleted file mode 100644 index 85200a3..0000000 --- a/src-tauri/src/sidecar.rs +++ /dev/null @@ -1,92 +0,0 @@ -use serde::{Deserialize, Serialize}; -use tauri::{AppHandle, Emitter}; -use tauri_plugin_shell::process::{CommandChild, CommandEvent}; -use tauri_plugin_shell::ShellExt; - -#[derive(Debug, Serialize, Deserialize)] -pub struct Request { - pub id: String, - #[serde(rename = "type")] - pub msg_type: String, - pub payload: serde_json::Value, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct Response { - pub id: String, - #[serde(rename = "type")] - pub msg_type: String, - pub payload: serde_json::Value, -} - -pub struct SidecarManager { - child: Option, -} - -impl SidecarManager { - pub fn new() -> Self { - Self { child: None } - } - - pub fn spawn(&mut self, app: &AppHandle) -> Result<(), String> { - let sidecar_command = app - .shell() - .sidecar("koring-sidecar") - .map_err(|e| format!("Failed to create sidecar command: {}", e))?; - - let (mut rx, child) = sidecar_command - .spawn() - .map_err(|e| format!("Failed to spawn sidecar: {}", e))?; - - self.child = Some(child); - - let app_handle = app.clone(); - - tauri::async_runtime::spawn(async move { - while let Some(event) = rx.recv().await { - match event { - CommandEvent::Stdout(line_bytes) => { - let line = String::from_utf8_lossy(&line_bytes); - for line in line.lines() { - let trimmed = line.trim(); - if trimmed.is_empty() { - continue; - } - if let Ok(response) = serde_json::from_str::(trimmed) { - let _ = app_handle.emit("sidecar-response", &response); - } - } - } - CommandEvent::Stderr(line_bytes) => { - let line = String::from_utf8_lossy(&line_bytes); - eprintln!("[sidecar stderr] {}", line); - } - CommandEvent::Error(err) => { - eprintln!("[sidecar error] {}", err); - } - CommandEvent::Terminated(status) => { - eprintln!("[sidecar] terminated with status: {:?}", status); - } - _ => {} - } - } - }); - - Ok(()) - } - - pub fn send_request(&mut self, request: &Request) -> Result<(), String> { - let child = self.child.as_mut().ok_or("Sidecar not running")?; - let json = serde_json::to_string(request).map_err(|e| format!("Serialize error: {}", e))?; - child - .write((json + "\n").as_bytes()) - .map_err(|e| format!("Write error: {}", e)) - } - - pub fn kill(&mut self) -> Result<(), String> { - if let Some(child) = self.child.take() { - child.kill().map_err(|e| format!("Kill error: {}", e))?; - } - Ok(()) - } -} diff --git a/src-tauri/tauri.beta.json b/src-tauri/tauri.beta.json deleted file mode 100644 index f9160cb..0000000 --- a/src-tauri/tauri.beta.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "build": { - "beforeBuildCommand": "echo skip-beta-build" - }, - "bundle": { - "targets": [] - } -} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json deleted file mode 100644 index 9cef4de..0000000 --- a/src-tauri/tauri.conf.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "$schema": "https://schema.tauri.app/config/2", - "productName": "koring-launcher", - "version": "0.1.0", - "identifier": "com.lingke.koring.launcher", - "build": { - "beforeDevCommand": "pnpm dev", - "devUrl": "http://localhost:1420", - "beforeBuildCommand": "pnpm build", - "frontendDist": "../dist" - }, - "app": { - "windows": [ - { - "label": "splashscreen", - "title": "Koring Launcher", - "url": "/splash.html", - "width": 480, - "height": 320, - "decorations": false, - "transparent": true, - "center": true, - "visible": true, - "resizable": false, - "minWidth": 480, - "maxWidth": 480, - "minHeight": 320, - "maxHeight": 320 - }, - { - "label": "main", - "title": "Koring Launcher", - "width": 900, - "height": 600, - "minWidth": 800, - "minHeight": 600, - "decorations": false, - "transparent": true, - "center": true, - "visible": false - } - ], - "security": { - "csp": null - } - }, - "bundle": { - "active": true, - "targets": ["nsis"], - "icon": [ - "icons/icon.png" - ], - "externalBin": [ - "binaries/koring-sidecar" - ], - "createUpdaterArtifacts": true - }, - "plugins": { - "updater": { - "endpoints": [ - "https://cdn.crabnebula.app/update/lingke-network/koring-launcher/{{target}}-{{arch}}/{{current_version}}" - ], - "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEYxRDZBQjc3QUQxNDBGNDUKUldSRkR4U3RkNnZXOGNtdHE4TS80d3p4UHlhaEVVMDFUTFRrQmhySnFVNWdZWHNXOWUraFFhRTcK" - } - } -} diff --git a/src/App.tsx b/src/App.tsx index a2e80b1..4c220df 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,12 @@ +import { useEffect } from "react"; import { RootLayout } from "./layouts/RootLayout"; import { useRouteStore } from "./stores/routeStore"; import { useTheme } from "./hooks/useTheme"; +import { useConfigStore } from "./stores/configStore"; +import { syncThemeFromConfig } from "./stores/themeStore"; +import { syncA11yFromConfig } from "./stores/a11yStore"; +import { syncBackgroundFromConfig } from "./stores/backgroundStore"; +import { useAuthStore } from "./stores/authStore"; import { Home } from "./pages/home"; import { Store } from "./pages/store"; import { Today } from "./pages/today"; @@ -12,6 +18,8 @@ import { SplashDebug } from "./pages/debug/splash-debug"; import { DisplayDebug } from "./pages/debug/display-debug"; import { VersionCardDebug } from "./pages/debug/version-card-debug"; import { TaskDebug } from "./pages/debug/task-debug"; +import { Oobe } from "./pages/oobe"; +import { OobeAboutInfo } from "./pages/oobe/about-info"; const pageMap = { home: Home, @@ -20,6 +28,8 @@ const pageMap = { "play-link": PlayLink, setting: Setting, "task-queue": TaskQueue, + oobe: Oobe, + "oobe/about-info": OobeAboutInfo, debug: Debug, "debug-splash": SplashDebug, "debug-display": DisplayDebug, @@ -32,6 +42,15 @@ function App() { const current = useRouteStore((s) => s.current); const Page = pageMap[current]; + useEffect(() => { + useConfigStore.getState().init().then(() => { + syncThemeFromConfig(); + syncA11yFromConfig(); + syncBackgroundFromConfig(); + useAuthStore.getState().initFromRegistry(); + }); + }, []); + return ( diff --git a/src/api/auth-registry.ts b/src/api/auth-registry.ts new file mode 100644 index 0000000..caf20c0 --- /dev/null +++ b/src/api/auth-registry.ts @@ -0,0 +1,21 @@ +import { ipcInvoke } from './ipc'; + +export interface AuthData { + username: string; + uuid: string; + accessToken: string; + refreshToken: string; + xboxProfile: string; +} + +export async function getAuth(): Promise { + return ipcInvoke('auth:get'); +} + +export async function saveAuth(auth: AuthData): Promise { + await ipcInvoke('auth:save', auth); +} + +export async function deleteAuth(): Promise { + await ipcInvoke('auth:delete'); +} diff --git a/src/api/auth.ts b/src/api/auth.ts index 3f683ac..11af69f 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -1,4 +1,4 @@ -import { sidecarRequest } from "./sidecar"; +import { ipcInvoke } from './ipc'; export interface AuthResult { username: string; @@ -13,12 +13,12 @@ export interface AuthResult { } export async function offlineLogin(username: string): Promise { - return sidecarRequest("auth:offline-login", { username }); + return ipcInvoke('auth:offline-login', { username }); } export async function microsoftLoginStart(clientId: string, redirectUri?: string) { - return sidecarRequest<{ state: string; authUrl: string }>( - "auth:microsoft-login-start", + return ipcInvoke<{ state: string; authUrl: string }>( + 'auth:microsoft-login-start', { client_id: clientId, redirect_uri: redirectUri } ); } @@ -28,7 +28,7 @@ export async function microsoftLoginCallback( clientId: string, redirectUri?: string ): Promise { - return sidecarRequest("auth:microsoft-login-callback", { + return ipcInvoke('auth:microsoft-login-callback', { code, client_id: clientId, redirect_uri: redirectUri, @@ -36,7 +36,7 @@ export async function microsoftLoginCallback( } export async function validateToken(accessToken: string): Promise { - const result = await sidecarRequest<{ valid: boolean }>("auth:validate-token", { + const result = await ipcInvoke<{ valid: boolean }>('auth:validate-token', { accessToken, }); return result.valid; diff --git a/src/api/background.ts b/src/api/background.ts index b56225b..6f87477 100644 --- a/src/api/background.ts +++ b/src/api/background.ts @@ -1,10 +1,10 @@ -import { sidecarRequest } from "./sidecar"; +import { ipcInvoke } from './ipc'; -export type AnimationType = "none" | "gradient" | "particles"; -export type Theme = "light" | "dark" | "system"; +export type AnimationType = 'none' | 'gradient' | 'particles'; +export type Theme = 'light' | 'dark' | 'system'; export interface BackgroundConfig { - type: "image" | "color" | "gradient" | "particles"; + type: 'image' | 'color' | 'gradient' | 'particles'; image?: string; color?: string; blur: number; @@ -15,33 +15,33 @@ export interface BackgroundConfig { } export async function setImageBackground(url: string, blur?: number, opacity?: number): Promise { - return sidecarRequest("background:set-image", { url, blur, opacity }); + return ipcInvoke('background:set-image', { url, blur, opacity }); } export async function setColorBackground(color: string): Promise { - return sidecarRequest("background:set-color", { color }); + return ipcInvoke('background:set-color', { color }); } export async function setBackgroundBlur(blur: number): Promise { - return sidecarRequest("background:set-blur", { blur }); + return ipcInvoke('background:set-blur', { blur }); } export async function setBackgroundOpacity(opacity: number): Promise { - return sidecarRequest("background:set-opacity", { opacity }); + return ipcInvoke('background:set-opacity', { opacity }); } export async function setBackgroundAnimation(type: AnimationType, speed?: number): Promise { - return sidecarRequest("background:set-animation", { type, speed }); + return ipcInvoke('background:set-animation', { type, speed }); } export async function getBackgroundConfig(): Promise { - return sidecarRequest("background:get", {}); + return ipcInvoke('background:get', {}); } export async function setTheme(theme: Theme): Promise { - return sidecarRequest("background:set-theme", { theme }); + return ipcInvoke('background:set-theme', { theme }); } export async function resetBackground(): Promise { - return sidecarRequest("background:reset", {}); + return ipcInvoke('background:reset', {}); } diff --git a/src/api/config.ts b/src/api/config.ts new file mode 100644 index 0000000..fbfbd99 --- /dev/null +++ b/src/api/config.ts @@ -0,0 +1,88 @@ +import { ipcInvoke } from './ipc'; + +export interface ThemeConfig { + darkMode: string; + parallax: boolean; +} + +export interface A11yConfig { + reduceMotion: boolean; + reduceTransparency: boolean; + highContrast: boolean; + contentBlurOpacity: number; +} + +export interface BackgroundConfig { + bgType: string; + image: string; + blur: number; + opacity: number; +} + +export interface GameConfig { + gameDir: string; + resourceDir: string; + savesDir: string; + instancesDir: string; +} + +export interface JavaConfig { + javaPath: string; + memMode: string; + memGB: number; + gc: string; + jvmArgs: string; +} + +export interface AdvancedConfig { + afterLaunch: string; + winMode: string; + customWidth: number; + customHeight: number; + gameArgs: string; + preLaunchCmd: string; + debugMode: boolean; +} + +export interface DownloadConfig { + fileSource: string; + versionSource: string; + threads: number; + speedLimit: number; +} + +export interface SecurityIdConfig { + enabled: boolean; + authUrl: string; +} + +export interface NetworkConfig { + securityId: SecurityIdConfig; +} + +export interface AppConfig { + version: number; + theme: ThemeConfig; + a11y: A11yConfig; + background: BackgroundConfig; + game: GameConfig; + java: JavaConfig; + advanced: AdvancedConfig; + download: DownloadConfig; + network: NetworkConfig; +} + +interface CommandResult { + success: boolean; + data: unknown; + error: string | null; +} + +export async function getConfig(): Promise { + const result = await ipcInvoke('config:get'); + return result; +} + +export async function saveConfig(config: AppConfig): Promise { + await ipcInvoke('config:save', config); +} diff --git a/src/api/index.ts b/src/api/index.ts index c3f962b..03cd209 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,4 +1,4 @@ -export * from "./sidecar"; +export * from "./ipc"; export * from "./install"; export * from "./launch"; export * from "./auth"; diff --git a/src/api/install.ts b/src/api/install.ts index 6d07690..457b84a 100644 --- a/src/api/install.ts +++ b/src/api/install.ts @@ -1,4 +1,4 @@ -import { sidecarRequest } from "./sidecar"; +import { ipcInvoke } from './ipc'; export interface VersionInfo { id: string; @@ -12,7 +12,7 @@ export interface VersionManifest { } export async function getVersionList(type?: string): Promise { - return sidecarRequest("install:version-list", { type }); + return ipcInvoke('install:version-list', { type }); } export async function installMinecraft( @@ -21,7 +21,7 @@ export async function installMinecraft( javaPath?: string, downloadThreads?: number ): Promise<{ version: string; gamePath: string }> { - return sidecarRequest("install:minecraft", { + return ipcInvoke('install:minecraft', { version, gamePath, javaPath, @@ -32,11 +32,11 @@ export async function installMinecraft( export async function installModLoader( mcVersion: string, gamePath: string, - loaderType: "forge" | "fabric" | "quilt" | "neoforge", + loaderType: 'forge' | 'fabric' | 'quilt' | 'neoforge', loaderVersion?: string, javaPath?: string ): Promise<{ loaderType: string; mcVersion: string; loaderVersion: string }> { - return sidecarRequest("install:mod-loader", { + return ipcInvoke('install:mod-loader', { mcVersion, gamePath, loaderType, @@ -46,9 +46,9 @@ export async function installModLoader( } export async function getForgeVersions(mcVersion?: string) { - return sidecarRequest("install:forge-version-list", { mcVersion }); + return ipcInvoke('install:forge-version-list', { mcVersion }); } export async function getFabricVersions(mcVersion?: string) { - return sidecarRequest("install:fabric-version-list", { mcVersion }); + return ipcInvoke('install:fabric-version-list', { mcVersion }); } diff --git a/src/api/instance.ts b/src/api/instance.ts index 1fe219a..1ceab0b 100644 --- a/src/api/instance.ts +++ b/src/api/instance.ts @@ -1,4 +1,4 @@ -import { sidecarRequest } from "./sidecar"; +import { ipcInvoke } from './ipc'; export interface InstanceConfig { name: string; @@ -26,7 +26,7 @@ export async function createInstance( javaPath?: string, memory?: { min?: string; max?: string } ): Promise { - return sidecarRequest("instance:create", { + return ipcInvoke('instance:create', { name, gamePath, mcVersion, @@ -38,14 +38,14 @@ export async function createInstance( } export async function listInstances(instancesPath: string): Promise { - return sidecarRequest("instance:list", { instancesPath }); + return ipcInvoke('instance:list', { instancesPath }); } export async function deleteInstance( name: string, instancesPath: string ): Promise<{ deleted: string }> { - return sidecarRequest<{ deleted: string }>("instance:delete", { + return ipcInvoke<{ deleted: string }>('instance:delete', { name, instancesPath, }); @@ -55,5 +55,5 @@ export async function getInstanceInfo( name: string, instancesPath: string ): Promise { - return sidecarRequest("instance:info", { name, instancesPath }); + return ipcInvoke('instance:info', { name, instancesPath }); } diff --git a/src/api/ipc.ts b/src/api/ipc.ts new file mode 100644 index 0000000..65c06c2 --- /dev/null +++ b/src/api/ipc.ts @@ -0,0 +1,36 @@ +export interface SidecarResponse { + id: string; + type: 'result' | 'error' | 'progress' | 'event'; + payload: T; +} + +export interface CommandResult { + success: boolean; + data?: unknown; + error?: string; +} + +export interface ResultPayload { + success: boolean; + data?: T; + error?: string; +} + +export interface ProgressPayload { + stage: string; + current: number; + total: number; + message?: string; +} + +export async function ipcInvoke(channel: string, payload?: unknown): Promise { + const result = await window.electronAPI?.invoke(channel, payload) as CommandResult; + if (!result?.success) { + throw new Error(result?.error || 'Request failed'); + } + return result.data as T; +} + +export function onIpcEvent(channel: string, callback: (data: T) => void): () => void { + return window.electronAPI?.on(channel, (data) => callback(data as T)) ?? (() => {}); +} diff --git a/src/api/launch.ts b/src/api/launch.ts index 5eb4529..69352fc 100644 --- a/src/api/launch.ts +++ b/src/api/launch.ts @@ -1,5 +1,4 @@ -import { sidecarRequest, onEvent } from "./sidecar"; -import type { UnlistenFn } from "@tauri-apps/api/event"; +import { ipcInvoke, onIpcEvent } from './ipc'; export interface LaunchOptions { gamePath: string; @@ -23,19 +22,26 @@ export interface LaunchResult { } export async function launchGame(options: LaunchOptions): Promise { - return sidecarRequest("launch:launch", options); + return ipcInvoke('launch:launch', options); } export async function diagnoseVersion( gamePath: string, version: string ) { - return sidecarRequest("launch:diagnose", { gamePath, version }); + return ipcInvoke('launch:diagnose', { gamePath, version }); } export function onGameEvent( requestId: string, callback: (event: { event: string; [key: string]: unknown }) => void -): Promise { - return onEvent(requestId, callback as (e: Record) => void); +): () => void { + return onIpcEvent<{ requestId: string; event: string; [key: string]: unknown }>( + 'launch:event', + (data) => { + if (data.requestId === requestId) { + callback(data); + } + } + ); } diff --git a/src/api/mods.ts b/src/api/mods.ts index fda3a2f..1eee649 100644 --- a/src/api/mods.ts +++ b/src/api/mods.ts @@ -1,4 +1,4 @@ -import { sidecarRequest } from "./sidecar"; +import { ipcInvoke } from './ipc'; export interface ModSearchResult { id: string; @@ -10,7 +10,7 @@ export interface ModSearchResult { categories?: string[]; versions?: string[]; loaders?: string[]; - source: "modrinth" | "curseforge"; + source: 'modrinth' | 'curseforge'; } export interface ModVersionResult { @@ -33,9 +33,9 @@ export async function searchMods( loader?: string, limit?: number, offset?: number, - source: "modrinth" | "curseforge" = "modrinth" + source: 'modrinth' | 'curseforge' = 'modrinth' ): Promise { - return sidecarRequest("mods:search", { + return ipcInvoke('mods:search', { query, gameVersion, loader, @@ -47,18 +47,18 @@ export async function searchMods( export async function getModDetail( projectId: string, - source: "modrinth" | "curseforge" + source: 'modrinth' | 'curseforge' ): Promise { - return sidecarRequest("mods:detail", { projectId, source }); + return ipcInvoke('mods:detail', { projectId, source }); } export async function getModVersions( projectId: string, gameVersion?: string, loader?: string, - source: "modrinth" | "curseforge" = "modrinth" + source: 'modrinth' | 'curseforge' = 'modrinth' ): Promise { - return sidecarRequest("mods:versions", { + return ipcInvoke('mods:versions', { projectId, gameVersion, loader, @@ -70,9 +70,9 @@ export async function installMod( projectId: string, versionId: string | undefined, gamePath: string, - source: "modrinth" | "curseforge" = "modrinth" + source: 'modrinth' | 'curseforge' = 'modrinth' ): Promise<{ projectId: string; versionId: string; filename: string; path: string }> { - return sidecarRequest("mods:install", { + return ipcInvoke('mods:install', { projectId, versionId, gamePath, diff --git a/src/api/sidecar.ts b/src/api/sidecar.ts deleted file mode 100644 index ab010db..0000000 --- a/src/api/sidecar.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { invoke } from "@tauri-apps/api/core"; -import { listen, type UnlistenFn } from "@tauri-apps/api/event"; - -export interface SidecarResponse { - id: string; - type: "result" | "error" | "progress" | "event"; - payload: T; -} - -export interface CommandResult { - success: boolean; - data?: { requestId: string }; - error?: string; -} - -export interface ResultPayload { - success: boolean; - data?: T; - error?: string; -} - -export interface ProgressPayload { - stage: string; - current: number; - total: number; - message?: string; -} - -// Generic request function -export async function sidecarRequest( - type: string, - payload: unknown -): Promise { - const result = await invoke("sidecar_request", { - msgType: type, - payload, - }); - - if (!result.success) { - throw new Error(result.error || "Request failed"); - } - - // Wait for the response via event - const requestId = result.data?.requestId; - if (!requestId) { - throw new Error("No request ID returned"); - } - - return waitForResponse(requestId); -} - -// Wait for a specific response by request ID -function waitForResponse(requestId: string, timeout = 60000): Promise { - return new Promise((resolve, reject) => { - const timer = setTimeout(() => { - unlisten(); - reject(new Error("Request timed out")); - }, timeout); - - let unlisten: UnlistenFn; - - listen("sidecar-response", (event) => { - const response = event.payload; - if (response.id !== requestId) return; - - if (response.type === "result") { - clearTimeout(timer); - unlisten(); - const payload = response.payload as ResultPayload; - if (payload.success) { - resolve(payload.data as T); - } else { - reject(new Error(payload.error || "Request failed")); - } - } else if (response.type === "error") { - clearTimeout(timer); - unlisten(); - reject(new Error(String(response.payload))); - } - }).then((fn) => { - unlisten = fn; - }); - }); -} - -// Listen for progress events -export function onProgress( - requestId: string, - callback: (progress: ProgressPayload) => void -): Promise { - return listen("sidecar-response", (event) => { - const response = event.payload; - if (response.id === requestId && response.type === "progress") { - callback(response.payload as ProgressPayload); - } - }); -} - -// Listen for events (game lifecycle, etc.) -export function onEvent( - requestId: string, - callback: (event: Record) => void -): Promise { - return listen("sidecar-response", (event) => { - const response = event.payload; - if (response.id === requestId && response.type === "event") { - callback(response.payload as Record); - } - }); -} diff --git a/src/api/system.ts b/src/api/system.ts new file mode 100644 index 0000000..676b3a5 --- /dev/null +++ b/src/api/system.ts @@ -0,0 +1,26 @@ +import { ipcInvoke } from './ipc'; + +export interface SystemInfo { + app_version: string; + bios_id: string; + os_version: string; + os_name: string; +} + +export async function getSystemInfo(): Promise { + return ipcInvoke('system:info'); +} + +export interface LocaleInfo { + language: string; + region: string; + timezone: string; +} + +export function getLocaleInfo(): LocaleInfo { + const language = navigator.language || 'Unknown'; + const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'Unknown'; + const match = language.match(/[-_]([A-Z]{2})$/i); + const region = match ? match[1].toUpperCase() : 'Unknown'; + return { language, region, timezone }; +} diff --git a/src/api/update.ts b/src/api/update.ts index 519e4ce..ace6114 100644 --- a/src/api/update.ts +++ b/src/api/update.ts @@ -1,43 +1,23 @@ -import { check, type Update } from "@tauri-apps/plugin-updater"; -import { relaunch } from "@tauri-apps/plugin-process"; - export interface DownloadProgress { downloaded: number; contentLength: number; percent: number; } -export async function checkForUpdates(): Promise { - const update = await check(); - return update; +export async function checkForUpdates(): Promise<{ version: string; releaseNotes?: string } | null> { + try { + return await window.electronAPI?.invoke('update:check') as { version: string; releaseNotes?: string } | null; + } catch { + return null; + } } export async function downloadAndInstall( - update: Update, - onProgress?: (progress: DownloadProgress) => void, + onProgress?: (progress: DownloadProgress) => void ): Promise { - let downloaded = 0; - let contentLength = 0; - - await update.downloadAndInstall((event) => { - switch (event.event) { - case "Started": - contentLength = event.data.contentLength ?? 0; - break; - case "Progress": - downloaded += event.data.chunkLength; - onProgress?.({ - downloaded, - contentLength, - percent: contentLength > 0 ? Math.round((downloaded / contentLength) * 100) : 0, - }); - break; - case "Finished": - break; - } - }); + await window.electronAPI?.invoke('update:install'); } export async function relaunchApp(): Promise { - await relaunch(); + await window.electronAPI?.invoke('app:relaunch'); } diff --git a/src/components/VersionCard.tsx b/src/components/VersionCard.tsx index 1c9e2af..5b8de11 100644 --- a/src/components/VersionCard.tsx +++ b/src/components/VersionCard.tsx @@ -1,4 +1,4 @@ -import { BUILD_MODE } from "@/lib/mode"; +import { BUILD_MODE, LOGO_SVG } from "@/lib/mode"; import { useUpdateStore } from "@/stores/updateStore"; import { relaunchApp } from "@/api/update"; import Silk from "@/components/silk/Silk"; @@ -76,7 +76,7 @@ export function VersionCard({ {/* Logo */} - Koring + Koring {/* 版本号 */}

v{VERSION}

diff --git a/src/components/background/BackgroundLayer.tsx b/src/components/background/BackgroundLayer.tsx index 6dc1cb8..cb0f313 100644 --- a/src/components/background/BackgroundLayer.tsx +++ b/src/components/background/BackgroundLayer.tsx @@ -3,8 +3,7 @@ import { useBackgroundStore } from "@/stores/backgroundStore"; import { useThemeStore } from "@/stores/themeStore"; import { useRouteStore } from "@/stores/routeStore"; import { useDevStore } from "@/stores/devStore"; - -const DEFAULT_BG = "/background.png"; +import { DEFAULT_BG } from "@/lib/mode"; export function BackgroundLayer() { const { type, image, blur, opacity } = useBackgroundStore(); @@ -35,6 +34,7 @@ export function BackgroundLayer() { }, [parallax, handleMouseMove]); const bgUrl = image || DEFAULT_BG; + const contentBlur = showContentBlur && !forceDisableContentBlur; const getBackgroundStyle = (): React.CSSProperties => { const base: React.CSSProperties = { @@ -43,12 +43,13 @@ export function BackgroundLayer() { zIndex: 0, pointerEvents: "none", opacity, - transition: parallax ? "transform 0.1s ease-out" : undefined, + transition: "filter 0.4s cubic-bezier(0.4, 0, 0.2, 1), transform 0.1s ease-out", }; - if (blur > 0) { - base.filter = `blur(${blur}px)`; - } + const filters: string[] = []; + if (blur > 0) filters.push(`blur(${blur}px)`); + if (contentBlur) filters.push("blur(24px) saturate(120%)"); + if (filters.length) base.filter = filters.join(" "); if (type === "color") { return { @@ -70,7 +71,7 @@ export function BackgroundLayer() {
diff --git a/src/components/splash/Splash.tsx b/src/components/splash/Splash.tsx index 697d66f..dc55277 100644 --- a/src/components/splash/Splash.tsx +++ b/src/components/splash/Splash.tsx @@ -1,13 +1,14 @@ import { useEffect, useState } from "react"; -import { getVersion } from "@tauri-apps/api/app"; -import { BUILD_MODE } from "@/lib/mode"; +import { BUILD_MODE, LOGO_SVG } from "@/lib/mode"; export default function Splash() { const [phase, setPhase] = useState<"enter" | "visible">("enter"); const [version, setVersion] = useState(""); useEffect(() => { - getVersion().then(setVersion); + window.electronAPI?.invoke('system:info').then((result: any) => { + setVersion(result?.data?.app_version || ''); + }).catch(() => {}); const t = setTimeout(() => setPhase("visible"), 50); return () => clearTimeout(t); }, []); @@ -29,7 +30,7 @@ export default function Splash() { }} > Koring Launcher s.current); const navigate = useRouteStore((s) => s.navigate); const titleBarMode = useRouteStore((s) => s.titleBarMode); @@ -22,6 +20,10 @@ export function TitleBar({ const isSub = titleBarMode === "sub"; const isDefault = titleBarMode === "default"; + const isOobe = titleBarMode === "oobe"; + + const currentRoute = allRoutes.find((r) => r.key === current); + const showBack = isSub || (isOobe && currentRoute?.backable); const currentIdx = routes.findIndex((r) => r.key === current); @@ -49,7 +51,6 @@ export function TitleBar({ useEffect(() => { if (isDefault) { - // 延迟一帧等 DOM 更新后再计算指示条位置 requestAnimationFrame(() => updateIndicator(currentIdx)); } }, [currentIdx, updateIndicator, isDefault]); @@ -61,7 +62,6 @@ export function TitleBar({ return () => window.removeEventListener("resize", onResize); }, [currentIdx, updateIndicator, isDefault]); - // document 级别拖拽事件 useEffect(() => { if (!isDefault) return; @@ -129,12 +129,6 @@ export function TitleBar({ [currentIdx], ); - const handleMouseDown = (e: React.MouseEvent) => { - const target = e.target as HTMLElement; - if (target.closest("[data-no-drag]")) return; - appWindow.startDragging(); - }; - const handleBtnClick = useCallback( (key: string) => { if (hasDragged.current) { @@ -149,8 +143,8 @@ export function TitleBar({ return (
- {/* 左侧区域:返回按钮 + 品牌文字 */} -
- {/* 返回按钮:sub 模式显示 */} + {/* 左侧区域:品牌文字 */} +
+ {/* 返回按钮 */}
- {/* 中间区域:胶囊菜单,绝对定位居中 */} + {/* 中间区域:胶囊菜单 */}
{/* 右侧:窗口控制 */} -
+
diff --git a/src/components/system/WindowControls.tsx b/src/components/system/WindowControls.tsx index af5399b..4e2e67e 100644 --- a/src/components/system/WindowControls.tsx +++ b/src/components/system/WindowControls.tsx @@ -1,7 +1,8 @@ import { useState, useEffect } from "react"; -import { getCurrentWindow } from "@tauri-apps/api/window"; import { BUILD_MODE } from "@/lib/mode"; import { TaskButton } from "@/components/task/TaskButton"; +import { useRouteStore } from "@/stores/routeStore"; +import { Info } from "lucide-react"; import clsx from "clsx"; interface WindowControlsProps { @@ -9,6 +10,7 @@ interface WindowControlsProps { showMaximize?: boolean; showClose?: boolean; isSub?: boolean; + isOobe?: boolean; } export function WindowControls({ @@ -16,59 +18,86 @@ export function WindowControls({ showMaximize = true, showClose = true, isSub = false, + isOobe = false, }: WindowControlsProps) { const [isMaximized, setIsMaximized] = useState(false); - const appWindow = getCurrentWindow(); + const navigate = useRouteStore((s) => s.navigate); useEffect(() => { - appWindow.isMaximized().then(setIsMaximized); - const unlisten = appWindow.onResized(() => { - appWindow.isMaximized().then(setIsMaximized); + window.electronAPI?.isMaximized().then(setIsMaximized); + const unlisten = window.electronAPI?.onResized(() => { + window.electronAPI?.isMaximized().then(setIsMaximized); }); - return () => { unlisten.then(fn => fn()); }; - }, [appWindow]); + return () => { unlisten?.(); }; + }, []); - const handleMinimize = () => appWindow.minimize(); - const handleMaximize = () => appWindow.toggleMaximize(); - const handleClose = () => appWindow.close(); + const handleMinimize = () => window.electronAPI?.minimize(); + const handleMaximize = () => window.electronAPI?.maximize(); + const handleClose = () => window.electronAPI?.close(); const btnClass = "flex items-center justify-center w-[25px] h-[25px] rounded transition-colors cursor-default hover:bg-black/10 dark:hover:bg-white/15 text-black/70 dark:text-white/70 hover:text-black dark:hover:text-white"; const closeBtnClass = "flex items-center justify-center w-[25px] h-[25px] rounded transition-colors cursor-default hover:bg-red-500 text-black/70 dark:text-white/70 hover:text-white"; + const noDrag: React.CSSProperties = { WebkitAppRegion: "no-drag" }; const showBadge = BUILD_MODE !== "run"; const badgeLabel = BUILD_MODE === "dev" ? "DEV" : "BETA"; + const showTask = !isSub && !isOobe; + const showInfo = isOobe; + return ( -
+
{showBadge && ( {badgeLabel} )} - {/* Task button — hidden in sub mode */} - {!isSub && ( -
- -
- )} +
+ +
+ +
+ +
{showMinimize && ( -
+
+ )} {showMaximize && ( -
+
+ )} {showClose && ( -
+
+ )}
); diff --git a/src/components/task/TaskButton.tsx b/src/components/task/TaskButton.tsx index 9a9b307..c18754f 100644 --- a/src/components/task/TaskButton.tsx +++ b/src/components/task/TaskButton.tsx @@ -5,27 +5,17 @@ import { ListTodo } from "lucide-react"; export function TaskButton() { const navigate = useRouteStore((s) => s.navigate); const isRunning = useTaskStore((s) => s.isRunning); - const activeTasks = useTaskStore((s) => s.activeTasks); - const completedTasks = useTaskStore((s) => s.completedTasks); - const tasks = useTaskStore((s) => s.tasks); const running = isRunning(); - const active = activeTasks(); - const completed = completedTasks(); - const hasAny = tasks.length > 0; - - if (!hasAny) return null; - - const badgeCount = running ? active.length : completed.length; return ( ); } diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx new file mode 100644 index 0000000..7d21bab --- /dev/null +++ b/src/components/ui/input.tsx @@ -0,0 +1,20 @@ +import * as React from "react" +import { Input as InputPrimitive } from "@base-ui/react/input" + +import { cn } from "@/lib/utils" + +function Input({ className, type, ...props }: React.ComponentProps<"input">) { + return ( + + ) +} + +export { Input } diff --git a/src/hooks/useTheme.ts b/src/hooks/useTheme.ts index 438db64..1c42b30 100644 --- a/src/hooks/useTheme.ts +++ b/src/hooks/useTheme.ts @@ -7,16 +7,35 @@ export function useTheme() { useEffect(() => { const mq = window.matchMedia("(prefers-color-scheme: dark)"); - const apply = () => { + const applySync = () => { const mode = useThemeStore.getState().darkMode; - let dark = false; - if (mode === "auto") dark = mq.matches; - else if (mode === "dark") dark = true; - document.documentElement.classList.toggle("dark", dark); + if (mode === "auto") { + document.documentElement.classList.toggle("dark", mq.matches); + } else if (mode === "dark") { + document.documentElement.classList.add("dark"); + } else { + document.documentElement.classList.remove("dark"); + } }; - apply(); - mq.addEventListener("change", apply); - return () => mq.removeEventListener("change", apply); + const applyAuto = async () => { + const mode = useThemeStore.getState().darkMode; + if (mode !== "auto") { + applySync(); + return; + } + try { + const theme = await window.electronAPI?.getTheme(); + if (theme !== null && theme !== undefined) { + document.documentElement.classList.toggle("dark", theme === "dark"); + return; + } + } catch {} + applySync(); + }; + + applyAuto(); + mq.addEventListener("change", applySync); + return () => mq.removeEventListener("change", applySync); }, [darkMode]); } diff --git a/src/index.css b/src/index.css index 5feddb2..714c889 100644 --- a/src/index.css +++ b/src/index.css @@ -144,9 +144,12 @@ } body { @apply bg-background text-foreground; + margin: 0; + overflow: hidden; } html { @apply font-sans; + overflow: hidden; } } @@ -260,9 +263,7 @@ .content-blur-overlay { position: fixed; inset: 0; - backdrop-filter: blur(80px) saturate(120%); - -webkit-backdrop-filter: blur(80px) saturate(120%); - z-index: 0; + z-index: 1; pointer-events: none; background: rgba(255, 255, 255, var(--content-blur-opacity, 0.5)); transition: opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1); diff --git a/src/lib/mode.ts b/src/lib/mode.ts index 67ecda3..ae6fb63 100644 --- a/src/lib/mode.ts +++ b/src/lib/mode.ts @@ -1,7 +1,9 @@ export type BuildMode = "dev" | "beta" | "run"; export const BUILD_MODE: BuildMode = (import.meta.env.VITE_BUILD_MODE as BuildMode) || "dev"; -export const APP_ICON: string = import.meta.env.VITE_APP_ICON || "/dev.png"; +export const APP_ICON: string = import.meta.env.VITE_APP_ICON || `${import.meta.env.BASE_URL}dev.png`; +export const DEFAULT_BG = `${import.meta.env.BASE_URL}background.png`; +export const LOGO_SVG = `${import.meta.env.BASE_URL}koring-licon.svg`; export const isDev = BUILD_MODE === "dev"; export const isBeta = BUILD_MODE === "beta"; diff --git a/src/main.tsx b/src/main.tsx index 8b1ddb9..ee0a90e 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,8 +1,13 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; +import { isDev } from "./lib/mode"; import "./index.css"; +if (!isDev) { + document.addEventListener("contextmenu", (e) => e.preventDefault()); +} + ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( diff --git a/src/pages/debug/index.tsx b/src/pages/debug/index.tsx index f7c5e71..05ce642 100644 --- a/src/pages/debug/index.tsx +++ b/src/pages/debug/index.tsx @@ -1,5 +1,5 @@ import { useRouteStore } from "@/stores/routeStore"; -import { Monitor, Paintbrush, CreditCard, ListTodo, ChevronRight, FlaskConical } from "lucide-react"; +import { Monitor, Paintbrush, CreditCard, ListTodo, ChevronRight, FlaskConical, Rocket } from "lucide-react"; const debugPages = [ { @@ -34,6 +34,14 @@ const debugPages = [ color: "text-cyan-500", bg: "bg-cyan-500/10", }, + { + key: "oobe" as const, + icon: Rocket, + title: "OOBE 开箱体验", + desc: "查看开箱引导页面,标题栏切换为 OOBE 模式", + color: "text-pink-500", + bg: "bg-pink-500/10", + }, ]; export function Debug() { diff --git a/src/pages/debug/splash-debug.tsx b/src/pages/debug/splash-debug.tsx index 0ba311b..a797bce 100644 --- a/src/pages/debug/splash-debug.tsx +++ b/src/pages/debug/splash-debug.tsx @@ -1,32 +1,11 @@ import { useState } from "react"; import { Button } from "@/components/ui/button"; -import { WebviewWindow } from "@tauri-apps/api/webviewWindow"; import { Play, Square, RotateCw } from "lucide-react"; import { GlassCard, SettingRow, PageHeader } from "./components"; const openSplash = async () => { try { - const existing = await WebviewWindow.getByLabel("splashscreen"); - if (existing) { - await existing.show(); - await existing.setFocus(); - return; - } - const splash = new WebviewWindow("splashscreen", { - url: "/splash.html", - width: 480, - height: 320, - decorations: false, - transparent: true, - center: true, - visible: true, - resizable: false, - minWidth: 480, - maxWidth: 480, - minHeight: 320, - maxHeight: 320, - } as any); - splash.once("tauri://error", (e) => console.error("Splash window error:", e)); + await window.electronAPI?.invoke('window:openSplash'); } catch (err) { console.error("Failed to open splash:", err); } @@ -34,8 +13,7 @@ const openSplash = async () => { const closeSplash = async () => { try { - const splash = await WebviewWindow.getByLabel("splashscreen"); - if (splash) await splash.close(); + await window.electronAPI?.invoke('window:closeSplash'); } catch (err) { console.error("Failed to close splash:", err); } diff --git a/src/pages/debug/task-debug.tsx b/src/pages/debug/task-debug.tsx index c4c7e4d..56e087d 100644 --- a/src/pages/debug/task-debug.tsx +++ b/src/pages/debug/task-debug.tsx @@ -14,6 +14,7 @@ import { AlertCircle, Check, Ban, + Server, } from "lucide-react"; const taskTypes: { type: TaskType; label: string; icon: typeof Download; color: string; bg: string }[] = [ @@ -26,8 +27,9 @@ const taskTypes: { type: TaskType; label: string; icon: typeof Download; color: { type: "custom", label: "自定义", icon: Zap, color: "text-gray-500", bg: "bg-gray-500/10" }, ]; -function simulateTask(type: TaskType, title: string, duration: number, shouldFail = false) { - useTaskStore.getState().addTask(type, title, `模拟 ${duration / 1000}s 任务`, async (ctx) => { +/** Local task simulation (runs in browser) */ +function simulateLocalTask(type: TaskType, title: string, duration: number, shouldFail = false) { + useTaskStore.getState().addTask(type, title, `本地模拟 ${duration / 1000}s`, async (ctx) => { const steps = 20; const interval = duration / steps; for (let i = 0; i <= steps; i++) { @@ -47,6 +49,22 @@ function simulateTask(type: TaskType, title: string, duration: number, shouldFai }); } +/** IPC @xmcl/task simulation (runs in main process via AbortableTask) */ +function simulateSidecarTask( + type: TaskType, + title: string, + executorName: string, + params: Record, +) { + useTaskStore.getState().addSidecarTask({ + type, + title, + description: `IPC @xmcl/task: ${executorName}`, + executorName, + params, + }); +} + const statusIcons = { pending: RefreshCw, running: RefreshCw, @@ -68,7 +86,7 @@ export function TaskDebug() { return (
- + {/* Stats */}
@@ -124,10 +142,82 @@ export function TaskDebug() {
- {/* Add tasks by type */} + {/* Sidecar @xmcl/task executors */} +
+

+ + Sidecar @xmcl/task 执行器 +

+
+ +
+
+

sleep 执行器

+

3s 计时任务,AbortableTask + 进度追踪

+
+
+ + +
+
+
+ +
+
+

download 执行器

+

模拟下载 100 单位,分块进度更新

+
+
+ +
+
+
+ +
+
+

install 执行器

+

模拟安装 10 步骤,每步 200ms

+
+
+ +
+
+
+
+
+ + {/* Local browser tasks */}

- 添加模拟任务 + 本地浏览器任务

{taskTypes.map((tt) => ( @@ -139,20 +229,18 @@ export function TaskDebug() {

{tt.label}任务

-

- 模拟 3s 成功任务 -

+

本地模拟 3s

+ + {/* Launch button */} + + + {/* Instance button */} + +
+ ); +} diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 6a8bf13..2673bd9 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -1,10 +1,9 @@ +import { StartCard } from "./StartCard"; + export function Home() { return ( -
-
-

Koring Launcher

-

欢迎使用 Koring 启动器

-
+
+
); } diff --git a/src/pages/oobe/about-info.tsx b/src/pages/oobe/about-info.tsx new file mode 100644 index 0000000..f3aa5ad --- /dev/null +++ b/src/pages/oobe/about-info.tsx @@ -0,0 +1,79 @@ +import { useState, useEffect } from "react"; +import { getSystemInfo, getLocaleInfo, type SystemInfo, type LocaleInfo } from "@/api/system"; +import { + Package, + Cpu, + Monitor, + Globe, + Languages, + Clock, + Loader2, +} from "lucide-react"; + +interface InfoItem { + icon: typeof Package; + label: string; + value: string; + color: string; + bg: string; +} + +export function OobeAboutInfo() { + const [systemInfo, setSystemInfo] = useState(null); + const [localeInfo, setLocaleInfo] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + async function load() { + const [sys, loc] = await Promise.all([getSystemInfo(), Promise.resolve(getLocaleInfo())]); + setSystemInfo(sys); + setLocaleInfo(loc); + setLoading(false); + } + load(); + }, []); + + const items: InfoItem[] = systemInfo && localeInfo + ? [ + { icon: Package, label: "App Version", value: `v${systemInfo.app_version}`, color: "text-primary", bg: "bg-primary/10" }, + { icon: Cpu, label: "BIOS ID", value: systemInfo.bios_id, color: "text-blue-500", bg: "bg-blue-500/10" }, + { icon: Monitor, label: "OS Name", value: `${systemInfo.os_name} (${systemInfo.os_version})`, color: "text-purple-500", bg: "bg-purple-500/10" }, + { icon: Globe, label: "Region", value: localeInfo.region, color: "text-green-500", bg: "bg-green-500/10" }, + { icon: Languages, label: "Language", value: localeInfo.language, color: "text-amber-500", bg: "bg-amber-500/10" }, + { icon: Clock, label: "Timezone", value: localeInfo.timezone, color: "text-cyan-500", bg: "bg-cyan-500/10" }, + ] + : []; + + return ( +
+
+
+

System Debug Information

+
+ + {loading ? ( +
+ + Checking system information... +
+ ) : ( +
+ {items.map((item) => ( +
+
+
+ +
+
+

{item.label}

+

{item.value}

+
+
+
+ ))} +
+ )} +
+
+ ); +} diff --git a/src/pages/oobe/index.tsx b/src/pages/oobe/index.tsx new file mode 100644 index 0000000..487d464 --- /dev/null +++ b/src/pages/oobe/index.tsx @@ -0,0 +1,31 @@ +import { useRouteStore } from "@/stores/routeStore"; +import { Rocket, ChevronRight } from "lucide-react"; + +export function Oobe() { + const goBack = useRouteStore((s) => s.goBack); + + return ( +
+
+
+ +
+ +

+ 欢迎使用 Koring Launcher +

+

+ 这是 OOBE(开箱体验)页面。在这里可以引导用户完成初始设置。 +

+ + +
+
+ ); +} diff --git a/src/pages/setting/game/advanced.tsx b/src/pages/setting/game/advanced.tsx index 8d0a743..68a106e 100644 --- a/src/pages/setting/game/advanced.tsx +++ b/src/pages/setting/game/advanced.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useConfigStore } from "@/stores/configStore"; import { Switch } from "@/components/ui/switch"; function GlassCard({ children }: { children: React.ReactNode }) { @@ -30,13 +30,8 @@ const windowSize = [ ]; export function AdvancedSetting() { - const [afterLaunch, setAfterLaunch] = useState("close"); - const [winMode, setWinMode] = useState("default"); - const [customWidth, setCustomWidth] = useState("854"); - const [customHeight, setCustomHeight] = useState("480"); - const [gameArgs, setGameArgs] = useState(""); - const [preLaunchCmd, setPreLaunchCmd] = useState(""); - const [debugMode, setDebugMode] = useState(false); + const adv = useConfigStore((s) => s.config.advanced); + const setAdvanced = useConfigStore((s) => s.setAdvanced); return (
@@ -55,7 +50,7 @@ export function AdvancedSetting() {
{launcherBehavior.map((opt) => ( ))} @@ -76,20 +71,20 @@ export function AdvancedSetting() {
{windowSize.map((opt) => ( ))}
- {winMode === "custom" && ( + {adv.winMode === "custom" && (
setCustomWidth(e.target.value)} + value={adv.customWidth} + onChange={(e) => setAdvanced({ customWidth: Number(e.target.value) })} className="w-20 h-8 px-2 rounded-md border border-input bg-background text-sm text-center font-mono focus:outline-none focus:ring-1 focus:ring-ring" />
@@ -98,8 +93,8 @@ export function AdvancedSetting() { setCustomHeight(e.target.value)} + value={adv.customHeight} + onChange={(e) => setAdvanced({ customHeight: Number(e.target.value) })} className="w-20 h-8 px-2 rounded-md border border-input bg-background text-sm text-center font-mono focus:outline-none focus:ring-1 focus:ring-ring" />
@@ -120,8 +115,8 @@ export function AdvancedSetting() {

附加到游戏启动命令末尾的参数

setGameArgs(e.target.value)} + value={adv.gameArgs} + onChange={(e) => setAdvanced({ gameArgs: e.target.value })} placeholder="可选,例如 --demo" className="w-full h-8 px-3 rounded-md border border-input bg-background text-sm font-mono placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring" /> @@ -140,8 +135,8 @@ export function AdvancedSetting() {

游戏启动前自动执行的命令或程序路径

setPreLaunchCmd(e.target.value)} + value={adv.preLaunchCmd} + onChange={(e) => setAdvanced({ preLaunchCmd: e.target.value })} placeholder="可选,例如 D:\scripts\pre-launch.bat" className="w-full h-8 px-3 rounded-md border border-input bg-background text-sm font-mono placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring" /> @@ -156,7 +151,7 @@ export function AdvancedSetting() {
- + setAdvanced({ debugMode: v })} />
diff --git a/src/pages/setting/game/game-dir.tsx b/src/pages/setting/game/game-dir.tsx index 5a2bdc1..53f580c 100644 --- a/src/pages/setting/game/game-dir.tsx +++ b/src/pages/setting/game/game-dir.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useConfigStore } from "@/stores/configStore"; import { Button } from "@/components/ui/button"; import { RefreshCw } from "lucide-react"; @@ -29,9 +29,8 @@ function PathInput({ label, desc, value, onChange }: { label: string; desc: stri } export function GameDirSetting() { - const [gameDir, setGameDir] = useState(".minecraft"); - const [resourceDir, setResourceDir] = useState(""); - const [savesDir, setSavesDir] = useState(""); + const game = useConfigStore((s) => s.config.game); + const setGame = useConfigStore((s) => s.setGame); return (
@@ -46,8 +45,8 @@ export function GameDirSetting() { setGame({ gameDir: v })} />
@@ -71,8 +70,8 @@ export function GameDirSetting() { setGame({ resourceDir: v })} />
@@ -84,8 +83,8 @@ export function GameDirSetting() { setGame({ savesDir: v })} />
diff --git a/src/pages/setting/game/java-mem.tsx b/src/pages/setting/game/java-mem.tsx index d32d41e..384ea5a 100644 --- a/src/pages/setting/game/java-mem.tsx +++ b/src/pages/setting/game/java-mem.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useConfigStore } from "@/stores/configStore"; import { Button } from "@/components/ui/button"; import { Slider } from "@/components/ui/slider"; import { Cpu, FolderSearch } from "lucide-react"; @@ -37,11 +37,8 @@ const gcOptions = [ ]; export function JavaMemSetting() { - const [javaPath, setJavaPath] = useState(""); - const [memMode, setMemMode] = useState<"auto" | "custom">("auto"); - const [memGB, setMemGB] = useState(4); - const [gc, setGc] = useState("auto"); - const [jvmArgs, setJvmArgs] = useState(""); + const java = useConfigStore((s) => s.config.java); + const setJava = useConfigStore((s) => s.setJava); return (
@@ -62,20 +59,19 @@ export function JavaMemSetting() { - {/* 检测结果列表 */} - {mockJavaList.map((java) => ( - + {mockJavaList.map((j) => ( +

- {java.vendor} {java.version} + {j.vendor} {j.version}

- {java.path} + {j.path}

-
@@ -88,8 +84,8 @@ export function JavaMemSetting() {
setJavaPath(e.target.value)} + value={java.javaPath} + onChange={(e) => setJava({ javaPath: e.target.value })} placeholder="输入 javaw.exe 完整路径" className="flex-1 h-8 px-3 rounded-md border border-input bg-background text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring" /> @@ -108,23 +104,23 @@ export function JavaMemSetting() {
- {memMode === "custom" && ( + {java.memMode === "custom" && (
分配内存 - {memGB} GB + {java.memGB} GB
setMemGB(Array.isArray(v) ? v[0] : v)} + value={[java.memGB]} + onValueChange={(v) => setJava({ memGB: Array.isArray(v) ? v[0] : v })} min={1} max={16} step={1} @@ -149,8 +145,8 @@ export function JavaMemSetting() {

额外 JVM 启动参数

每行一个参数,例如 -XX:+UseZGC