diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..b013920 --- /dev/null +++ b/.env.example @@ -0,0 +1,11 @@ +# Sentry DSN — 从 https://sentry.io 项目设置中获取 +# Web 层(Vite 使用,带 VITE_ 前缀才会注入到前端代码) +VITE_SENTRY_DSN= + +# Electron main 进程(Node.js 环境,不需要 VITE_ 前缀) +SENTRY_DSN= + +# Sentry Source Map Upload(CI 上传用,本地开发不需要) +SENTRY_ORG= +SENTRY_PROJECT= +SENTRY_AUTH_TOKEN= diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..362d4e3 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: "pnpm" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + versioning-strategy: increase + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f12363..3173179 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: "22" + node-version: "24" cache: "pnpm" - name: Install diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index ff7a37e..1dbf42e 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: "22" + node-version: "24" cache: "pnpm" - name: Install diff --git a/.gitignore b/.gitignore index 4efada0..d73f433 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ coverage # Environment files .env .env.* +!.env.example # Security *.pem diff --git a/.issy/issues/0001-welcome-to-issy.md b/.issy/issues/0001-welcome-to-issy.md new file mode 100644 index 0000000..fa97ca2 --- /dev/null +++ b/.issy/issues/0001-welcome-to-issy.md @@ -0,0 +1,14 @@ +--- +title: Welcome to issy +description: Your first issue in this repo +priority: medium +type: improvement +status: open +order: a0 +created: 2026-06-18T09:37:43 +--- + +## Details + +- This issue was created automatically on first run. +- Edit it, close it, or delete it to get started. diff --git "a/.issy/issues/0002-\350\242\253\345\212\250\346\226\255\345\274\200\345\220\216\351\207\215\350\277\236\346\243\200\346\265\213\346\227\240\346\225\210.md" "b/.issy/issues/0002-\350\242\253\345\212\250\346\226\255\345\274\200\345\220\216\351\207\215\350\277\236\346\243\200\346\265\213\346\227\240\346\225\210.md" new file mode 100644 index 0000000..fe0b7cd --- /dev/null +++ "b/.issy/issues/0002-\350\242\253\345\212\250\346\226\255\345\274\200\345\220\216\351\207\215\350\277\236\346\243\200\346\265\213\346\227\240\346\225\210.md" @@ -0,0 +1,13 @@ +--- +title: 被动断开后重连检测无效 +priority: medium +type: bug +status: open +order: a1 +created: 2026-06-18T10:56:31 +--- + +## Details + +downloadkit中,当用户连接串口后,如果被动断开(即拔出usb)可以检测到,但是当用户再次插入usb时没有检测到或者没有主动重连成功 +目前在serial这个flaher模式下发现了,其他类型的flasher不确定 diff --git a/.mise.toml b/.mise.toml index 2b68e8d..11a2700 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,3 +1,3 @@ [tools] node = "24" -pnpm = "11.4.0" +pnpm = "11.6.0" diff --git a/AGENTS.md b/AGENTS.md index ba445b1..49124c4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,7 +16,7 @@ 所有命令在 `weblink/` 目录下执行: ```bash -pnpm install # 安装全部依赖(pnpm 9,Node 22) +pnpm install # 安装全部依赖(pnpm 11,Node 24) pnpm dev # 启动 apps/home 聚合首页 pnpm dev:legacy # 启动根目录遗留 Vue 应用(src/) pnpm build # 全量构建所有包 @@ -50,7 +50,7 @@ ESLint:Vue flat config + `@vue/eslint-config-prettier/skip-formatting`(格 ## CI -`.github/workflows/ci.yml`:pnpm 9 + Node 22,执行顺序为 `lint`(`continue-on-error: true`)→ `test` → `build`。lint 失败不阻塞构建。 +`.github/workflows/ci.yml`:pnpm 11 + Node 24,执行顺序为 `lint`(`continue-on-error: true`)→ `test` → `build`。lint 失败不阻塞构建。 ## 技术栈 @@ -61,6 +61,6 @@ ESLint:Vue flat config + `@vue/eslint-config-prettier/skip-formatting`(格 ## 注意事项 -- Vue DevTools 默认关闭,通过 `VITE_VUE_DEVTOOLS=1` 环境变量启用(Node 22 下有 localStorage shim 兼容处理) +- Vue DevTools 默认关闭,通过 `VITE_VUE_DEVTOOLS=1` 环境变量启用(Node 24 下有 localStorage shim 兼容处理) - `electron/` 是桌面壳代码,与 web 应用分开,当前未集成到 pnpm workspace - Changesets 配置 `commit: false`、`access: "restricted"`,基线分支为 `main` diff --git a/kits/downloadkit/src/features/flasher/pages/FlasherPage.vue b/kits/downloadkit/src/features/flasher/pages/FlasherPage.vue index de99f87..af7c1d9 100644 --- a/kits/downloadkit/src/features/flasher/pages/FlasherPage.vue +++ b/kits/downloadkit/src/features/flasher/pages/FlasherPage.vue @@ -22,6 +22,7 @@ import { prepareFlasherForCurrentSelection, startFlash, cancelDownload, + tryRestoreConnection, } from "../services/flasherFacade"; import { flasherLogger } from "../services/flasherLogger"; import { useUrlParams } from "../../../url-params/useUrlParams"; @@ -336,6 +337,15 @@ onMounted(async () => { } } + // 页面加载后尝试静默恢复上次的设备连接 + if (!hasUrlParams) { + try { + await tryRestoreConnection(); + } catch (error) { + flasherLogger.warning(error instanceof Error ? error.message : String(error)); + } + } + store.setFlasherRuntime(getFlasherRuntimeInfo()); isHydratingPersistence.value = false; diff --git a/kits/downloadkit/src/features/flasher/services/flasherFacade.ts b/kits/downloadkit/src/features/flasher/services/flasherFacade.ts index a55e783..5848f37 100644 --- a/kits/downloadkit/src/features/flasher/services/flasherFacade.ts +++ b/kits/downloadkit/src/features/flasher/services/flasherFacade.ts @@ -7,53 +7,28 @@ import type { FlasherProtocol } from "../../../protocols/types"; import { normalizeConfigBySchema } from "../../../plugins/config/pluginConfig.validators"; import type { PluginConfigObject } from "../../../plugins/config/pluginConfig.types"; import type { Transport } from "../../../transports/types"; -import { useFlasherStore, type DeviceStatus } from "../stores/flasher.store"; +import { useFlasherStore } from "../stores/flasher.store"; import { flasherLogger } from "./flasherLogger"; import { i18n } from "../../../i18n"; import { formatBytes, formatSpeed } from "../../../shared/format/formatBytes"; -import { SessionManager } from "../session/SessionManager"; +import { FlasherSession } from "../../../transports/FlasherSession"; +import { DeviceIdentityStore } from "../../../transports/DeviceIdentityStore"; function t(key: string, values?: Record): string { return String(i18n.global.t(key, (values ?? {}) as Record)); } -interface PreparedTransportSession { +interface PreparedInfo { pluginId: string; configKey: string; - transport: Transport; } -let prepared: PreparedTransportSession | null = null; -let selectingTask: Promise | null = null; -let sessionManager: SessionManager | null = null; +let prepared: PreparedInfo | null = null; /** 当前活跃的下载会话(供 cancelDownload() 和 disconnect 中断使用)。 */ let currentSession: DownloadSession | null = null; /** 当前活跃的协议实例(供 disconnect 时立即中断 I/O 使用)。 */ let currentProtocol: FlasherProtocol | null = null; -function getSessionManager(): SessionManager { - if (!sessionManager) { - sessionManager = new SessionManager(); - sessionManager.onStatusChange((status) => { - const store = useFlasherStore(); - store.setFlasherState({ status: status as DeviceStatus, label: store.flasherLabel, error: store.flasherError }); - }); - sessionManager.onDisconnect(() => { - // 串口被动断开时:立即中断协议 I/O(无需等超时),再取消下载流程 - currentProtocol?.abort?.(); - flasherLogger.warning(t("flasherPage.deviceDisconnected")); - cancelDownload(); - }); - sessionManager.onConfirmReconnect((portInfo: string) => { - // VID/PID 匹配但无法确认是同一设备时,询问用户 - return Promise.resolve( - window.confirm(t("flasherPage.confirmReconnect", { device: portInfo })), - ); - }); - } - return sessionManager; -} - /** 中断当前正在进行的下载(用户取消 / 串口被动断开 共用)。 */ export function cancelDownload(): void { currentSession?.cancel(); @@ -96,9 +71,17 @@ export function getCurrentPluginMeta(): FlasherPlugin | null { } export function getCurrentDeviceDetails(): string[] { - if (!prepared) return []; - const details = prepared.transport.getDeviceDetails?.() ?? []; - return details.filter((item) => item && item.trim().length > 0); + const hs = FlasherSession.getInstance(); + if (hs.getStatus() !== 'ready') return []; + const identity = hs.getDeviceIdentity(); + if (!identity) return []; + const details: string[] = []; + if (identity.usbVendorId != null && identity.usbProductId != null) { + details.push(`${identity.usbVendorId.toString(16).padStart(4, '0')}:${identity.usbProductId.toString(16).padStart(4, '0')}`); + } + if (identity.manufacturerName) details.push(identity.manufacturerName); + if (identity.productName) details.push(identity.productName); + return details; } function getPluginConfigSnapshot(plugin: FlasherPlugin): PluginConfigObject { @@ -162,6 +145,35 @@ export function getFlasherRuntimeInfo(): { canFlash: boolean; canSelectConnectio return { canFlash: plugin.canFlash, canSelectConnection: plugin.canSelectConnection, hint }; } +/** Silently restore device connection from stored identity on page load. */ +export async function tryRestoreConnection(): Promise { + const store = useFlasherStore(); + const plugin = resolveCurrentPlugin(); + if (!plugin || !plugin.canSelectConnection) return false; + + const hs = FlasherSession.getInstance(); + const restored = await hs.tryRestore(); + if (!restored) return false; + + const configKey = JSON.stringify(getPluginConfigSnapshot(plugin)); + prepared = { pluginId: plugin.id, configKey }; + store.setFlasherState({ status: 'ready', label: plugin.displayName, error: null }); + + hs.onDisconnect(() => { + currentProtocol?.abort?.(); + flasherLogger.warning(t('flasherPage.deviceDisconnected')); + cancelDownload(); + store.setFlasherState({ status: 'disconnected', label: store.flasherLabel, error: null }); + }); + + hs.onReconnect(() => { + flasherLogger.info(t('flasherPage.deviceReconnected')); + store.setFlasherState({ status: 'ready', label: plugin.displayName, error: null }); + }); + + return true; +} + export async function prepareFlasherForCurrentSelection(options?: { forceReselect?: boolean }): Promise { const store = useFlasherStore(); const plugin = resolveCurrentPlugin(); @@ -180,53 +192,81 @@ export async function prepareFlasherForCurrentSelection(options?: { forceReselec const configSnapshot = getPluginConfigSnapshot(plugin); const configKey = JSON.stringify(configSnapshot); + const hs = FlasherSession.getInstance(); - if (prepared && (prepared.pluginId !== plugin.id || prepared.configKey !== configKey || options?.forceReselect)) { - sessionManager?.destroy(); - await prepared.transport.close().catch(() => undefined); - prepared = null; - } - - if (!prepared) { - prepared = { pluginId: plugin.id, configKey, transport: plugin.createTransport(configSnapshot) }; + // 检测配置变更或插件切换 + if (hs.getStatus() !== 'idle') { + if (prepared?.pluginId !== plugin.id || options?.forceReselect) { + await hs.release(); + prepared = null; + } else if (prepared.configKey !== configKey) { + // 配置变更(如波特率修改),保持设备连接但用新配置重建传输 + await hs.reopen(configSnapshot as Record); + prepared.configKey = configKey; + store.setFlasherState({ status: 'ready', label: plugin.displayName, error: null }); + return; + } else { + // 已有活跃连接且配置未变 + store.setFlasherState({ status: 'ready', label: plugin.displayName, error: null }); + return; + } } if (!plugin.canSelectConnection) { - store.setFlasherState({ status: "idle", label: null, error: t("flasherPage.noConnectionNeeded") }); + store.setFlasherState({ status: 'idle', label: null, error: t('flasherPage.noConnectionNeeded') }); return; } - if (prepared.transport.isDeviceReady?.()) { - const label = prepared.transport.getDeviceLabel?.() ?? plugin.displayName; - store.setFlasherState({ status: "ready", label, error: null }); + // 使用 FlasherSession 管理连接流程 + store.setFlasherState({ status: 'pending', label: null, error: null }); + + try { + // 从持久化存储读取上次的设备身份(如有) + const identityStore = new DeviceIdentityStore(); + const stored = await identityStore.load(); + + // 首次连接时传入插件配置,确保 lastConfig 被持久化 + const identity = stored ?? { + type: plugin.connectionType, + lastConfig: getPluginConfigSnapshot(plugin) as Record, + }; + + const transport = await withTimeout( + hs.acquire(plugin.connectionType, identity), + SELECT_DEVICE_TIMEOUT_MS, + t('flasherPage.deviceSelectionTimeout'), + ); + + if (hs.getStatus() !== 'ready') return; // user cancelled → stays pending + + prepared = { pluginId: plugin.id, configKey }; + store.setFlasherState({ status: 'ready', label: plugin.displayName, error: null }); + + // 监听设备被动断开与自动重连 + hs.onDisconnect(() => { + currentProtocol?.abort?.(); + flasherLogger.warning(t('flasherPage.deviceDisconnected')); + cancelDownload(); + store.setFlasherState({ + status: 'disconnected', + label: store.flasherLabel, + error: null, + }); + }); + + hs.onReconnect(() => { + flasherLogger.info(t('flasherPage.deviceReconnected')); + store.setFlasherState({ status: 'ready', label: plugin.displayName, error: null }); + }); + return; + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + store.setFlasherState({ status: 'failed', label: null, error: message }); + await hs.release().catch(() => undefined); + prepared = null; + throw error; } - - // 使用 SessionManager 管理连接流程(pending → selecting → ready) - store.setFlasherState({ status: "pending", label: null, error: null }); - if (selectingTask) return selectingTask; - selectingTask = (async () => { - const sm = getSessionManager(); - try { - await withTimeout( - sm.connect(prepared!.transport), - SELECT_DEVICE_TIMEOUT_MS, - t("flasherPage.deviceSelectionTimeout"), - ); - if (sm.status !== "ready") return; // user cancelled → stays pending - const label = prepared?.transport.getDeviceLabel?.() ?? plugin.displayName; - store.setFlasherState({ status: "ready", label, error: null }); - } catch (error) { - const message = error instanceof Error ? error.message : String(error); - store.setFlasherState({ status: "failed", label: null, error: message }); - await prepared?.transport.close().catch(() => undefined); - prepared = null; - throw error; - } finally { - selectingTask = null; - } - })(); - return selectingTask; } /** @returns true if flash completed successfully; false if user cancelled (e.g. ST-Link target picker). */ @@ -251,6 +291,19 @@ export async function startFlash(input: unknown, deps: PluginRuntimeDeps = {}): store.setDownloadResult("error"); throw new Error(t("flasherPage.flashNotImplemented")); } + const hs = FlasherSession.getInstance(); + const existingTransport = hs.getStatus() === 'ready' ? hs.getTransport() : null; + + let transport: Transport; + if (existingTransport) { + transport = existingTransport; + } else if (!plugin.canSelectConnection) { + transport = plugin.createTransport(getPluginConfigSnapshot(plugin)); + } else { + store.setDownloadResult("error"); + throw new Error(t("flasherPage.selectConnectionFirst")); + } + if (!prepared || prepared.pluginId !== plugin.id) { store.setDownloadResult("error"); throw new Error(t("flasherPage.selectConnectionFirst")); @@ -268,7 +321,6 @@ export async function startFlash(input: unknown, deps: PluginRuntimeDeps = {}): store.setRuntimePhase("idle"); }; - const transport = prepared.transport; const configSnapshot = getPluginConfigSnapshot(plugin); const protocol = plugin.createProtocol(transport, deps, configSnapshot); const speedWindow: Array<{ t: number; w: number }> = []; diff --git a/kits/downloadkit/src/features/flasher/session/SessionManager.spec.ts b/kits/downloadkit/src/features/flasher/session/SessionManager.spec.ts index 2bdad95..5cd4807 100644 --- a/kits/downloadkit/src/features/flasher/session/SessionManager.spec.ts +++ b/kits/downloadkit/src/features/flasher/session/SessionManager.spec.ts @@ -1,35 +1,28 @@ -import { describe, expect, it, vi } from "vitest"; -import { SessionManager } from "./SessionManager"; -import type { Transport } from "../../../../transports/types"; +import { describe, expect, it, vi } from 'vitest'; +import { SessionManager } from './SessionManager'; +import type { Transport } from '../../../../transports/types'; function createMockTransport(overrides: Partial = {}): Transport { return { - name: "mock-transport", - selectDevice: vi.fn().mockResolvedValue(undefined), + name: 'mock-transport', open: vi.fn().mockResolvedValue(undefined), close: vi.fn().mockResolvedValue(undefined), write: vi.fn(), read: vi.fn(), - isDeviceReady: vi.fn().mockReturnValue(true), - getDeviceLabel: vi.fn().mockReturnValue("mock-device"), - getDeviceDetails: vi.fn().mockReturnValue([]), - onDisconnect: vi.fn(), - onReconnect: vi.fn(), - removeEventListeners: vi.fn(), ...overrides, }; } -describe("SessionManager", () => { - describe("初始状态", () => { - it("创建时为 idle", () => { +describe('SessionManager', () => { + describe('初始状态', () => { + it('创建时为 idle', () => { const sm = new SessionManager(); - expect(sm.status).toBe("idle"); + expect(sm.status).toBe('idle'); }); }); - describe("connect()", () => { - it("正常流程: pending → selecting → ready", async () => { + describe('connect()', () => { + it('正常流程: pending → selecting → ready', async () => { const sm = new SessionManager(); const transport = createMockTransport(); const statuses: string[] = []; @@ -37,85 +30,45 @@ describe("SessionManager", () => { sm.onStatusChange((s) => statuses.push(s)); await sm.connect(transport); - expect(statuses).toEqual(["pending", "selecting", "ready"]); - expect(sm.status).toBe("ready"); - expect(transport.selectDevice).toHaveBeenCalledOnce(); + expect(statuses).toEqual(['pending', 'selecting', 'ready']); + expect(sm.status).toBe('ready'); expect(transport.open).toHaveBeenCalledOnce(); }); - it("用户取消选择时回到 pending", async () => { + it('连接失败转为 failed', async () => { const sm = new SessionManager(); const transport = createMockTransport({ - selectDevice: vi.fn().mockRejectedValue(new Error("cancelled")), + open: vi.fn().mockRejectedValue(new Error('port busy')), }); - const statuses: string[] = []; - - sm.onStatusChange((s) => statuses.push(s)); - await sm.connect(transport); - - expect(statuses).toEqual(["pending", "selecting", "pending"]); - expect(sm.status).toBe("pending"); - }); - - it("Not allowed 错误也视为用户取消,回到 pending", async () => { - const sm = new SessionManager(); - const transport = createMockTransport({ - selectDevice: vi.fn().mockRejectedValue(new Error("Not allowed")), - }); - - await sm.connect(transport); - expect(sm.status).toBe("pending"); - }); - it("其他错误转为 failed", async () => { - const sm = new SessionManager(); - const transport = createMockTransport({ - selectDevice: vi.fn().mockRejectedValue(new Error("port busy")), - }); - - await expect(sm.connect(transport)).rejects.toThrow("port busy"); - expect(sm.status).toBe("failed"); - }); - }); - - describe("connect() 无 selectDevice(如 ST-Link 直连)", () => { - it("跳过 selectDevice 直接 open", async () => { - const sm = new SessionManager(); - const open = vi.fn().mockResolvedValue(undefined); - const transport = createMockTransport({ - selectDevice: undefined, - open, - }); - - await sm.connect(transport); - expect(sm.status).toBe("ready"); - expect(open).toHaveBeenCalledOnce(); + await expect(sm.connect(transport)).rejects.toThrow('port busy'); + expect(sm.status).toBe('failed'); }); }); - describe("disconnect()", () => { - it("关闭传输并回到 idle", async () => { + describe('disconnect()', () => { + it('关闭传输并回到 idle', async () => { const sm = new SessionManager(); const transport = createMockTransport(); await sm.connect(transport); - expect(sm.status).toBe("ready"); + expect(sm.status).toBe('ready'); await sm.disconnect(); - expect(sm.status).toBe("idle"); + expect(sm.status).toBe('idle'); expect(transport.close).toHaveBeenCalledOnce(); }); }); - describe("destroy()", () => { - it("清理所有资源", async () => { + describe('destroy()', () => { + it('清理所有资源', async () => { const sm = new SessionManager(); const transport = createMockTransport(); await sm.connect(transport); sm.destroy(); - expect(sm.status).toBe("idle"); + expect(sm.status).toBe('idle'); }); }); }); diff --git a/kits/downloadkit/src/features/flasher/session/SessionManager.ts b/kits/downloadkit/src/features/flasher/session/SessionManager.ts index f01a10a..39ebd5d 100644 --- a/kits/downloadkit/src/features/flasher/session/SessionManager.ts +++ b/kits/downloadkit/src/features/flasher/session/SessionManager.ts @@ -1,182 +1,68 @@ -import type { Transport } from "../../../../transports/types"; -import type { ConnectionStatus } from "./types"; -import { createSerialReconnectManager, type SerialReconnectManager } from "./serialReconnectManager"; +import type { Transport } from '../../../../transports/types'; +import type { ConnectionStatus } from './types'; export type StatusChangeHandler = (status: ConnectionStatus) => void; -export type DisconnectHandler = () => void; -export type ReconnectHandler = () => Promise; -/** 设备重连确认:VID/PID 匹配但无法确认是同一设备时,询问用户是否接受重连。 */ -export type ConfirmReconnectHandler = (portInfo: string) => Promise; /** - * USB 设备会话管理器。 + * USB 设备会话管理器(简化版)。 * - * 职责:管理设备从「选择 → 连接 → 监听 → 断开 → 重连」的全生命周期, - * 通过回调函数与外部(如 Pinia store)解耦。 + * 职责:管理设备从「选择 → 连接」的简单生命周期。 + * 设备选择由 FlasherSession 统一管理。 * * 状态机: * idle → pending → selecting → ready - * ↘ disconnected → (auto-reconnect) → ready * selecting → pending (用户取消弹窗) * any → failed (错误) - * - * 对于 WebSerial 等支持重连的传输层,自动创建 SerialReconnectManager - * 来管理 navigator 级别的事件监听和轮询兜底。 */ export class SessionManager { - private _status: ConnectionStatus = "idle"; + private _status: ConnectionStatus = 'idle'; private _transport: Transport | null = null; private _onStatusChange: StatusChangeHandler | null = null; - private _onDisconnect: DisconnectHandler | null = null; - private _onReconnect: ReconnectHandler | null = null; - private _onConfirmReconnect: ConfirmReconnectHandler | null = null; - - /** 串口重连管理器(当传输层支持时) */ - private _reconnectManager: SerialReconnectManager | null = null; - /** 当前连接状态(只读) */ get status(): ConnectionStatus { return this._status; } - /** 监听状态变化 */ onStatusChange(handler: StatusChangeHandler): void { this._onStatusChange = handler; } - /** 注册被动断开回调 */ - onDisconnect(handler: DisconnectHandler): void { - this._onDisconnect = handler; - } - - /** 注册自动重连回调 */ - onReconnect(handler: ReconnectHandler): void { - this._onReconnect = handler; - } - - /** 注册重连确认回调(VID/PID 匹配时询问用户)。 */ - onConfirmReconnect(handler: ConfirmReconnectHandler): void { - this._onConfirmReconnect = handler; - } - - /** - * 启动连接流程。 - * 状态机:pending → selecting → ready - * 如果用户取消设备弹窗,状态回到 pending。 - */ async connect(transport: Transport): Promise { this._transport = transport; - this.setState("pending"); + this.setState('pending'); try { - this.setState("selecting"); - await transport.selectDevice?.(); + this.setState('selecting'); await transport.open(); - this.setState("ready"); - - // 成功连接后,尝试创建重连管理器 - this.setupReconnectManager(transport); + this.setState('ready'); } catch (error: unknown) { - // 用户取消设备弹窗:回到 pending const msg = error instanceof Error ? error.message : String(error); - if (msg.includes("cancelled") || msg.includes("canceled") || msg.includes("Not allowed")) { - this.setState("pending"); + if (msg.includes('cancelled') || msg.includes('canceled') || msg.includes('Not allowed')) { + this.setState('pending'); return; } - this.setState("failed"); + this.setState('failed'); throw error; } } - /** 释放当前会话,清理监听器 */ async disconnect(): Promise { - this.teardownReconnectManager(); if (this._transport) { await this._transport.close().catch(() => undefined); } this._transport = null; - this.setState("idle"); + this.setState('idle'); } - /** 销毁管理器,清理所有资源 */ destroy(): void { - this.teardownReconnectManager(); this._transport = null; this._onStatusChange = null; - this._onDisconnect = null; - this._onReconnect = null; - this._onConfirmReconnect = null; - this._status = "idle"; + this._status = 'idle'; } - // ── 私有方法 ── - private setState(status: ConnectionStatus): void { this._status = status; this._onStatusChange?.(status); } - - /** - * 检查传输层是否支持 ReconnectManager(通过 duck-typing 判断)。 - * 目前支持 WebSerialTransport(具有 `port` 属性和 `replacePort` 方法)。 - */ - private setupReconnectManager(transport: Transport): void { - const reconnectable = transport as { - readonly port: SerialPort | null; - replacePort?: (port: SerialPort) => void; - }; - - if (!("port" in transport) || !reconnectable.replacePort) return; - if (!reconnectable.port) return; - - this._reconnectManager = createSerialReconnectManager({ - enabled: () => this._status === "ready" || this._status === "disconnected", - onDisconnect: () => { - this.setState("disconnected"); - this._onDisconnect?.(); - }, - onReconnect: (newPort: SerialPort) => { - if (this._status !== "disconnected") return; - this.setState("selecting"); - reconnectable.replacePort!(newPort); - transport - .open() - .then(() => { - this.setState("ready"); - return this._onReconnect?.(); - }) - .catch(() => { - this.setState("failed"); - }); - }, - confirmReconnect: this._onConfirmReconnect - ? async (port: SerialPort) => { - const info = port.getInfo?.(); - const label = - info && typeof info.usbVendorId === "number" - ? `VID:${info.usbVendorId.toString(16).toUpperCase()} PID:${info.usbProductId?.toString(16).toUpperCase()}` - : "unknown"; - return this._onConfirmReconnect!(label); - } - : undefined, - }); - - this._reconnectManager.rememberPort(reconnectable.port); - this._reconnectManager.start(); - - // I/O 级断开检测:传输层的 read/write 失败(stream closed)时,通过 - // ReconnectManager 触发断开流程。这是最可靠的检测路径(覆盖 navigator 事件不可靠的场景)。 - transport.onDisconnect?.(() => { - this._reconnectManager?.notifyIoLinkLost(); - }); - } - - private teardownReconnectManager(): void { - if (this._reconnectManager) { - this._reconnectManager.stop(); - this._reconnectManager.clearRemembered(); - this._reconnectManager = null; - } - } } diff --git a/kits/downloadkit/src/features/flasher/session/serialReconnectManager.spec.ts b/kits/downloadkit/src/features/flasher/session/serialReconnectManager.spec.ts deleted file mode 100644 index 35600ed..0000000 --- a/kits/downloadkit/src/features/flasher/session/serialReconnectManager.spec.ts +++ /dev/null @@ -1,356 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { createSerialReconnectManager } from "./serialReconnectManager"; - -/** - * 模拟 SerialPort 的最小接口。 - * 使用 EventTarget 以便支持对象引用匹配测试。 - */ -function makePort(vid?: number, pid?: number): SerialPort { - // SerialPort 继承 EventTarget,这里用普通对象模拟 - const port = { getInfo: () => ({ usbVendorId: vid, usbProductId: pid }) } as unknown as SerialPort; - return port; -} - -describe("createSerialReconnectManager", () => { - let serialTarget: EventTarget & { getPorts: ReturnType }; - let enabled: boolean; - - beforeEach(() => { - enabled = true; - serialTarget = new EventTarget() as EventTarget & { getPorts: ReturnType }; - Object.assign(serialTarget, { - requestPort: vi.fn(), - getPorts: vi.fn().mockResolvedValue([]), - }); - vi.stubGlobal("navigator", { serial: serialTarget }); - }); - - afterEach(() => { - vi.unstubAllGlobals(); - }); - - describe("断开检测", () => { - it("port.ondisconnect 直接回调触发 onDisconnect", async () => { - const port = makePort(0x1234, 0x5678); - const onDisconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect, - onReconnect: vi.fn(), - }); - mgr.rememberPort(port); - mgr.start(); - - // port.ondisconnect 应已被设置 - const handler = (port as unknown as { ondisconnect: (() => void) | null }).ondisconnect; - expect(handler).toBeInstanceOf(Function); - handler!(); - - expect(onDisconnect).toHaveBeenCalledOnce(); - mgr.stop(); - }); - - it("port.ondisconnect 在 stop() 后清除", async () => { - const port = makePort(0x1234, 0x5678); - const onDisconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect, - onReconnect: vi.fn(), - }); - mgr.rememberPort(port); - mgr.start(); - mgr.stop(); - - // stop 后 ondisconnect 应被清除 - expect((port as unknown as { ondisconnect: unknown }).ondisconnect).toBeNull(); - - // 手动调用也不会触发 - const handler = (port as unknown as { ondisconnect: (() => void) | null }).ondisconnect; - handler?.(); - expect(onDisconnect).not.toHaveBeenCalled(); - }); - - it("port.ondisconnect 与 navigator.serial 事件同时触发不会重复通知", async () => { - const port = makePort(0x1234, 0x5678); - const onDisconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect, - onReconnect: vi.fn(), - }); - mgr.rememberPort(port); - mgr.start(); - - // 先触发 port.ondisconnect - const handler = (port as unknown as { ondisconnect: (() => void) | null }).ondisconnect; - handler!(); - - // 再触发 navigator.serial disconnect 事件 - const ev = new Event("disconnect"); - Object.defineProperty(ev, "port", { value: port, configurable: true }); - serialTarget.dispatchEvent(ev); - - // 应该只收到一次通知 - expect(onDisconnect).toHaveBeenCalledOnce(); - mgr.stop(); - }); - - it("navigator.serial disconnect 事件先触发时 port.ondisconnect 不再重复通知", async () => { - const port = makePort(0x1234, 0x5678); - const onDisconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect, - onReconnect: vi.fn(), - }); - mgr.rememberPort(port); - mgr.start(); - - // 先触发 navigator.serial disconnect 事件 - const ev = new Event("disconnect"); - Object.defineProperty(ev, "port", { value: port, configurable: true }); - serialTarget.dispatchEvent(ev); - expect(onDisconnect).toHaveBeenCalledOnce(); - - // 再调用 port.ondisconnect - const handler = (port as unknown as { ondisconnect: (() => void) | null }).ondisconnect; - handler?.(); - - // 不应再次通知 - expect(onDisconnect).toHaveBeenCalledOnce(); - mgr.stop(); - }); - - it("serial disconnect 事件触发 onDisconnect", async () => { - const port = makePort(0x1234, 0x5678); - const onDisconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect, - onReconnect: vi.fn(), - }); - mgr.rememberPort(port); - mgr.start(); - - // dispatch navigator.serial disconnect 事件 - const ev = new Event("disconnect"); - Object.defineProperty(ev, "port", { value: port, configurable: true }); - serialTarget.dispatchEvent(ev); - - expect(onDisconnect).toHaveBeenCalledOnce(); - mgr.stop(); - }); - - it("其他设备的断开事件不会触发 onDisconnect(VID/PID 不匹配)", async () => { - const port = makePort(0x1234, 0x5678); - const otherPort = makePort(0x9999, 0x8888); - const onDisconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect, - onReconnect: vi.fn(), - }); - mgr.rememberPort(port); - mgr.start(); - - const ev = new Event("disconnect"); - Object.defineProperty(ev, "port", { value: otherPort, configurable: true }); - serialTarget.dispatchEvent(ev); - - expect(onDisconnect).not.toHaveBeenCalled(); - mgr.stop(); - }); - - it("stop() 后不再处理断开事件", async () => { - const port = makePort(0x1234, 0x5678); - const onDisconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect, - onReconnect: vi.fn(), - }); - mgr.rememberPort(port); - mgr.start(); - mgr.stop(); - - const ev = new Event("disconnect"); - Object.defineProperty(ev, "port", { value: port, configurable: true }); - serialTarget.dispatchEvent(ev); - - expect(onDisconnect).not.toHaveBeenCalled(); - }); - }); - - describe("重连检测", () => { - it("serial connect 事件触发 onReconnect(VID/PID 匹配)", async () => { - const remembered = makePort(0x1111, 0x2222); - const incoming = makePort(0x1111, 0x2222); - const onReconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect: vi.fn(), - onReconnect, - }); - mgr.rememberPort(remembered); - mgr.start(); - - const ev = new Event("connect"); - Object.defineProperty(ev, "port", { value: incoming, configurable: true }); - serialTarget.dispatchEvent(ev); - - // onReconnect 应该收到新的端口对象 + needsConfirm 标志 - await vi.waitFor(() => expect(onReconnect).toHaveBeenCalledWith(incoming, true), { timeout: 500 }); - mgr.stop(); - }); - - it("disabled 时不重连", async () => { - enabled = false; - const remembered = makePort(1, 2); - const incoming = makePort(1, 2); - const onReconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect: vi.fn(), - onReconnect, - }); - mgr.rememberPort(remembered); - mgr.start(); - - const ev = new Event("connect"); - Object.defineProperty(ev, "port", { value: incoming, configurable: true }); - serialTarget.dispatchEvent(ev); - - await new Promise((r) => setTimeout(r, 50)); - expect(onReconnect).not.toHaveBeenCalled(); - mgr.stop(); - }); - - it("其他设备的 connect 事件不会触发 onReconnect", async () => { - const remembered = makePort(0x1111, 0x2222); - const other = makePort(0x3333, 0x4444); - const onReconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect: vi.fn(), - onReconnect, - }); - mgr.rememberPort(remembered); - mgr.start(); - - const ev = new Event("connect"); - Object.defineProperty(ev, "port", { value: other, configurable: true }); - serialTarget.dispatchEvent(ev); - - await new Promise((r) => setTimeout(r, 50)); - expect(onReconnect).not.toHaveBeenCalled(); - mgr.stop(); - }); - - it("通过 getPorts 轮询兜底重连", async () => { - const remembered = makePort(0xabcd, 0x00ef); - const granted = makePort(0xabcd, 0x00ef); - const onReconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => true, - onDisconnect: vi.fn(), - onReconnect, - pollIntervalMs: 30, - }); - mgr.rememberPort(remembered); - serialTarget.getPorts.mockResolvedValue([granted]); - mgr.start(); - - await vi.waitFor(() => expect(onReconnect).toHaveBeenCalledWith(granted, true), { timeout: 2000 }); - mgr.stop(); - }); - }); - - describe("无 USB 身份的设备(蓝牙串口 / 虚拟 COM 口)", () => { - it("无 VID/PID 时通过端口引用匹配断开", async () => { - // getInfo 返回空对象(无 VID/PID) - const port = { getInfo: () => ({}) } as unknown as SerialPort; - const onDisconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => enabled, - onDisconnect, - onReconnect: vi.fn(), - }); - mgr.rememberPort(port); - mgr.start(); - - // 断开事件:event.port 与 rememberedPort 是同一对象引用 - const ev = new Event("disconnect"); - Object.defineProperty(ev, "port", { value: port, configurable: true }); - serialTarget.dispatchEvent(ev); - - expect(onDisconnect).toHaveBeenCalledOnce(); - mgr.stop(); - }); - - it("无 VID/PID 且 getPorts 只剩一个端口时尝试重连", async () => { - const rememberedPort = { getInfo: () => ({}) } as unknown as SerialPort; - const grantedPort = { getInfo: () => ({}) } as unknown as SerialPort; - const onReconnect = vi.fn(); - const mgr = createSerialReconnectManager({ - enabled: () => true, - onDisconnect: vi.fn(), - onReconnect, - pollIntervalMs: 30, - }); - mgr.rememberPort(rememberedPort); - serialTarget.getPorts.mockResolvedValue([grantedPort]); - mgr.start(); - - await vi.waitFor(() => expect(onReconnect).toHaveBeenCalledWith(grantedPort, true), { timeout: 2000 }); - mgr.stop(); - }); - }); - - describe("生命周期管理", () => { - it("hasRememberedPort 反映是否有记住的端口", () => { - const mgr = createSerialReconnectManager({ - enabled: () => true, - onDisconnect: vi.fn(), - onReconnect: vi.fn(), - }); - expect(mgr.hasRememberedPort()).toBe(false); - mgr.rememberPort(makePort(1, 2)); - expect(mgr.hasRememberedPort()).toBe(true); - mgr.clearRemembered(); - expect(mgr.hasRememberedPort()).toBe(false); - }); - - it("多次 start() 不会重复注册事件", () => { - const addEventListenerSpy = vi.spyOn(serialTarget, "addEventListener"); - const mgr = createSerialReconnectManager({ - enabled: () => true, - onDisconnect: vi.fn(), - onReconnect: vi.fn(), - }); - mgr.rememberPort(makePort(1, 2)); - mgr.start(); - mgr.start(); - mgr.start(); - // 应该只注册一次 connect + disconnect - expect(addEventListenerSpy).toHaveBeenCalledTimes(2); - mgr.stop(); - }); - - it("rememberPort 在 start() 后调用时设置 ondisconnect", () => { - const port = makePort(0xaaaa, 0xbbbb); - const mgr = createSerialReconnectManager({ - enabled: () => true, - onDisconnect: vi.fn(), - onReconnect: vi.fn(), - }); - // 先 start,再 rememberPort - mgr.start(); - mgr.rememberPort(port); - - // ondisconnect 应被设置 - expect((port as unknown as { ondisconnect: unknown }).ondisconnect).toBeInstanceOf(Function); - mgr.stop(); - }); - }); -}); diff --git a/kits/downloadkit/src/features/flasher/session/serialReconnectManager.ts b/kits/downloadkit/src/features/flasher/session/serialReconnectManager.ts deleted file mode 100644 index 4d9ea61..0000000 --- a/kits/downloadkit/src/features/flasher/session/serialReconnectManager.ts +++ /dev/null @@ -1,286 +0,0 @@ -/** - * WebSerial 设备的重连管理器。 - * - * 严格遵循 modbus-io-webserial 的 `createWebSerialReconnectManager` 模式: - * - 在 `navigator.serial` 级别监听 connect/disconnect 事件(不依赖 port 对象生命周期) - * - 通过 USB 身份(VID/PID)匹配确认是同一个设备 - * - 轮询 `navigator.serial.getPorts()` 作为兜底(connect 事件不可靠时) - * - 完全独立于 Transport,只负责事件监听 + 身份匹配 + 回调通知 - * - * 增强:增加 port.ondisconnect 直接回调作为第二检测层, - * 覆盖 navigator.serial 事件不可靠的场景(某些 USB 转串口适配器/浏览器不触发全局事件)。 - */ - -/** 串口端口的 USB 身份标识。 */ -export type SerialPortIdentity = { - usbVendorId?: number; - usbProductId?: number; -}; - -/** 使用全局 navigator.serial 的迷你接口(避免依赖完整 DOM 类型)。 */ -interface NavigatorSerialLike extends EventTarget { - addEventListener( - type: "connect" | "disconnect", - listener: (ev: Event) => void, - options?: boolean | AddEventListenerOptions, - ): void; - removeEventListener( - type: "connect" | "disconnect", - listener: (ev: Event) => void, - options?: boolean | EventListenerOptions, - ): void; - getPorts(): Promise; -} - -interface SerialPortLike { - getInfo?(): { usbVendorId?: number; usbProductId?: number }; -} - -function getWebSerial(): NavigatorSerialLike | undefined { - if (typeof navigator === "undefined") return undefined; - return (navigator as Navigator & { serial?: NavigatorSerialLike }).serial; -} - -function getPortIdentity(port: SerialPortLike): SerialPortIdentity { - const info = port.getInfo?.(); - if (!info) return {}; - return { - usbVendorId: typeof info.usbVendorId === "number" ? info.usbVendorId : undefined, - usbProductId: typeof info.usbProductId === "number" ? info.usbProductId : undefined, - }; -} - -function identityHasUsbIds(id: SerialPortIdentity): boolean { - return id.usbVendorId != null && id.usbProductId != null; -} - -function identitiesMatch(a: SerialPortIdentity, b: SerialPortIdentity): boolean { - if (!identityHasUsbIds(a) || !identityHasUsbIds(b)) return false; - return a.usbVendorId === b.usbVendorId && a.usbProductId === b.usbProductId; -} - -export type SerialReconnectManagerOptions = { - enabled: () => boolean; - onDisconnect: () => void; - onReconnect: (port: SerialPort, needsConfirm: boolean) => void; - /** 仅 VID/PID 匹配(非同一对象引用)时,询问用户是否重连。返回 true 表示同意。 */ - confirmReconnect?: (port: SerialPort) => Promise; - /** getPorts() 轮询间隔;connect 事件不可靠时的兜底(毫秒)。 */ - pollIntervalMs?: number; -}; - -export type SerialReconnectManager = { - rememberPort(port: SerialPort): void; - clearRemembered(): void; - start(): void; - stop(): void; - hasRememberedPort(): boolean; - /** I/O 操作失败(stream closed)时通知管理器,触发断开流程。 */ - notifyIoLinkLost(): void; -}; - -export function createSerialReconnectManager( - opts: SerialReconnectManagerOptions, -): SerialReconnectManager { - let rememberedPort: SerialPort | null = null; - let rememberedIdentity: SerialPortIdentity | null = null; - let started = false; - let reconnecting = false; - /** 护板标志:防止 navigator.serial 事件与 port.ondisconnect 同时触发导致重复通知。 */ - let disconnected = false; - let pollTimer: ReturnType | null = null; - const pollIntervalMs = opts.pollIntervalMs ?? 1000; - /** 本轮重连已成功,防止轮询重复触发。断开时重置。 */ - let reconnected = false; - - // ----- 共享的断开逻辑 ----- - - const handleDisconnect = () => { - if (!started || disconnected) return; - disconnected = true; - reconnected = false; - rememberedPort = null; - opts.onDisconnect(); - }; - - // ----- 事件处理器 ----- - - const onConnect = (ev: Event) => { - if (!started || !opts.enabled() || reconnecting) return; - // navigator.serial connect 事件通过 SerialConnectionEvent.port 传递端口 - const port = (ev as unknown as { port: SerialPort }).port; - if (port == null || !rememberedIdentity) return; - if (!portsMatch(rememberedIdentity, port, rememberedPort)) return; - void runReconnect(port); - }; - - const onDisconnect = (ev: Event) => { - if (!started || !rememberedIdentity) return; - const port = (ev as unknown as { port: SerialPort }).port; - if (port == null) return; - if (!portsMatch(rememberedIdentity, port, rememberedPort)) return; - handleDisconnect(); - }; - - /** port.ondisconnect 直接回调(不依赖 navigator.serial 事件)。 */ - const onPortDisconnect = () => { - handleDisconnect(); - }; - - async function runReconnect(port: SerialPort) { - if (reconnecting) return; - reconnecting = true; - try { - // 断开后 rememberedPort 已清空,插回的新端口永远是新对象引用。 - // 仅 VID/PID 匹配无法区分"同一设备插回"和"同型号不同设备", - // 因此始终传 needsConfirm=true,由上层决定是否需要用户确认。 - const needsConfirm = true; - - if (opts.confirmReconnect) { - const confirmed = await opts.confirmReconnect(port); - if (!confirmed) return; - } - - disconnected = false; - reconnected = true; - rememberedPort = port; - rememberedIdentity = getPortIdentity(port); - setupPortDisconnect(port); - opts.onReconnect(port, needsConfirm); - rememberedPort = null; - } finally { - reconnecting = false; - } - } - - /** 当 I/O 操作失败(stream closed)时由传输层调用。这是最可靠的断开检测路径。 */ - const onIoLinkLost = () => { - handleDisconnect(); - }; - - /** 在端口对象上设置 ondisconnect 直接回调。 */ - function setupPortDisconnect(port: SerialPort): void { - try { - (port as unknown as { ondisconnect: ((ev: Event) => void) | null }).ondisconnect = onPortDisconnect; - } catch { - // 某些环境可能不支持 ondisconnect 属性 - } - } - - /** 清除端口对象上的 ondisconnect 回调。 */ - function teardownPortDisconnect(port: SerialPort): void { - try { - (port as unknown as { ondisconnect: ((ev: Event) => void) | null }).ondisconnect = null; - } catch { - // ignore - } - } - - // ----- 身份匹配 ----- - - function portsMatch( - remembered: SerialPortIdentity, - port: SerialPortLike, - rememberedPortRef?: SerialPortLike | null, - ): boolean { - // 同一对象引用(适用于断开事件,该端口对象尚未被回收) - if (rememberedPortRef != null && rememberedPortRef === port) return true; - const other = getPortIdentity(port); - // 有 USB 身份时严格按 VID/PID 匹配 - if (identityHasUsbIds(remembered) && identityHasUsbIds(other)) { - return identitiesMatch(remembered, other); - } - // 无 USB 身份时再用引用检查一次(兜底) - if (rememberedPortRef != null && rememberedPortRef === port) return true; - return false; - } - - // ----- 轮询兜底 ----- - - async function scanGrantedPortsForReconnect() { - if (!started || !opts.enabled() || reconnecting || reconnected || !rememberedIdentity) return; - const serial = getWebSerial(); - if (!serial?.getPorts) return; - try { - const granted = await serial.getPorts(); - for (const candidate of granted) { - if (portsMatch(rememberedIdentity, candidate, rememberedPort)) { - void runReconnect(candidate as unknown as SerialPort); - return; - } - } - // 无 USB 身份且只剩一个已授权端口时,尝试用它重连 - if (!identityHasUsbIds(rememberedIdentity) && granted.length === 1) { - void runReconnect(granted[0] as unknown as SerialPort); - } - } catch { - // 忽略轮询错误 - } - } - - // ----- API ----- - - return { - rememberPort(port: SerialPort) { - rememberedPort = port; - rememberedIdentity = getPortIdentity(port); - disconnected = false; - if (started) { - setupPortDisconnect(port); - } - }, - - clearRemembered() { - rememberedPort = null; - rememberedIdentity = null; - disconnected = false; - }, - - hasRememberedPort() { - return rememberedIdentity != null; - }, - - /** I/O 操作失败(stream closed)时通知管理器:这是最可靠的断开检测路径。 */ - notifyIoLinkLost() { - onIoLinkLost(); - }, - - start() { - if (started) return; - started = true; - disconnected = false; - const serial = getWebSerial(); - if (serial?.addEventListener) { - serial.addEventListener("connect", onConnect); - serial.addEventListener("disconnect", onDisconnect); - } - // 端口级断开直接回调(即使 navigator.serial 事件不可靠也能检测) - if (rememberedPort) { - setupPortDisconnect(rememberedPort); - } - // 可能设备已经插回:启动时立即扫描一次 - void scanGrantedPortsForReconnect(); - // 轮询兜底 - pollTimer = setInterval(() => void scanGrantedPortsForReconnect(), pollIntervalMs); - }, - - stop() { - if (!started) return; - started = false; - reconnecting = false; - disconnected = false; - if (pollTimer != null) { - clearInterval(pollTimer); - pollTimer = null; - } - const serial = getWebSerial(); - if (serial?.removeEventListener) { - serial.removeEventListener("connect", onConnect); - serial.removeEventListener("disconnect", onDisconnect); - } - if (rememberedPort) { - teardownPortDisconnect(rememberedPort); - } - }, - }; -} diff --git a/kits/downloadkit/src/plugins/builtin/ch32Serial.plugin.ts b/kits/downloadkit/src/plugins/builtin/ch32Serial.plugin.ts index 0c07df7..1258f77 100644 --- a/kits/downloadkit/src/plugins/builtin/ch32Serial.plugin.ts +++ b/kits/downloadkit/src/plugins/builtin/ch32Serial.plugin.ts @@ -35,6 +35,7 @@ export const ch32SerialPlugin: FlasherPlugin = { displayName: "CH32 Serial (WCH ISP)", chipFamily: "ch32", flasherType: "serial", + connectionType: "serial", canSelectConnection: true, canFlash: true, priority: 100, diff --git a/kits/downloadkit/src/plugins/builtin/esp32Serial.plugin.ts b/kits/downloadkit/src/plugins/builtin/esp32Serial.plugin.ts index 1b792c7..4c3e68d 100644 --- a/kits/downloadkit/src/plugins/builtin/esp32Serial.plugin.ts +++ b/kits/downloadkit/src/plugins/builtin/esp32Serial.plugin.ts @@ -41,6 +41,7 @@ export const esp32SerialPlugin: FlasherPlugin = { displayName: "ESP32 Serial", chipFamily: "esp32", flasherType: "serial", + connectionType: "serial", canSelectConnection: true, canFlash: true, priority: 100, diff --git a/kits/downloadkit/src/plugins/builtin/gd32Dfu.plugin.ts b/kits/downloadkit/src/plugins/builtin/gd32Dfu.plugin.ts index 0298f40..e889e7c 100644 --- a/kits/downloadkit/src/plugins/builtin/gd32Dfu.plugin.ts +++ b/kits/downloadkit/src/plugins/builtin/gd32Dfu.plugin.ts @@ -10,6 +10,7 @@ export const gd32DfuPlugin: FlasherPlugin = { displayName: "GD32 USB DFU", chipFamily: "gd32", flasherType: "usb-dfu", + connectionType: "usb", canSelectConnection: true, canFlash: true, priority: 100, diff --git a/kits/downloadkit/src/plugins/builtin/gd32Serial.plugin.ts b/kits/downloadkit/src/plugins/builtin/gd32Serial.plugin.ts index 69cd760..14159d6 100644 --- a/kits/downloadkit/src/plugins/builtin/gd32Serial.plugin.ts +++ b/kits/downloadkit/src/plugins/builtin/gd32Serial.plugin.ts @@ -35,6 +35,7 @@ export const gd32SerialPlugin: FlasherPlugin = { displayName: "GD32 Serial", chipFamily: "gd32", flasherType: "serial", + connectionType: "serial", canSelectConnection: true, canFlash: true, priority: 100, diff --git a/kits/downloadkit/src/plugins/builtin/stm32Daplink.plugin.ts b/kits/downloadkit/src/plugins/builtin/stm32Daplink.plugin.ts index 6551bf9..1730126 100644 --- a/kits/downloadkit/src/plugins/builtin/stm32Daplink.plugin.ts +++ b/kits/downloadkit/src/plugins/builtin/stm32Daplink.plugin.ts @@ -12,6 +12,7 @@ export const stm32DaplinkPlugin: FlasherPlugin = { displayName: "STM32 DAP-Link", chipFamily: "stm32", flasherType: "dap-link", + connectionType: "usb", canSelectConnection: true, canFlash: true, priority: 100, diff --git a/kits/downloadkit/src/plugins/builtin/stm32Dfu.plugin.ts b/kits/downloadkit/src/plugins/builtin/stm32Dfu.plugin.ts index 9301fe7..9207198 100644 --- a/kits/downloadkit/src/plugins/builtin/stm32Dfu.plugin.ts +++ b/kits/downloadkit/src/plugins/builtin/stm32Dfu.plugin.ts @@ -16,6 +16,7 @@ export const stm32DfuPlugin: FlasherPlugin = { displayName: "STM32 USB DFU", chipFamily: "stm32", flasherType: "usb-dfu", + connectionType: "usb", canSelectConnection: true, canFlash: true, priority: 100, diff --git a/kits/downloadkit/src/plugins/builtin/stm32Serial.plugin.ts b/kits/downloadkit/src/plugins/builtin/stm32Serial.plugin.ts index f8efde8..e8695a3 100644 --- a/kits/downloadkit/src/plugins/builtin/stm32Serial.plugin.ts +++ b/kits/downloadkit/src/plugins/builtin/stm32Serial.plugin.ts @@ -35,6 +35,7 @@ export const stm32SerialPlugin: FlasherPlugin = { displayName: "STM32 Serial", chipFamily: "stm32", flasherType: "serial", + connectionType: "serial", canSelectConnection: true, canFlash: true, priority: 100, diff --git a/kits/downloadkit/src/plugins/builtin/stm32Stlink.plugin.ts b/kits/downloadkit/src/plugins/builtin/stm32Stlink.plugin.ts index e733d1c..592f544 100644 --- a/kits/downloadkit/src/plugins/builtin/stm32Stlink.plugin.ts +++ b/kits/downloadkit/src/plugins/builtin/stm32Stlink.plugin.ts @@ -45,6 +45,7 @@ export const stm32StlinkPlugin: FlasherPlugin = { displayName: "STM32 ST-Link", chipFamily: "stm32", flasherType: "st-link", + connectionType: "usb", canSelectConnection: true, canFlash: true, priority: 100, diff --git a/kits/downloadkit/src/plugins/types.ts b/kits/downloadkit/src/plugins/types.ts index 590f6f8..b1adfd9 100644 --- a/kits/downloadkit/src/plugins/types.ts +++ b/kits/downloadkit/src/plugins/types.ts @@ -7,6 +7,8 @@ import type { import type { StlinkTargetVariant } from "../transports/adapters/stlink.adapter"; import type { Transport } from "../transports/types"; +export type HardwareType = "serial" | "usb" | "hid"; + export type ChipFamily = "stm32" | "esp32" | "gd32" | "ch32"; export type FlasherType = "serial" | "usb-dfu" | "st-link" | "dap-link"; @@ -61,6 +63,7 @@ export interface FlasherPlugin { displayName: string; chipFamily: ChipFamily; flasherType: FlasherType; + connectionType: HardwareType; canSelectConnection: boolean; canFlash: boolean; priority: number; diff --git a/kits/downloadkit/src/transports/DeviceIdentityStore.spec.ts b/kits/downloadkit/src/transports/DeviceIdentityStore.spec.ts new file mode 100644 index 0000000..e864cd8 --- /dev/null +++ b/kits/downloadkit/src/transports/DeviceIdentityStore.spec.ts @@ -0,0 +1,47 @@ +import 'fake-indexeddb/auto'; +import { describe, expect, it, beforeEach, afterEach } from 'vitest'; +import { DeviceIdentityStore } from './DeviceIdentityStore'; +import type { PersistedHardwareIdentity } from './DeviceIdentityStore'; + +describe('DeviceIdentityStore', () => { + let store: DeviceIdentityStore; + + beforeEach(() => { + store = new DeviceIdentityStore(); + }); + + afterEach(async () => { + await store.clear(); + }); + + it('初始时加载返回 null', async () => { + const result = await store.load(); + expect(result).toBeNull(); + }); + + it('保存后加载返回相同值', async () => { + const identity: PersistedHardwareIdentity = { + type: 'serial', + usbVendorId: 0x1a86, + usbProductId: 0x7523, + lastConfig: { baudRate: 115200 }, + }; + await store.save(identity); + const loaded = await store.load(); + expect(loaded).toEqual(identity); + }); + + it('覆盖保存后加载返回新值', async () => { + await store.save({ type: 'serial', usbVendorId: 0xaaaa, usbProductId: 0xbbbb }); + await store.save({ type: 'usb', usbVendorId: 0xcccc, usbProductId: 0xdddd }); + const loaded = await store.load(); + expect(loaded?.type).toBe('usb'); + }); + + it('clear 后加载返回 null', async () => { + await store.save({ type: 'serial' }); + await store.clear(); + const result = await store.load(); + expect(result).toBeNull(); + }); +}); diff --git a/kits/downloadkit/src/transports/DeviceIdentityStore.ts b/kits/downloadkit/src/transports/DeviceIdentityStore.ts new file mode 100644 index 0000000..10933f2 --- /dev/null +++ b/kits/downloadkit/src/transports/DeviceIdentityStore.ts @@ -0,0 +1,44 @@ +import { openDB } from 'idb'; + +const DB = 'hardware-session-db'; +const STORE = 'device'; +const KEY = 'current-device'; +const SCHEMA_VERSION = 1; + +export interface PersistedHardwareIdentity { + type: 'serial' | 'usb' | 'hid'; + usbVendorId?: number; + usbProductId?: number; + manufacturerName?: string; + productName?: string; + serialNumber?: string; + lastConfig?: Record; +} + +export class DeviceIdentityStore { + private async getDb() { + return openDB(DB, SCHEMA_VERSION, { + upgrade(db) { + if (!db.objectStoreNames.contains(STORE)) { + db.createObjectStore(STORE); + } + }, + }); + } + + async load(): Promise { + const db = await this.getDb(); + const result = await db.get(STORE, KEY); + return (result as PersistedHardwareIdentity) ?? null; + } + + async save(identity: PersistedHardwareIdentity): Promise { + const db = await this.getDb(); + await db.put(STORE, identity, KEY); + } + + async clear(): Promise { + const db = await this.getDb(); + await db.delete(STORE, KEY); + } +} diff --git a/kits/downloadkit/src/transports/FlasherSession.ts b/kits/downloadkit/src/transports/FlasherSession.ts new file mode 100644 index 0000000..1563c4a --- /dev/null +++ b/kits/downloadkit/src/transports/FlasherSession.ts @@ -0,0 +1,331 @@ +import { DeviceIdentityStore, type PersistedHardwareIdentity } from './DeviceIdentityStore'; +import type { HardwareIdentity, HardwareType, SessionStatus } from './FlasherSession.types'; +import type { DeviceSelector } from './selectors/DeviceSelector'; +import type { Transport } from './types'; +import { SerialSelector } from './selectors/SerialSelector'; +import { UsbSelector } from './selectors/UsbSelector'; +import { HidSelector } from './selectors/HidSelector'; +import { WebSerialTransport } from './serial/WebSerialTransport'; +import { WebUsbTransport } from './usb/WebUsbTransport'; +import { WebHidTransport } from './hid/WebHidTransport'; + +export interface FlasherSessionDeps { + store?: DeviceIdentityStore; + createSelector?: (type: HardwareType) => DeviceSelector; + createTransport?: ( + type: HardwareType, + device?: unknown, + config?: Record, + ) => Transport; +} + +export class FlasherSession { + private static instance: FlasherSession | null = null; + + private _status: SessionStatus = 'idle'; + private _transport: Transport | null = null; + private _currentIdentity: HardwareIdentity | null = null; + private _disconnectCallback: (() => void) | null = null; + private _disconnectBound: (() => void) | null = null; + private _reconnectCallback: (() => void) | null = null; + private _reconnectController: AbortController | null = null; + + private readonly store: DeviceIdentityStore; + private readonly createSelectorFn: (type: HardwareType) => DeviceSelector; + private readonly createTransportFn: ( + type: HardwareType, + device?: unknown, + config?: Record, + ) => Transport; + + private constructor(deps?: FlasherSessionDeps) { + this.store = deps?.store ?? new DeviceIdentityStore(); + this.createSelectorFn = deps?.createSelector ?? this.defaultCreateSelector; + this.createTransportFn = deps?.createTransport ?? this.defaultCreateTransport; + } + + static getInstance(deps?: FlasherSessionDeps): FlasherSession { + if (!FlasherSession.instance) { + FlasherSession.instance = new FlasherSession(deps); + } + return FlasherSession.instance; + } + + static resetInstance(): void { + FlasherSession.instance = null; + } + + getStatus(): SessionStatus { + return this._status; + } + + getTransport(): Transport | null { + return this._transport; + } + + getDeviceIdentity(): HardwareIdentity | null { + return this._currentIdentity; + } + + onDisconnect(cb: (() => void) | null): void { + this._disconnectCallback = cb; + } + + onReconnect(cb: (() => void) | null): void { + this._reconnectCallback = cb; + } + + async acquire(type: HardwareType, identity?: PersistedHardwareIdentity): Promise { + if (this._transport) { + throw new Error('Hardware session is already active. Call release() first.'); + } + + this._status = 'selecting'; + + try { + const selector = this.createSelectorFn(type); + const device = identity + ? (await this.tryMatchGranted(selector, identity)) ?? (await selector.request()) + : await selector.request(); + + const transport = this.createTransportFn(type, device, identity?.lastConfig); + const hardwareIdentity = selector.getIdentity(device); + + this._disconnectBound = () => { + this._status = 'disconnected'; + this._disconnectCallback?.(); + }; + selector.watchDisconnect(device, this._disconnectBound); + + await transport.open(); + + this._transport = transport; + this._currentIdentity = hardwareIdentity; + this._status = 'ready'; + + await this.store.save({ + ...hardwareIdentity, + lastConfig: identity?.lastConfig, + }); + + this.startAutoReconnect(); + + return transport; + } catch (e) { + this._status = 'idle'; + throw e; + } + } + + async release(): Promise { + this.stopAutoReconnect(); + if (this._transport && this._currentIdentity) { + const selector = this.createSelectorFn(this._currentIdentity.type); + const device = this.extractDevice(this._transport, this._currentIdentity.type); + if (device && this._disconnectBound) { + selector.unwatchDisconnect(device, this._disconnectBound); + } + } + + this._disconnectBound = null; + + if (this._transport) { + await this._transport.close().catch(() => undefined); + } + + this._transport = null; + this._currentIdentity = null; + this._status = 'idle'; + } + + async reopen(config: Record): Promise { + if (!this._transport || !this._currentIdentity) { + throw new Error('No active session to reopen'); + } + + const identity = this._currentIdentity; + const transport = this._transport; + const type = identity.type; + const device = this.extractDevice(transport, type); + + await transport.close().catch(() => undefined); + + const newTransport = this.createTransportFn(type, device, config); + + await newTransport.open(); + + this._transport = newTransport; + this._currentIdentity = { ...identity }; + + await this.store.save({ ...identity, lastConfig: config }); + } + + async clearIdentity(): Promise { + await this.store.clear(); + } + + /** Start listening for browser connect events to auto-reconnect after a disconnect. */ + startAutoReconnect(): void { + this.stopAutoReconnect(); + + const identity = this._currentIdentity; + if (!identity) return; + + const controller = new AbortController(); + this._reconnectController = controller; + const signal = controller.signal; + + switch (identity.type) { + case 'serial': { + const nav = navigator as Navigator & { serial?: { addEventListener: Function } }; + if (!nav.serial?.addEventListener) break; + nav.serial.addEventListener( + 'connect', + async (e: Event) => { + const port = (e as unknown as { port: SerialPort }).port; + const info = port.getInfo?.(); + if (!info) return; + if (this._status !== 'disconnected') return; + if ( + identity.usbVendorId != null && + identity.usbProductId != null && + info.usbVendorId === identity.usbVendorId && + info.usbProductId === identity.usbProductId + ) { + const restored = await this.tryRestore(); + if (restored) this._reconnectCallback?.(); + } + }, + { signal }, + ); + break; + } + case 'usb': { + const nav = navigator as Navigator & { usb?: USB }; + if (!nav.usb?.addEventListener) break; + nav.usb.addEventListener( + 'connect', + async (e: Event) => { + const device = (e as USBConnectionEvent).device; + if (this._status !== 'disconnected') return; + if ( + identity.usbVendorId != null && + identity.usbProductId != null && + device.vendorId === identity.usbVendorId && + device.productId === identity.usbProductId + ) { + const restored = await this.tryRestore(); + if (restored) this._reconnectCallback?.(); + } + }, + { signal }, + ); + break; + } + // hid: navigator.hid has no connect/disconnect events + } + } + + stopAutoReconnect(): void { + this._reconnectController?.abort(); + this._reconnectController = null; + } + + /** Silently restore device connection from stored identity. No user prompt. */ + async tryRestore(): Promise { + if (this._transport) return false; + + const identity = await this.store.load(); + if (!identity) return false; + + this._status = 'selecting'; + try { + const selector = this.createSelectorFn(identity.type); + const device = await this.tryMatchGranted(selector, identity); + if (!device) { + this._status = 'idle'; + return false; + } + + const transport = this.createTransportFn(identity.type, device, identity.lastConfig); + const hardwareIdentity = selector.getIdentity(device); + + this._disconnectBound = () => { + this._status = 'disconnected'; + this._disconnectCallback?.(); + }; + selector.watchDisconnect(device, this._disconnectBound); + await transport.open(); + + this._transport = transport; + this._currentIdentity = hardwareIdentity; + this._status = 'ready'; + + await this.store.save({ ...hardwareIdentity, lastConfig: identity.lastConfig }); + this.startAutoReconnect(); + return true; + } catch { + this._status = 'idle'; + return false; + } + } + + // --- Default implementations (real browser API) --- + + private defaultCreateSelector(type: HardwareType): DeviceSelector { + switch (type) { + case 'serial': + return new SerialSelector(); + case 'usb': + return new UsbSelector(); + case 'hid': + return new HidSelector(); + } + } + + private defaultCreateTransport( + type: HardwareType, + device?: unknown, + config?: Record, + ): Transport { + switch (type) { + case 'serial': + return new WebSerialTransport(device as SerialPort, (config?.baudRate as number) ?? 115200); + case 'usb': + return new WebUsbTransport(device as USBDevice); + case 'hid': + return new WebHidTransport(device as HIDDevice); + } + } + + // --- Internal helpers --- + + private async tryMatchGranted( + selector: DeviceSelector, + identity: PersistedHardwareIdentity, + ): Promise { + const granted = await selector.getGranted(); + return ( + granted.find((d: unknown) => { + const id = selector.getIdentity(d); + return ( + identity.usbVendorId != null && + id.usbVendorId === identity.usbVendorId && + identity.usbProductId != null && + id.usbProductId === identity.usbProductId + ); + }) ?? null + ); + } + + private extractDevice(transport: Transport, type: HardwareType): unknown { + switch (type) { + case 'serial': + return (transport as WebSerialTransport).port; + case 'usb': + return (transport as WebUsbTransport).device; + case 'hid': + return (transport as WebHidTransport).device; + } + } +} diff --git a/kits/downloadkit/src/transports/FlasherSession.types.ts b/kits/downloadkit/src/transports/FlasherSession.types.ts new file mode 100644 index 0000000..3db5fca --- /dev/null +++ b/kits/downloadkit/src/transports/FlasherSession.types.ts @@ -0,0 +1,12 @@ +export type HardwareType = "serial" | "usb" | "hid"; + +export type SessionStatus = "idle" | "selecting" | "ready" | "disconnected"; + +export interface HardwareIdentity { + type: HardwareType; + usbVendorId?: number; + usbProductId?: number; + manufacturerName?: string; + productName?: string; + serialNumber?: string; +} diff --git a/kits/downloadkit/src/transports/__tests__/FlasherSession.spec.ts b/kits/downloadkit/src/transports/__tests__/FlasherSession.spec.ts new file mode 100644 index 0000000..0e35362 --- /dev/null +++ b/kits/downloadkit/src/transports/__tests__/FlasherSession.spec.ts @@ -0,0 +1,273 @@ +import 'fake-indexeddb/auto'; +import { describe, expect, it, beforeEach, vi, type Mock } from 'vitest'; +import { FlasherSession } from '../FlasherSession'; +import type { HardwareType, HardwareIdentity } from '../FlasherSession.types'; +import type { DeviceSelector } from '../selectors/DeviceSelector'; +import type { Transport } from '../types'; +import { DeviceIdentityStore } from '../DeviceIdentityStore'; + +function makeMockTransport(device?: unknown): Transport { + let mockPort = device ?? null; + return { + name: 'mock-transport', + get port() { + return mockPort; + }, + open: vi.fn().mockResolvedValue(undefined), + close: vi.fn().mockResolvedValue(undefined), + write: vi.fn(), + read: vi.fn(), + } as unknown as Transport; +} + +function makeMockSelector(): DeviceSelector { + return { + type: 'serial' as HardwareType, + request: vi.fn().mockRejectedValue(new Error('no default device')), + getGranted: vi.fn().mockResolvedValue([]), + getIdentity: vi.fn((_d) => ({ type: 'serial' })), + watchDisconnect: vi.fn(), + unwatchDisconnect: vi.fn(), + }; +} + +describe('FlasherSession', () => { + let mockSelector: DeviceSelector; + let mockDevice: object; + let transports: Transport[]; + let lastConfig: Record | undefined; + + function createSession() { + transports = []; + lastConfig = undefined; + mockSelector = makeMockSelector(); + mockDevice = { id: 'device-1' }; + (mockSelector.request as Mock).mockResolvedValue(mockDevice); + + return FlasherSession.getInstance({ + createSelector: () => mockSelector, + createTransport: (_type, device, config) => { + lastConfig = config; + const t = makeMockTransport(device); + transports.push(t); + return t; + }, + }); + } + + beforeEach(() => { + FlasherSession.resetInstance(); + }); + + it('初始状态为 idle', () => { + const session = createSession(); + expect(session.getStatus()).toBe('idle'); + }); + + it('acquire 后状态为 ready', async () => { + const session = createSession(); + const transport = await session.acquire('serial'); + + expect(session.getStatus()).toBe('ready'); + expect(transport).toBe(transports[0]); + expect(transports[0].open).toHaveBeenCalledOnce(); + }); + + it('acquire 调用 watchDisconnect', async () => { + const session = createSession(); + await session.acquire('serial'); + + expect(mockSelector.watchDisconnect).toHaveBeenCalledWith(mockDevice, expect.any(Function)); + }); + + it('acquire 失败时回到 idle', async () => { + const session = createSession(); + (mockSelector.request as Mock).mockRejectedValue(new Error('canceled')); + + await expect(session.acquire('serial')).rejects.toThrow('canceled'); + expect(session.getStatus()).toBe('idle'); + }); + + it('重复 acquire 抛异常', async () => { + const session = createSession(); + await session.acquire('serial'); + await expect(session.acquire('serial')).rejects.toThrow('already active'); + }); + + it('release 后回到 idle', async () => { + const session = createSession(); + await session.acquire('serial'); + await session.release(); + + expect(session.getStatus()).toBe('idle'); + expect(transports[0].close).toHaveBeenCalledOnce(); + }); + + it('release 调用 unwatchDisconnect', async () => { + const session = createSession(); + await session.acquire('serial'); + await session.release(); + + expect(mockSelector.unwatchDisconnect).toHaveBeenCalledWith(mockDevice, expect.any(Function)); + }); + + it('reopen 用新配置重建传输', async () => { + const session = createSession(); + await session.acquire('serial'); + + await session.reopen({ baudRate: 9600 }); + + expect(lastConfig).toEqual({ baudRate: 9600 }); + expect(transports).toHaveLength(2); + expect(transports[0].close).toHaveBeenCalledOnce(); + expect(transports[1].open).toHaveBeenCalledOnce(); + expect(session.getStatus()).toBe('ready'); + }); + + it('reopen 时没有活跃会话抛异常', async () => { + const session = createSession(); + await expect(session.reopen({ baudRate: 9600 })).rejects.toThrow('No active session'); + }); + + it('断开回调触发状态变化', async () => { + const session = createSession(); + + let disconnectHandler: (() => void) | undefined; + (mockSelector.watchDisconnect as Mock).mockImplementation((_d, cb) => { + disconnectHandler = cb; + }); + + const onDisconnect = vi.fn(); + session.onDisconnect(onDisconnect); + await session.acquire('serial'); + + expect(session.getStatus()).toBe('ready'); + + disconnectHandler!(); + expect(session.getStatus()).toBe('disconnected'); + expect(onDisconnect).toHaveBeenCalledOnce(); + }); + + it('带 identity 时优先匹配已授权设备', async () => { + const session = createSession(); + (mockSelector.getIdentity as Mock).mockImplementation((d) => ({ + type: 'serial', + usbVendorId: d.usbVendorId, + usbProductId: d.usbProductId, + })); + (mockSelector.getGranted as Mock).mockResolvedValue([ + { usbVendorId: 0x1234, usbProductId: 0x5678 }, + { usbVendorId: 0xaaaa, usbProductId: 0xbbbb }, + ]); + + await session.acquire('serial', { + type: 'serial', + usbVendorId: 0x1234, + usbProductId: 0x5678, + }); + + expect(mockSelector.request).not.toHaveBeenCalled(); + }); + + it('带 identity 但无匹配时 fallback 到 request', async () => { + const session = createSession(); + (mockSelector.getGranted as Mock).mockResolvedValue([ + { usbVendorId: 0xaaaa, usbProductId: 0xbbbb }, + ]); + + await session.acquire('serial', { + type: 'serial', + usbVendorId: 0x1234, + usbProductId: 0x5678, + }); + + expect(mockSelector.request).toHaveBeenCalledOnce(); + }); + + it('clearIdentity 清空持久化记录', async () => { + const store = new DeviceIdentityStore(); + await store.save({ type: 'serial', usbVendorId: 1, usbProductId: 2 }); + expect(await store.load()).not.toBeNull(); + + const session = FlasherSession.getInstance({ store }); + await session.clearIdentity(); + expect(await store.load()).toBeNull(); + }); + + it('getInstance 返回同一个实例', () => { + const a = FlasherSession.getInstance(); + const b = FlasherSession.getInstance(); + expect(a).toBe(b); + }); + + describe('tryRestore', () => { + it('返回 false 当无存储的 identity', async () => { + const store = new DeviceIdentityStore(); + const session = FlasherSession.getInstance({ store, createSelector: () => makeMockSelector() }); + const result = await session.tryRestore(); + expect(result).toBe(false); + expect(session.getStatus()).toBe('idle'); + }); + + it('返回 false 当无匹配的已授权设备', async () => { + const mockSelector = makeMockSelector(); + (mockSelector.getGranted as Mock).mockResolvedValue([]); + + const store = new DeviceIdentityStore(); + await store.save({ type: 'serial', usbVendorId: 0x1234, usbProductId: 0x5678 }); + + const session = FlasherSession.getInstance({ + store, + createSelector: () => mockSelector, + createTransport: (_t, _d, _c) => makeMockTransport(), + }); + const result = await session.tryRestore(); + expect(result).toBe(false); + expect(session.getStatus()).toBe('idle'); + }); + + it('返回 true 当匹配到已授权设备并建立连接', async () => { + const mockDevice = { id: 'device-1', usbVendorId: 0x1234, usbProductId: 0x5678 }; + const mockSelector = makeMockSelector(); + (mockSelector.getGranted as Mock).mockResolvedValue([mockDevice]); + (mockSelector.getIdentity as Mock).mockImplementation((d) => ({ + type: 'serial', + usbVendorId: d.usbVendorId, + usbProductId: d.usbProductId, + })); + + const store = new DeviceIdentityStore(); + await store.save({ type: 'serial', usbVendorId: 0x1234, usbProductId: 0x5678 }); + + const session = FlasherSession.getInstance({ + store, + createSelector: () => mockSelector, + createTransport: (_t, _d, _c) => makeMockTransport(), + }); + const result = await session.tryRestore(); + expect(result).toBe(true); + expect(session.getStatus()).toBe('ready'); + expect(session.getTransport()).not.toBeNull(); + }); + + it('返回 false 当会话已激活', async () => { + const mockDevice = { id: 'device-1', usbVendorId: 0x1234, usbProductId: 0x5678 }; + const mockSelector = makeMockSelector(); + (mockSelector.request as Mock).mockResolvedValue(mockDevice); + + const store = new DeviceIdentityStore(); + await store.save({ type: 'serial', usbVendorId: 0x1234, usbProductId: 0x5678 }); + + const session = FlasherSession.getInstance({ + store, + createSelector: () => mockSelector, + createTransport: (_t, _d, _c) => makeMockTransport(), + }); + await session.acquire('serial'); + expect(session.getStatus()).toBe('ready'); + + const result = await session.tryRestore(); + expect(result).toBe(false); + }); + }); +}); diff --git a/kits/downloadkit/src/transports/hid/WebHidTransport.ts b/kits/downloadkit/src/transports/hid/WebHidTransport.ts index 66b9235..4564c0b 100644 --- a/kits/downloadkit/src/transports/hid/WebHidTransport.ts +++ b/kits/downloadkit/src/transports/hid/WebHidTransport.ts @@ -1,90 +1,24 @@ -import type { Transport } from "../types"; +import type { Transport } from '../types'; export class WebHidTransport implements Transport { - readonly name = "web-hid"; - private _device: HIDDevice | null = null; + readonly name = 'web-hid'; + private _device: HIDDevice; - private _disconnectCallback: (() => void) | null = null; - private _reconnectCallback: (() => void) | null = null; - - constructor(private readonly filters: HIDDeviceFilter[] = []) {} - - /** 获取底层 HIDDevice 引用(供 ReconnectManager 使用)。 */ - get device(): HIDDevice | null { - return this._device; - } - - onDisconnect(cb: () => void): void { - this._disconnectCallback = cb; - } - - onReconnect(cb: () => void): void { - this._reconnectCallback = cb; - } - - removeEventListeners(): void { - this._disconnectCallback = null; - this._reconnectCallback = null; - } - - /** 替换底层设备引用,供 ReconnectManager 在设备重连后调用。 */ - replaceDevice(newDevice: HIDDevice): void { - this._device = newDevice; - } - - /** 触发断开回调,供 ReconnectManager 调用。 */ - notifyDisconnect(): void { - this._disconnectCallback?.(); - } - - /** 触发重连回调,供 ReconnectManager 调用。 */ - notifyReconnect(): void { - this._reconnectCallback?.(); - } - - async selectDevice(): Promise { - if (!("hid" in navigator)) throw new Error("WebHID is not supported"); - const hidApi = navigator.hid as HID; - const selected = await hidApi.requestDevice({ filters: this.filters }); - this._device = selected[0] ?? null; - } - - isDeviceReady(): boolean { - return Boolean(this._device); - } - - getDeviceLabel(): string | null { - if (!this._device) return null; - return this._device.productName ?? "HID device"; + constructor(device: HIDDevice) { + this._device = device; } - getDeviceDetails(): string[] { - if (!this._device) return []; - const details: string[] = []; - details.push(`VID: 0x${this._device.vendorId.toString(16).padStart(4, "0").toUpperCase()}`); - details.push(`PID: 0x${this._device.productId.toString(16).padStart(4, "0").toUpperCase()}`); - if (this._device.productName) details.push(`PRODUCT: ${this._device.productName}`); - if (this._device.collections?.length) details.push(`COLLECTIONS: ${this._device.collections.length}`); - return details; + get device(): HIDDevice { + return this._device; } async open(): Promise { - if (!this._device) { - await this.selectDevice(); - } - if (!this._device) throw new Error("No HID device selected"); if (this._device.opened) return; await this._device.open(); } - async releaseSession(): Promise { - // Keep selected HID device for next download round. - } - async close(): Promise { - this.removeEventListeners(); - await this._device?.close().catch(() => undefined); - this._device = null; + await this._device.close().catch(() => undefined); } async write(_data: Uint8Array): Promise { diff --git a/kits/downloadkit/src/transports/selectors/DeviceSelector.ts b/kits/downloadkit/src/transports/selectors/DeviceSelector.ts new file mode 100644 index 0000000..f5e00c9 --- /dev/null +++ b/kits/downloadkit/src/transports/selectors/DeviceSelector.ts @@ -0,0 +1,10 @@ +import type { HardwareIdentity, HardwareType } from '../FlasherSession.types'; + +export interface DeviceSelector { + readonly type: HardwareType; + request(filters?: unknown): Promise; + getGranted(): Promise; + getIdentity(device: T): HardwareIdentity; + watchDisconnect(device: T, callback: () => void): void; + unwatchDisconnect(device: T): void; +} diff --git a/kits/downloadkit/src/transports/selectors/HidSelector.ts b/kits/downloadkit/src/transports/selectors/HidSelector.ts new file mode 100644 index 0000000..1503406 --- /dev/null +++ b/kits/downloadkit/src/transports/selectors/HidSelector.ts @@ -0,0 +1,57 @@ +import type { DeviceSelector } from './DeviceSelector'; +import type { HardwareIdentity, HardwareType } from '../FlasherSession.types'; + +function getNavigatorHid(): HID | undefined { + if (typeof navigator === 'undefined') return undefined; + return (navigator as Navigator & { hid?: HID }).hid; +} + +export class HidSelector implements DeviceSelector { + readonly type: HardwareType = 'hid'; + + async request(filters?: HIDDeviceFilter[]): Promise { + const hid = getNavigatorHid(); + if (!hid) throw new Error('Web HID is not supported'); + const devices = await hid.requestDevice({ filters: filters ?? [] }); + const device = devices[0]; + if (!device) throw new Error('No HID device selected'); + return device; + } + + async getGranted(): Promise { + const hid = getNavigatorHid(); + if (!hid?.getDevices) return []; + return hid.getDevices(); + } + + getIdentity(device: HIDDevice): HardwareIdentity { + return { + type: 'hid', + usbVendorId: device.vendorId, + usbProductId: device.productId, + productName: device.productName ?? undefined, + }; + } + + private disconnectHandlers = new WeakMap void>(); + + watchDisconnect(device: HIDDevice, callback: () => void): void { + const hid = getNavigatorHid(); + if (!hid) return; + const handler = (e: HIDConnectionEvent) => { + if (e.device === device) callback(); + }; + hid.addEventListener('disconnect', handler); + this.disconnectHandlers.set(device, handler); + } + + unwatchDisconnect(device: HIDDevice): void { + const hid = getNavigatorHid(); + if (!hid) return; + const handler = this.disconnectHandlers.get(device); + if (handler) { + hid.removeEventListener('disconnect', handler); + this.disconnectHandlers.delete(device); + } + } +} diff --git a/kits/downloadkit/src/transports/selectors/SerialSelector.ts b/kits/downloadkit/src/transports/selectors/SerialSelector.ts new file mode 100644 index 0000000..66c71c4 --- /dev/null +++ b/kits/downloadkit/src/transports/selectors/SerialSelector.ts @@ -0,0 +1,49 @@ +import type { DeviceSelector } from './DeviceSelector'; +import type { HardwareIdentity, HardwareType } from '../FlasherSession.types'; + +function getNavigatorSerial(): Serial | undefined { + if (typeof navigator === 'undefined') return undefined; + return (navigator as Navigator & { serial?: Serial }).serial; +} + +export class SerialSelector implements DeviceSelector { + readonly type: HardwareType = 'serial'; + + async request(): Promise { + const serial = getNavigatorSerial(); + if (!serial) throw new Error('Web Serial is not supported'); + return serial.requestPort(); + } + + async getGranted(): Promise { + const serial = getNavigatorSerial(); + if (!serial?.getPorts) return []; + return serial.getPorts(); + } + + getIdentity(port: SerialPort): HardwareIdentity { + const info = port.getInfo?.(); + if (!info) return { type: 'serial' }; + return { + type: 'serial', + usbVendorId: typeof info.usbVendorId === 'number' ? info.usbVendorId : undefined, + usbProductId: typeof info.usbProductId === 'number' ? info.usbProductId : undefined, + }; + } + + watchDisconnect(port: SerialPort, callback: () => void): void { + try { + (port as unknown as { ondisconnect: (() => void) | null }).ondisconnect = callback; + } catch { + // 某些浏览器不支持 ondisconnect 属性 + } + } + + unwatchDisconnect(port: SerialPort): void { + try { + (port as unknown as { ondisconnect: (() => void) | null }).ondisconnect = null; + } catch { + // ignore + } + } +} diff --git a/kits/downloadkit/src/transports/selectors/UsbSelector.ts b/kits/downloadkit/src/transports/selectors/UsbSelector.ts new file mode 100644 index 0000000..d23028e --- /dev/null +++ b/kits/downloadkit/src/transports/selectors/UsbSelector.ts @@ -0,0 +1,56 @@ +import type { DeviceSelector } from './DeviceSelector'; +import type { HardwareIdentity, HardwareType } from '../FlasherSession.types'; + +function getNavigatorUsb(): USB | undefined { + if (typeof navigator === 'undefined') return undefined; + return (navigator as Navigator & { usb?: USB }).usb; +} + +export class UsbSelector implements DeviceSelector { + readonly type: HardwareType = 'usb'; + + async request(filters?: USBDeviceFilter[]): Promise { + const usb = getNavigatorUsb(); + if (!usb) throw new Error('Web USB is not supported'); + return usb.requestDevice({ filters: filters ?? [] }); + } + + async getGranted(): Promise { + const usb = getNavigatorUsb(); + if (!usb?.getDevices) return []; + return usb.getDevices(); + } + + getIdentity(device: USBDevice): HardwareIdentity { + return { + type: 'usb', + usbVendorId: device.vendorId, + usbProductId: device.productId, + manufacturerName: device.manufacturerName ?? undefined, + productName: device.productName ?? undefined, + serialNumber: device.serialNumber ?? undefined, + }; + } + + private disconnectHandlers = new WeakMap void>(); + + watchDisconnect(device: USBDevice, callback: () => void): void { + const usb = getNavigatorUsb(); + if (!usb) return; + const handler = (e: USBConnectionEvent) => { + if (e.device === device) callback(); + }; + usb.addEventListener('disconnect', handler); + this.disconnectHandlers.set(device, handler); + } + + unwatchDisconnect(device: USBDevice): void { + const usb = getNavigatorUsb(); + if (!usb) return; + const handler = this.disconnectHandlers.get(device); + if (handler) { + usb.removeEventListener('disconnect', handler); + this.disconnectHandlers.delete(device); + } + } +} diff --git a/kits/downloadkit/src/transports/selectors/__tests__/HidSelector.spec.ts b/kits/downloadkit/src/transports/selectors/__tests__/HidSelector.spec.ts new file mode 100644 index 0000000..cba4ffb --- /dev/null +++ b/kits/downloadkit/src/transports/selectors/__tests__/HidSelector.spec.ts @@ -0,0 +1,24 @@ +import { describe, expect, it } from 'vitest'; +import { HidSelector } from '../HidSelector'; + +describe('HidSelector', () => { + const selector = new HidSelector(); + + it('type 返回 hid', () => { + expect(selector.type).toBe('hid'); + }); + + it('getIdentity 提取 VID/PID', () => { + const device = { vendorId: 0xcafe, productId: 0xbabe } as HIDDevice; + const id = selector.getIdentity(device); + expect(id.type).toBe('hid'); + expect(id.usbVendorId).toBe(0xcafe); + expect(id.usbProductId).toBe(0xbabe); + }); + + it('watchDisconnect 和 unwatchDisconnect 不抛异常', () => { + const device = {} as HIDDevice; + expect(() => selector.watchDisconnect(device, () => {})).not.toThrow(); + expect(() => selector.unwatchDisconnect(device)).not.toThrow(); + }); +}); diff --git a/kits/downloadkit/src/transports/selectors/__tests__/SerialSelector.spec.ts b/kits/downloadkit/src/transports/selectors/__tests__/SerialSelector.spec.ts new file mode 100644 index 0000000..511cd4b --- /dev/null +++ b/kits/downloadkit/src/transports/selectors/__tests__/SerialSelector.spec.ts @@ -0,0 +1,55 @@ +import { describe, expect, it, vi, beforeEach } from 'vitest'; +import { SerialSelector } from '../SerialSelector'; + +function makeMockSerialPort(vid?: number, pid?: number): SerialPort { + return { + getInfo: () => ({ usbVendorId: vid, usbProductId: pid }), + open: vi.fn(), + close: vi.fn(), + } as unknown as SerialPort; +} + +describe('SerialSelector', () => { + let selector: SerialSelector; + + beforeEach(() => { + selector = new SerialSelector(); + }); + + it('type 返回 serial', () => { + expect(selector.type).toBe('serial'); + }); + + it('getIdentity 提取 VID/PID', () => { + const port = makeMockSerialPort(0x1a86, 0x7523); + const id = selector.getIdentity(port); + expect(id.type).toBe('serial'); + expect(id.usbVendorId).toBe(0x1a86); + expect(id.usbProductId).toBe(0x7523); + }); + + it('getIdentity 无信息时返回空', () => { + const port = makeMockSerialPort(); + const id = selector.getIdentity(port); + expect(id).toEqual({ type: 'serial' }); + }); + + it('watchDisconnect 设置 ondisconnect', () => { + const port = makeMockSerialPort(1, 2); + const cb = vi.fn(); + selector.watchDisconnect(port, cb); + const handler = (port as unknown as { ondisconnect: (() => void) | null }).ondisconnect; + expect(handler).toBeInstanceOf(Function); + handler!(); + expect(cb).toHaveBeenCalledOnce(); + }); + + it('unwatchDisconnect 清除 ondisconnect', () => { + const port = makeMockSerialPort(1, 2); + const cb = vi.fn(); + selector.watchDisconnect(port, cb); + selector.unwatchDisconnect(port); + const handler = (port as unknown as { ondisconnect: (() => void) | null }).ondisconnect; + expect(handler).toBeNull(); + }); +}); diff --git a/kits/downloadkit/src/transports/selectors/__tests__/UsbSelector.spec.ts b/kits/downloadkit/src/transports/selectors/__tests__/UsbSelector.spec.ts new file mode 100644 index 0000000..dbf5625 --- /dev/null +++ b/kits/downloadkit/src/transports/selectors/__tests__/UsbSelector.spec.ts @@ -0,0 +1,24 @@ +import { describe, expect, it } from 'vitest'; +import { UsbSelector } from '../UsbSelector'; + +describe('UsbSelector', () => { + const selector = new UsbSelector(); + + it('type 返回 usb', () => { + expect(selector.type).toBe('usb'); + }); + + it('getIdentity 提取 VID/PID', () => { + const device = { vendorId: 0x0483, productId: 0x5740 } as USBDevice; + const id = selector.getIdentity(device); + expect(id.type).toBe('usb'); + expect(id.usbVendorId).toBe(0x0483); + expect(id.usbProductId).toBe(0x5740); + }); + + it('watchDisconnect 和 unwatchDisconnect 不抛异常', () => { + const device = {} as USBDevice; + expect(() => selector.watchDisconnect(device, () => {})).not.toThrow(); + expect(() => selector.unwatchDisconnect(device)).not.toThrow(); + }); +}); diff --git a/kits/downloadkit/src/transports/serial/WebSerialTransport.ts b/kits/downloadkit/src/transports/serial/WebSerialTransport.ts index 231892f..46d0acc 100644 --- a/kits/downloadkit/src/transports/serial/WebSerialTransport.ts +++ b/kits/downloadkit/src/transports/serial/WebSerialTransport.ts @@ -1,176 +1,59 @@ -import type { SerialSignals, SerialTransport } from "../types"; +import type { SerialSignals, SerialTransport } from '../types'; export class WebSerialTransport implements SerialTransport { - readonly name = "web-serial"; - private _port: SerialPort | null = null; - // Do not hold reader/writer locks here. - // Protocol implementations (e.g. UARTISP) may need to lock the stream too. - private reader: ReadableStreamDefaultReader | null = null; - private writer: WritableStreamDefaultWriter | null = null; + readonly name = 'web-serial'; + private _port: SerialPort; - private _disconnectCallback: (() => void) | null = null; - private _reconnectCallback: (() => void) | null = null; - /** 护板标志:close() / cancel() 等主动操作期间跳过 I/O 断开检测。 */ - private _intentionalClose = false; - - constructor(private readonly baudRate = 115200) {} - - /** 获取底层 SerialPort 引用(供 ReconnectManager 使用)。 */ - get port(): SerialPort | null { - return this._port; - } - - onDisconnect(cb: () => void): void { - this._disconnectCallback = cb; - } - - onReconnect(cb: () => void): void { - this._reconnectCallback = cb; - } - - removeEventListeners(): void { - this._disconnectCallback = null; - this._reconnectCallback = null; - } - - /** 替换底层端口引用,供 ReconnectManager 在设备重连后调用。 */ - replacePort(newPort: SerialPort): void { - this._port = newPort; - } - - /** 触发断开回调,供 ReconnectManager 调用。 */ - notifyDisconnect(): void { - this._disconnectCallback?.(); - } - - /** 触发重连回调,供 ReconnectManager 调用。 */ - notifyReconnect(): void { - this._reconnectCallback?.(); + constructor(port: SerialPort, private readonly baudRate = 115200) { + this._port = port; } - async selectDevice(): Promise { - if (!("serial" in navigator)) throw new Error("WebSerial is not supported"); - const serialApi = navigator.serial as Serial; - this._port = await serialApi.requestPort(); - } - - isDeviceReady(): boolean { - return Boolean(this._port); - } - - getDeviceLabel(): string | null { - if (!this._port) return null; - const info = this._port.getInfo?.(); - if (!info) return "Serial device"; - const vendor = typeof info.usbVendorId === "number" ? info.usbVendorId.toString(16) : "unknown"; - const product = typeof info.usbProductId === "number" ? info.usbProductId.toString(16) : "unknown"; - return `Serial ${vendor}:${product}`; - } - - getDeviceDetails(): string[] { - if (!this._port) return []; - const info = this._port.getInfo?.(); - if (!info) return ["Serial device"]; - const details: string[] = []; - if (typeof info.usbVendorId === "number") { - details.push(`VID: 0x${info.usbVendorId.toString(16).padStart(4, "0").toUpperCase()}`); - } - if (typeof info.usbProductId === "number") { - details.push(`PID: 0x${info.usbProductId.toString(16).padStart(4, "0").toUpperCase()}`); - } - return details; + get port(): SerialPort { + return this._port; } - /** - * 已打开且流可用时直接返回(幂等)。STM32 等协议在会话开始即 open;ESP32(esptool-js)由 - * vendor 在 `probe` 内 `Transport.connect` 打开,会话层可跳过对本方法的首次调用(见 - * `FlasherProtocol.defersTransportOpen`)。 - */ async open(): Promise { - if (!this._port) { - await this.selectDevice(); - } - if (!this._port) throw new Error("Serial port is not selected"); if (this._port.readable && this._port.writable) return; await this._port.open({ baudRate: this.baudRate }); - // Intentionally do not lock readable/writable here. - } - - async releaseSession(): Promise { - await this.reader?.cancel().catch(() => undefined); - this.reader?.releaseLock(); - this.writer?.releaseLock(); - this.reader = null; - this.writer = null; } async close(): Promise { - this._intentionalClose = true; - this.removeEventListeners(); - await this.releaseSession(); - await this._port?.close().catch(() => undefined); - this._port = null; + await this._port.close().catch(() => undefined); } async write(data: Uint8Array): Promise { - if (!this._port) throw new Error("Serial port is not opened"); - if (!this._port.writable) throw new Error("Serial writable stream unavailable"); + if (!this._port.writable) throw new Error('Serial writable stream unavailable'); const writer = this._port.writable.getWriter(); try { await writer.write(data); - } catch (e) { - // 串口流写入失败 → 设备可能已断开(这是最可靠的 I/O 级检测路径) - if (!this._intentionalClose) this.notifyDisconnect(); - throw e; } finally { writer.releaseLock(); } } async read(size: number, timeoutMs = 1000): Promise { - if (!this._port) throw new Error("Serial port is not opened"); - if (!this._port.readable) { - if (!this._intentionalClose) this.notifyDisconnect(); - throw new Error("Serial readable stream unavailable"); - } + if (!this._port.readable) throw new Error('Serial readable stream unavailable'); const reader = this._port.readable.getReader(); const deadline = Date.now() + timeoutMs; const chunks: number[] = []; try { while (chunks.length < size) { - if (Date.now() > deadline) throw new Error("Serial read timeout"); + if (Date.now() > deadline) throw new Error('Serial read timeout'); const result = await reader.read(); - if (result.done) { - // 流已关闭 → 设备断开 - if (!this._intentionalClose) this.notifyDisconnect(); - throw new Error("Serial closed"); - } + if (result.done) throw new Error('Serial closed'); if (result.value) chunks.push(...result.value); } return Uint8Array.from(chunks.slice(0, size)); - } catch (e) { - // 非超时错误也可能是断开的信号 - if (!this._intentionalClose && e instanceof Error && e.message !== "Serial read timeout") { - this.notifyDisconnect(); - } - throw e; } finally { reader.releaseLock(); } } - async cancel(): Promise { - this._intentionalClose = true; - await this.reader?.cancel().catch(() => undefined); - } - getPort(): SerialPort { - if (!this._port) throw new Error("Serial port is not opened"); return this._port; } async setSignals(signals: SerialSignals): Promise { - if (!this._port) throw new Error("Serial port is not opened"); await this._port.setSignals(signals); } } diff --git a/kits/downloadkit/src/transports/types.ts b/kits/downloadkit/src/transports/types.ts index c9e7984..e0d345a 100644 --- a/kits/downloadkit/src/transports/types.ts +++ b/kits/downloadkit/src/transports/types.ts @@ -1,23 +1,9 @@ export interface Transport { readonly name: string; - selectDevice?(): Promise; - isDeviceReady?(): boolean; - getDeviceLabel?(): string | null; - getDeviceDetails?(): string[]; - releaseSession?(): Promise; open(): Promise; close(): Promise; write(data: Uint8Array): Promise; read(size: number, timeoutMs?: number): Promise; - flush?(): Promise; - cancel?(): Promise; - - /** 注册设备被动断开回调(如 USB 被拔出) */ - onDisconnect?: (cb: () => void) => void; - /** 注册设备重新连接回调(如 USB 重新插入) */ - onReconnect?: (cb: () => void) => void; - /** 移除所有已注册的事件监听器 */ - removeEventListeners?: () => void; } export interface SerialSignals { diff --git a/kits/downloadkit/src/transports/usb/WebUsbTransport.ts b/kits/downloadkit/src/transports/usb/WebUsbTransport.ts index 9eb846c..db4a912 100644 --- a/kits/downloadkit/src/transports/usb/WebUsbTransport.ts +++ b/kits/downloadkit/src/transports/usb/WebUsbTransport.ts @@ -1,105 +1,25 @@ -import type { UsbTransport } from "../types"; +import type { UsbTransport } from '../types'; export class WebUsbTransport implements UsbTransport { - readonly name = "web-usb"; - private _device: USBDevice | null = null; - private opened = false; + readonly name = 'web-usb'; + private _device: USBDevice; - private _disconnectCallback: (() => void) | null = null; - private _reconnectCallback: (() => void) | null = null; - - constructor(private readonly filters: USBDeviceFilter[] = []) {} - - /** 获取底层 USBDevice 引用(供 ReconnectManager 使用)。 */ - get device(): USBDevice | null { - return this._device; - } - - onDisconnect(cb: () => void): void { - this._disconnectCallback = cb; - } - - onReconnect(cb: () => void): void { - this._reconnectCallback = cb; - } - - removeEventListeners(): void { - this._disconnectCallback = null; - this._reconnectCallback = null; - } - - /** 替换底层设备引用,供 ReconnectManager 在设备重连后调用。 */ - replaceDevice(newDevice: USBDevice): void { - this._device = newDevice; - this.opened = false; - } - - /** 触发断开回调,供 ReconnectManager 调用。 */ - notifyDisconnect(): void { - this._disconnectCallback?.(); - } - - /** 触发重连回调,供 ReconnectManager 调用。 */ - notifyReconnect(): void { - this._reconnectCallback?.(); - } - - async selectDevice(): Promise { - if (!("usb" in navigator)) throw new Error("WebUSB is not supported"); - const usbApi = navigator.usb as USB; - this._device = await usbApi.requestDevice({ filters: this.filters }); - } - - isDeviceReady(): boolean { - return Boolean(this._device); - } - - getDeviceLabel(): string | null { - if (!this._device) return null; - return this._device.productName ?? `${this._device.vendorId.toString(16)}:${this._device.productId.toString(16)}`; + constructor(device: USBDevice) { + this._device = device; } - getDeviceDetails(): string[] { - if (!this._device) return []; - const details: string[] = []; - details.push(`VID: 0x${this._device.vendorId.toString(16).padStart(4, "0").toUpperCase()}`); - details.push(`PID: 0x${this._device.productId.toString(16).padStart(4, "0").toUpperCase()}`); - if (this._device.manufacturerName) details.push(`MFR: ${this._device.manufacturerName}`); - if (this._device.productName) details.push(`PRODUCT: ${this._device.productName}`); - if (this._device.serialNumber) details.push(`SN: ${this._device.serialNumber}`); - if (this._device.usbVersionMajor != null) { - details.push( - `USB: ${this._device.usbVersionMajor}.${String(this._device.usbVersionMinor ?? 0)}.${String(this._device.usbVersionSubminor ?? 0)}`, - ); - } - return details; + get device(): USBDevice { + return this._device; } async open(): Promise { - if (!this._device) { - await this.selectDevice(); - } - if (!this._device) throw new Error("USB device is not selected"); - if (this._device.opened) { - this.opened = true; - return; - } + if (this._device.opened) return; await this._device.open(); if (!this._device.configuration) await this._device.selectConfiguration(1); - this.opened = true; - } - - async releaseSession(): Promise { - // Keep selected USB device for next download round. } async close(): Promise { - this.removeEventListeners(); - if (this._device && this.opened) { - await this._device.close().catch(() => undefined); - } - this._device = null; - this.opened = false; + await this._device.close().catch(() => undefined); } async write(_data: Uint8Array): Promise { @@ -111,7 +31,6 @@ export class WebUsbTransport implements UsbTransport { } getDevice(): USBDevice { - if (!this._device) throw new Error("USB device is not opened"); return this._device; } } diff --git a/package.json b/package.json index 2df4d59..8a9c07e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "type": "module", - "packageManager": "pnpm@11.4.0", + "packageManager": "pnpm@11.6.0", "scripts": { "dev": "turbo dev --filter=@weblink/web", "dev:web": "turbo dev --filter=@weblink/web", @@ -32,7 +32,7 @@ "eslint-plugin-vue": "^10.8.0", "globals": "^16.2.0", "prettier": "^3.8.3", - "turbo": "^2.9.14", + "turbo": "^2.9.18", "typescript": "~6.0.2", "typescript-eslint": "^8.58.2", "vite": "^8.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8b80157..018d662 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,7 +16,7 @@ importers: version: 2.2.6 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) eslint: specifier: ^10.2.0 version: 10.2.1(jiti@2.6.1) @@ -30,8 +30,8 @@ importers: specifier: ^3.8.3 version: 3.8.3 turbo: - specifier: ^2.9.14 - version: 2.9.14 + specifier: ^2.9.18 + version: 2.9.18 typescript: specifier: ~6.0.2 version: 6.0.3 @@ -40,10 +40,10 @@ importers: version: 8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -74,7 +74,7 @@ importers: version: 25.1.8(electron-builder-squirrel-windows@25.1.8) electron-vite: specifier: ^6.0.0-beta.1 - version: 6.0.0-beta.1(@swc/core@1.15.33(@swc/helpers@0.5.21))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 6.0.0-beta.1(@swc/core@1.15.33(@swc/helpers@0.5.21))(vite@8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) apps/tauri: dependencies: @@ -93,10 +93,10 @@ importers: version: 10.56.0(pinia@2.3.1(typescript@6.0.3)(vue@3.5.32(typescript@6.0.3)))(vue@3.5.32(typescript@6.0.3)) '@vercel/analytics': specifier: ^2.0.1 - version: 2.0.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vue-router@4.6.4(vue@3.5.32(typescript@6.0.3)))(vue@3.5.32(typescript@6.0.3)) + version: 2.0.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vue-router@4.6.4(vue@3.5.32(typescript@6.0.3)))(vue@3.5.32(typescript@6.0.3)) '@vercel/speed-insights': specifier: ^2.0.0 - version: 2.0.0(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vue-router@4.6.4(vue@3.5.32(typescript@6.0.3)))(vue@3.5.32(typescript@6.0.3)) + version: 2.0.0(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vue-router@4.6.4(vue@3.5.32(typescript@6.0.3)))(vue@3.5.32(typescript@6.0.3)) '@weblink/bridge': specifier: workspace:* version: link:../../packages/bridge @@ -163,7 +163,7 @@ importers: version: 24.12.2 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config @@ -175,10 +175,10 @@ importers: version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vite-plugin-pwa: specifier: ^1.3.0 - version: 1.3.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(workbox-build@7.4.1)(workbox-window@7.4.1) + version: 1.3.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(workbox-build@7.4.1)(workbox-window@7.4.1) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -206,22 +206,25 @@ importers: version: 1.0.14 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -240,22 +243,25 @@ importers: devDependencies: '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -337,13 +343,16 @@ importers: version: 1.0.14 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config fake-indexeddb: specifier: ^6.2.5 version: 6.2.5 @@ -352,10 +361,10 @@ importers: version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -386,22 +395,25 @@ importers: version: 1.0.14 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -420,10 +432,10 @@ importers: version: link:../../packages/tsconfig vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) kits/hidkit: dependencies: @@ -442,22 +454,25 @@ importers: version: 24.12.2 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -488,22 +503,25 @@ importers: version: 24.12.2 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -521,10 +539,10 @@ importers: version: 0.515.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) '@sveltejs/vite-plugin-svelte': specifier: ^6.1.0 - version: 6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)) + version: 6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)) '@tailwindcss/vite': specifier: ^4.0.0 - version: 4.2.2(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)) + version: 4.2.2(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.8 @@ -536,7 +554,7 @@ importers: version: 1.0.8 bits-ui: specifier: ^2.9.2 - version: 2.18.0(@internationalized/date@3.12.1)(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) + version: 2.18.0(@internationalized/date@3.12.1)(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -548,7 +566,7 @@ importers: version: 3.17.0(eslint@9.39.4(jiti@2.6.1))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) formsnap: specifier: ^2.0.1 - version: 2.0.1(svelte@5.55.4(@typescript-eslint/types@8.58.2))(sveltekit-superforms@2.30.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(@types/json-schema@7.0.15)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)) + version: 2.0.1(svelte@5.55.4(@typescript-eslint/types@8.58.2))(sveltekit-superforms@2.30.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(@types/json-schema@7.0.15)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)) globals: specifier: ^16.3.0 version: 16.5.0 @@ -572,7 +590,7 @@ importers: version: 4.4.6(picomatch@4.0.4)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3) sveltekit-superforms: specifier: ^2.27.1 - version: 2.30.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(@types/json-schema@7.0.15)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3) + version: 2.30.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(@types/json-schema@7.0.15)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3) tailwind-merge: specifier: ^3.3.1 version: 3.5.0 @@ -593,10 +611,10 @@ importers: version: 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.8.3) vite: specifier: ^7.0.4 - version: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0) + version: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4) vite-plugin-singlefile: specifier: ^2.3.0 - version: 2.3.3(rollup@4.60.2)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)) + version: 2.3.3(rollup@4.60.2)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)) zod: specifier: ^3.25.76 version: 3.25.76 @@ -621,22 +639,25 @@ importers: version: 24.12.2 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -658,22 +679,25 @@ importers: version: 24.12.2 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -701,22 +725,25 @@ importers: version: 1.0.8 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -738,22 +765,25 @@ importers: version: 24.12.2 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -781,22 +811,25 @@ importers: version: 24.12.2 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -824,22 +857,25 @@ importers: version: 24.12.2 '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) '@weblink/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@weblink/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@weblink/vite-config': + specifier: workspace:* + version: link:../../packages/vite-config typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -859,12 +895,18 @@ importers: better-sqlite3: specifier: ^11.9.1 version: 11.10.0 + js-yaml: + specifier: ^4.1.0 + version: 4.2.0 + tsx: + specifier: ^4.19.0 + version: 4.22.4 typescript: specifier: ~6.0.2 version: 6.0.3 vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) vue-tsc: specifier: ^3.2.6 version: 3.2.7(typescript@6.0.3) @@ -922,22 +964,25 @@ importers: version: 6.0.3 vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) packages/vite-config: devDependencies: '@vitejs/plugin-vue': specifier: ^6.0.5 - version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3)) + version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3)) + '@weblink/tsconfig': + specifier: workspace:* + version: link:../tsconfig typescript: specifier: ~6.0.2 version: 6.0.3 vite: specifier: ^8.0.4 - version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vitest: specifier: ^4.1.4 - version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + version: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) packages: @@ -976,6 +1021,10 @@ packages: resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} + '@babel/core@7.29.7': + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.29.1': resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} @@ -1105,6 +1154,10 @@ packages: resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} + '@babel/helpers@7.29.7': + resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.29.2': resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} engines: {node: '>=6.0.0'} @@ -1502,6 +1555,10 @@ packages: resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} + '@babel/runtime@7.29.7': + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.28.6': resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} @@ -1628,6 +1685,9 @@ packages: resolution: {integrity: sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==} engines: {node: '>=16.4'} + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + '@emnapi/core@1.9.2': resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} @@ -1661,6 +1721,12 @@ packages: 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.25.12': resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} engines: {node: '>=18'} @@ -1679,6 +1745,12 @@ packages: 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.25.12': resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} engines: {node: '>=18'} @@ -1697,6 +1769,12 @@ packages: 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.25.12': resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} engines: {node: '>=18'} @@ -1715,6 +1793,12 @@ packages: 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.25.12': resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} engines: {node: '>=18'} @@ -1733,6 +1817,12 @@ packages: 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.25.12': resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} engines: {node: '>=18'} @@ -1751,6 +1841,12 @@ packages: 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.25.12': resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} engines: {node: '>=18'} @@ -1769,6 +1865,12 @@ packages: 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.25.12': resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} engines: {node: '>=18'} @@ -1787,6 +1889,12 @@ packages: 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.25.12': resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} engines: {node: '>=18'} @@ -1805,6 +1913,12 @@ packages: 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.25.12': resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} engines: {node: '>=18'} @@ -1823,6 +1937,12 @@ packages: 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.25.12': resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} engines: {node: '>=18'} @@ -1841,6 +1961,12 @@ packages: 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.25.12': resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} engines: {node: '>=18'} @@ -1859,6 +1985,12 @@ packages: 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.25.12': resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} engines: {node: '>=18'} @@ -1877,6 +2009,12 @@ packages: 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.25.12': resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} engines: {node: '>=18'} @@ -1895,6 +2033,12 @@ packages: 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.25.12': resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} engines: {node: '>=18'} @@ -1913,6 +2057,12 @@ packages: 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.25.12': resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} engines: {node: '>=18'} @@ -1931,6 +2081,12 @@ packages: 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.25.12': resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} engines: {node: '>=18'} @@ -1949,6 +2105,12 @@ packages: 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.25.12': resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} engines: {node: '>=18'} @@ -1967,6 +2129,12 @@ packages: 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.25.12': resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} engines: {node: '>=18'} @@ -1985,6 +2153,12 @@ packages: 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.25.12': resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} engines: {node: '>=18'} @@ -2003,6 +2177,12 @@ packages: 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.25.12': resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} engines: {node: '>=18'} @@ -2021,6 +2201,12 @@ packages: 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.25.12': resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} engines: {node: '>=18'} @@ -2039,6 +2225,12 @@ packages: 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.25.12': resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} engines: {node: '>=18'} @@ -2057,6 +2249,12 @@ packages: 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.25.12': resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} engines: {node: '>=18'} @@ -2075,6 +2273,12 @@ packages: 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.25.12': resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} engines: {node: '>=18'} @@ -2093,6 +2297,12 @@ packages: 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.25.12': resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} engines: {node: '>=18'} @@ -2111,6 +2321,12 @@ packages: 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] + '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2474,6 +2690,12 @@ packages: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 + '@napi-rs/wasm-runtime@1.1.5': + resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@npmcli/fs@2.1.2': resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -2678,6 +2900,9 @@ packages: '@oxc-project/types@0.124.0': resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} + '@oxc-project/types@0.133.0': + resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + '@pinojs/redact@0.4.0': resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} @@ -2711,30 +2936,60 @@ packages: cpu: [arm64] os: [android] + '@rolldown/binding-android-arm64@1.0.3': + resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@rolldown/binding-darwin-arm64@1.0.0-rc.15': resolution: {integrity: sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + '@rolldown/binding-darwin-arm64@1.0.3': + resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@rolldown/binding-darwin-x64@1.0.0-rc.15': resolution: {integrity: sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + '@rolldown/binding-darwin-x64@1.0.3': + resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@rolldown/binding-freebsd-x64@1.0.0-rc.15': resolution: {integrity: sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + '@rolldown/binding-freebsd-x64@1.0.3': + resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': resolution: {integrity: sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': resolution: {integrity: sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2742,6 +2997,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-arm64-gnu@1.0.3': + resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': resolution: {integrity: sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2749,6 +3011,13 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-arm64-musl@1.0.3': + resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': resolution: {integrity: sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2756,6 +3025,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': resolution: {integrity: sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2763,6 +3039,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.0.3': + resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': resolution: {integrity: sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2770,6 +3053,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.0.3': + resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': resolution: {integrity: sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2777,35 +3067,68 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-x64-musl@1.0.3': + resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': resolution: {integrity: sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] + '@rolldown/binding-openharmony-arm64@1.0.3': + resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': resolution: {integrity: sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==} engines: {node: '>=14.0.0'} cpu: [wasm32] + '@rolldown/binding-wasm32-wasi@1.0.3': + resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': resolution: {integrity: sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] + '@rolldown/binding-win32-arm64-msvc@1.0.3': + resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': resolution: {integrity: sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] + '@rolldown/binding-win32-x64-msvc@1.0.3': + resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@rolldown/pluginutils@1.0.0-rc.13': resolution: {integrity: sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==} '@rolldown/pluginutils@1.0.0-rc.15': resolution: {integrity: sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==} + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + '@rollup/plugin-babel@6.1.0': resolution: {integrity: sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==} engines: {node: '>=14.0.0'} @@ -2860,139 +3183,277 @@ packages: cpu: [arm] os: [android] + '@rollup/rollup-android-arm-eabi@4.62.0': + resolution: {integrity: sha512-IPIQ55ythEHkfEd9jMEi32OQ7SxURsGA43JI22lj01OLZNt2NUbJX8YUHxkVWyQ6daHPNn0truF5nSj3DQp6YQ==} + cpu: [arm] + os: [android] + '@rollup/rollup-android-arm64@4.60.2': resolution: {integrity: sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==} cpu: [arm64] os: [android] + '@rollup/rollup-android-arm64@4.62.0': + resolution: {integrity: sha512-M6s9cr10MibETyo8JsOkq+Lo1+lU6hcvb1MApnUql5qte/5hMEgzlN8/ReIKNfRV8rrqX50W1BX9zoUhC192RA==} + cpu: [arm64] + os: [android] + '@rollup/rollup-darwin-arm64@4.60.2': resolution: {integrity: sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==} cpu: [arm64] os: [darwin] + '@rollup/rollup-darwin-arm64@4.62.0': + resolution: {integrity: sha512-BqCoMoIbn0keKys+dEAdBa70EtOwV1bEsQCUgU9FdiZmmMge/Zk7LlkYGqbrdHR+Frnt0E1FOanly+rlwvvQzw==} + cpu: [arm64] + os: [darwin] + '@rollup/rollup-darwin-x64@4.60.2': resolution: {integrity: sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==} cpu: [x64] os: [darwin] + '@rollup/rollup-darwin-x64@4.62.0': + resolution: {integrity: sha512-SIMzST3VFNXDAbeIWDWiFCNM5qncUBDWaEV7NfE7oZbDt2mgfW4MvbKdbYiGOLoM32gbTv608UMd0XktEYSD7w==} + cpu: [x64] + os: [darwin] + '@rollup/rollup-freebsd-arm64@4.60.2': resolution: {integrity: sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==} cpu: [arm64] os: [freebsd] + '@rollup/rollup-freebsd-arm64@4.62.0': + resolution: {integrity: sha512-ezjfSQMP7ArdUsbBwbQIfwAlhE84I2iVnzQNCFSveqV42q+BmKlzVpf7mxv5EchLcoWU4y6/heFzVg1F+hodUQ==} + cpu: [arm64] + os: [freebsd] + '@rollup/rollup-freebsd-x64@4.60.2': resolution: {integrity: sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==} cpu: [x64] os: [freebsd] + '@rollup/rollup-freebsd-x64@4.62.0': + resolution: {integrity: sha512-9+qTWGW9AZRhnUgwtTwzNwcPlL87ngkeN0LA+q1bADvmY9aNvWaF2TFW8BZgnQPYxpDI7+rMVLivcd4V737TAQ==} + cpu: [x64] + os: [freebsd] + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': resolution: {integrity: sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==} cpu: [arm] os: [linux] libc: [glibc] + '@rollup/rollup-linux-arm-gnueabihf@4.62.0': + resolution: {integrity: sha512-T1dMEQhXA/jkJ/jyMIw9IovK8bSUq7A8kLIlvZTb/6YIVsp2zLavr4F3oyllHWo7eIVJRyE5n3tUjQJEbE1IuQ==} + cpu: [arm] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-arm-musleabihf@4.60.2': resolution: {integrity: sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==} cpu: [arm] os: [linux] libc: [musl] + '@rollup/rollup-linux-arm-musleabihf@4.62.0': + resolution: {integrity: sha512-2as0LgT7qQpyceQq6VUJYnumUMUrgGQCWIiDIN9DE0/tglsk6o66uCB4f3djRawAltvfCNLyZZrsqbPA6inCsA==} + cpu: [arm] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-arm64-gnu@4.60.2': resolution: {integrity: sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==} cpu: [arm64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-arm64-gnu@4.62.0': + resolution: {integrity: sha512-bVURMg+6eNN9C/yc0aVjooZcwTTtYF4YW3xta5pP0//r3o1V8gXEHXWCndj47w/HhwsFroZrFhR+6uQP5T0n0g==} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-arm64-musl@4.60.2': resolution: {integrity: sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==} cpu: [arm64] os: [linux] libc: [musl] + '@rollup/rollup-linux-arm64-musl@4.62.0': + resolution: {integrity: sha512-Ful8pM/2yYI83PViWdFdpZhdI8HJ5qsXANe5atypbHDf+KIBBDsZsbyy8hbXnULVvW9NsTh5DHwbcBftyLTfiw==} + cpu: [arm64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-loong64-gnu@4.60.2': resolution: {integrity: sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==} cpu: [loong64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-loong64-gnu@4.62.0': + resolution: {integrity: sha512-9Gp/DgrkzfUBmNPVTyPTvay+4xEP7M/clXpj3efXBcm6uTIVIgDg4rqUpqKXvLEuFRVuEpSAOkhgNeecvaZ4Cg==} + cpu: [loong64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-loong64-musl@4.60.2': resolution: {integrity: sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==} cpu: [loong64] os: [linux] libc: [musl] + '@rollup/rollup-linux-loong64-musl@4.62.0': + resolution: {integrity: sha512-m9tsJz54LUXkSYM8+8PG81B9IKK5r+2T0clMq4QrS16xFosufU7firBDAZEsDheDs7wTlP7h3++S7lMsU955HA==} + cpu: [loong64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-ppc64-gnu@4.60.2': resolution: {integrity: sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==} cpu: [ppc64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-ppc64-gnu@4.62.0': + resolution: {integrity: sha512-3UvJ5PNVU16aJf6M3tFI24pWzAl2/ynfbyRN3ICyQajK1lSkrnVYNnLz3v04J32qKa0FczJc22zeToc0lr2A3w==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-ppc64-musl@4.60.2': resolution: {integrity: sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==} cpu: [ppc64] os: [linux] libc: [musl] + '@rollup/rollup-linux-ppc64-musl@4.62.0': + resolution: {integrity: sha512-vRWUAbYLGHBZS6Q8Msb2sfnf1fvJf+47t8l/TwOerM2qArzy+IeNMTHrYLHXh95h8MoatPHI5hhSZNs+mGXKPg==} + cpu: [ppc64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-riscv64-gnu@4.60.2': resolution: {integrity: sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==} cpu: [riscv64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-riscv64-gnu@4.62.0': + resolution: {integrity: sha512-c00T5SYENHAt86cfW47URaP3Us5vLC/4QO7GYud1G5VNRffCwwCuBspwqYrriuJB+5m0WFzClCn9wed0FBjKvg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-riscv64-musl@4.60.2': resolution: {integrity: sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==} cpu: [riscv64] os: [linux] libc: [musl] + '@rollup/rollup-linux-riscv64-musl@4.62.0': + resolution: {integrity: sha512-krrCDilhXOwFkSkO3Wm9I/f9H0L92XHHwy2fwxjukxIbh0dem8gZqOW5Y8BsHrpJv5qwlRBV+Wl4ZFyRWhUpwg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-s390x-gnu@4.60.2': resolution: {integrity: sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==} cpu: [s390x] os: [linux] libc: [glibc] + '@rollup/rollup-linux-s390x-gnu@4.62.0': + resolution: {integrity: sha512-7pfYFSTc4/rUC/FtAI0Qp6QthDBCIi6/AuP1xYqFk5vanI6KnL5dWKP60OM/05LOsbwTmIcvr6eXC4CJuJ75IA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-x64-gnu@4.60.2': resolution: {integrity: sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==} cpu: [x64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-x64-gnu@4.62.0': + resolution: {integrity: sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg==} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-x64-musl@4.60.2': resolution: {integrity: sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==} cpu: [x64] os: [linux] libc: [musl] + '@rollup/rollup-linux-x64-musl@4.62.0': + resolution: {integrity: sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw==} + cpu: [x64] + os: [linux] + libc: [musl] + '@rollup/rollup-openbsd-x64@4.60.2': resolution: {integrity: sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==} cpu: [x64] os: [openbsd] + '@rollup/rollup-openbsd-x64@4.62.0': + resolution: {integrity: sha512-3oVS7FLGa4U1qcvao9ylGxrjXZyUQqR8UwxEcnUEyPX53O/C/mKDZegNXTdHCP+h3e6ta/f1EN38Yif1mmZHYg==} + cpu: [x64] + os: [openbsd] + '@rollup/rollup-openharmony-arm64@4.60.2': resolution: {integrity: sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==} cpu: [arm64] os: [openharmony] + '@rollup/rollup-openharmony-arm64@4.62.0': + resolution: {integrity: sha512-yTB9TgfWj5wHe5QgktAgXTLLot1gvEjl1NiPPAUiCs4oPrIWFl5V4nC3GrkNdj9LaAU4s94nVrGbGOCqUpyWsg==} + cpu: [arm64] + os: [openharmony] + '@rollup/rollup-win32-arm64-msvc@4.60.2': resolution: {integrity: sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==} cpu: [arm64] os: [win32] + '@rollup/rollup-win32-arm64-msvc@4.62.0': + resolution: {integrity: sha512-5LOhoaesY3doG1c+ac/2JtgREpKoJr5bUHH8tKY0V8di7+uSV6BwLs2PlR0/yzefGOkR+wE7ZolZphHCsyG5Rw==} + cpu: [arm64] + os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.60.2': resolution: {integrity: sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==} cpu: [ia32] os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.62.0': + resolution: {integrity: sha512-yYkWHhmbhRTWTnWos5HC4GcPQfjlzzCNbM9e/+GXrLuaBXYA3qSDR9f0Vgufd5S8yX81U8jPKp7ZnAjZFMtRnw==} + cpu: [ia32] + os: [win32] + '@rollup/rollup-win32-x64-gnu@4.60.2': resolution: {integrity: sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-gnu@4.62.0': + resolution: {integrity: sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA==} + cpu: [x64] + os: [win32] + '@rollup/rollup-win32-x64-msvc@4.60.2': resolution: {integrity: sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-msvc@4.62.0': + resolution: {integrity: sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA==} + cpu: [x64] + os: [win32] + '@sentry-internal/browser-utils@10.50.0': resolution: {integrity: sha512-42bxyRTxnCmYlWnvz4CxikuQNanw8UNma2WJrtxJ0f1MAJV2GhQGSHDLnA+lvFlmiz6qct3pfen/NXGyOTegTA==} engines: {node: '>=18'} @@ -3122,6 +3583,11 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@sveltejs/acorn-typescript@1.0.10': + resolution: {integrity: sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==} + peerDependencies: + acorn: ^8.9.0 + '@sveltejs/acorn-typescript@1.0.9': resolution: {integrity: sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==} peerDependencies: @@ -3439,39 +3905,42 @@ packages: '@tsconfig/svelte@5.0.8': resolution: {integrity: sha512-UkNnw1/oFEfecR8ypyHIQuWYdkPvHiwcQ78sh+ymIiYoF+uc5H1UBetbjyqT+vgGJ3qQN6nhucJviX6HesWtKQ==} - '@turbo/darwin-64@2.9.14': - resolution: {integrity: sha512-t7QiPflaEyBE4oayeZtSmu4mEfjgIrcNlNNl1z1dmIVPqEdtA7+CfTf8d7KXsOGPh6aNgWjKxyvQg9uGfDQF+A==} + '@turbo/darwin-64@2.9.18': + resolution: {integrity: sha512-9f27peFu16ur8c0v9nUFUEyBnbKuuFsUTjHFWfmwGfzySBXbHwzU44QhZon6Mznz0cHsIr3984NQj/bVrnGSRw==} cpu: [x64] os: [darwin] - '@turbo/darwin-arm64@2.9.14': - resolution: {integrity: sha512-d23147mC9BsCPA9mJ0h/ubcpbRgcJBXbcG3+Vq7YLhjz3IXuvQsJ1UXH8f4MD76ZjJ4m/E4aRdJV+MW88CDfbw==} + '@turbo/darwin-arm64@2.9.18': + resolution: {integrity: sha512-9A6TMRq/Ib+QnbhLlgkhOm+624wO4pzSQ/yQviQfWHOlFvaYxdnIAYmu2H6TS6y7kSVL0DvzNe04NbESTOzFVQ==} cpu: [arm64] os: [darwin] - '@turbo/linux-64@2.9.14': - resolution: {integrity: sha512-P3ZKB5tuUDdDQWuAsACGUR1qv9W7BNWxdxqVJ0kZNuNNPRaVYTPPikLcp79+GiEcW3npsR+KyP38lnQiBc5aSA==} + '@turbo/linux-64@2.9.18': + resolution: {integrity: sha512-zCdIDtz69AnbYh913elJRRoF3QY5aa2HNnf+4rAkc7bQ+tWujiDkCNV7stazOUPggaDvhKIf2Z87qHftTeXSkw==} cpu: [x64] os: [linux] - '@turbo/linux-arm64@2.9.14': - resolution: {integrity: sha512-ZRTlzcUMrrPv9ZuDzRF9n60Ym13bKeG9jDB8WjxyLhWNzV+AJQN+zdpIk3NJYf2zQsGUm1mNar2P0elRzLw25g==} + '@turbo/linux-arm64@2.9.18': + resolution: {integrity: sha512-Va1kXI04naMgYwqv/5Dfa36dTDx8015U7oaQAjrXa45ua9OoFjSV4OmvkML4EmXvUclQHCiBRbY8bvd0jV7eAg==} cpu: [arm64] os: [linux] - '@turbo/windows-64@2.9.14': - resolution: {integrity: sha512-exanwN6sIduZwykYeiTQj8kCmOhazP5WOz3bvXMcYtjhL6Z3iRWLewKrXCBq0bqwSP3iBMb/AerRCnHI4lx46A==} + '@turbo/windows-64@2.9.18': + resolution: {integrity: sha512-m0kDhZANxSNz9ck1ybogFscHabriAsp4eDFNrN/1H5WrgTF7b3VlcPZnhuO3v2+E2KnCbeAc+UUT10BZZHdDKw==} cpu: [x64] os: [win32] - '@turbo/windows-arm64@2.9.14': - resolution: {integrity: sha512-fVdCsnmYoKICsycbWuuGp6Jvi51/3G/UluFWuAUCvR8PIW5IJkAk5BM9UF8PSm0Q2IphWHFZjYEgjHsh3B9y/g==} + '@turbo/windows-arm64@2.9.18': + resolution: {integrity: sha512-nUdR8WqoomUys9iIQmG45TMiizJ+5BV8egSeLLZba/AWblyp3fVBcIH1kSE58OtK4g2YzbMJEth6Ttv9w5rqMA==} cpu: [arm64] os: [win32] '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + '@types/cacheable-request@6.0.3': resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} @@ -3496,6 +3965,9 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@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==} @@ -3829,6 +4301,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -4405,6 +4882,9 @@ packages: devalue@5.7.1: resolution: {integrity: sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA==} + devalue@5.8.1: + resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} + dir-compare@4.2.0: resolution: {integrity: sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==} @@ -4513,6 +4993,10 @@ packages: error-stack-parser-es@1.0.5: resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + es-abstract-get@1.0.0: + resolution: {integrity: sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==} + engines: {node: '>= 0.4'} + es-abstract@1.24.2: resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} engines: {node: '>= 0.4'} @@ -4540,8 +5024,8 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + es-to-primitive@1.3.1: + resolution: {integrity: sha512-CxN9N56HYfd2m/acc/NOFrZQsN9kU4eh+2kk6A707Kz1krH8tKmfrs5RnftB8WNX80T0NS7vSQsDOlg23diR2g==} engines: {node: '>= 0.4'} es6-error@4.1.1: @@ -4562,6 +5046,11 @@ packages: 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'} @@ -4855,8 +5344,8 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + function.prototype.name@1.2.0: + resolution: {integrity: sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==} engines: {node: '>= 0.4'} functions-have-names@1.2.3: @@ -4982,6 +5471,10 @@ packages: resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} engines: {node: '>= 0.4'} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + highlight.js@11.11.1: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} @@ -5137,6 +5630,10 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-document.all@1.0.0: + resolution: {integrity: sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==} + engines: {node: '>= 0.4'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -5283,8 +5780,8 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} hasBin: true jsesc@3.1.0: @@ -5675,6 +6172,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + napi-build-utils@2.0.0: resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} @@ -5939,6 +6441,10 @@ packages: resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + engines: {node: ^10 || ^12 || >=14} + postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -6095,8 +6601,8 @@ packages: regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.13.1: - resolution: {integrity: sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==} + regjsparser@0.13.2: + resolution: {integrity: sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==} hasBin: true require-directory@2.1.1: @@ -6152,11 +6658,21 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rolldown@1.0.3: + resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup@4.60.2: resolution: {integrity: sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rollup@4.62.0: + resolution: {integrity: sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + router@2.2.0: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} @@ -6221,6 +6737,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} + engines: {node: '>=10'} + hasBin: true + send@1.2.1: resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} @@ -6286,6 +6807,10 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -6571,6 +7096,10 @@ packages: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + tinyrainbow@3.1.0: resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} @@ -6622,11 +7151,16 @@ 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 + tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - turbo@2.9.14: - resolution: {integrity: sha512-BQqXRr4UoWI3UPFrtznCLykYHxwxWh53iCB57x092jPMjIlW1wnm3N895g5irpiXmnxUhREBB0n6+y8BHhs4nw==} + turbo@2.9.18: + resolution: {integrity: sha512-bwabv6PupzeavybzEoArBAkwq5fnzwf8OFnRtpHwnviFWuwJPFxtyH+aVp36TmIqK3aYYgtTJ3J0m2ysxxSzQg==} hasBin: true tw-animate-css@1.4.0: @@ -6851,6 +7385,49 @@ packages: yaml: optional: true + vite@8.0.16: + resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.18 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vite@8.0.8: resolution: {integrity: sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -7259,6 +7836,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/core@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/helper-compilation-targets': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helpers': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/generator@7.29.1': dependencies: '@babel/parser': 7.29.2 @@ -7295,29 +7892,29 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.0)': + '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-member-expression-to-functions': 7.29.7 '@babel/helper-optimise-call-expression': 7.29.7 - '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.0) + '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 '@babel/traverse': 7.29.7 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.29.7(@babel/core@7.29.0)': + '@babel/helper-create-regexp-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-annotate-as-pure': 7.29.7 regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 debug: 4.4.3 @@ -7360,9 +7957,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.0)': + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-module-imports': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 '@babel/traverse': 7.29.7 @@ -7377,18 +7974,18 @@ snapshots: '@babel/helper-plugin-utils@7.29.7': {} - '@babel/helper-remap-async-to-generator@7.29.7(@babel/core@7.29.0)': + '@babel/helper-remap-async-to-generator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-wrap-function': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.0)': + '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-member-expression-to-functions': 7.29.7 '@babel/helper-optimise-call-expression': 7.29.7 '@babel/traverse': 7.29.7 @@ -7427,6 +8024,11 @@ snapshots: '@babel/template': 7.28.6 '@babel/types': 7.29.0 + '@babel/helpers@7.29.7': + dependencies: + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 + '@babel/parser@7.29.2': dependencies: '@babel/types': 7.29.0 @@ -7435,67 +8037,67 @@ snapshots: dependencies: '@babel/types': 7.29.7 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 - '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 - '@babel/plugin-syntax-import-assertions@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-syntax-import-assertions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-import-attributes@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-syntax-import-attributes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': @@ -7503,424 +8105,427 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-arrow-functions@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-arrow-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-async-generator-functions@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-async-generator-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.0) + '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.7) '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-async-to-generator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-module-imports': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.0) + '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-block-scoped-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-block-scoping@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-block-scoping@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-class-properties@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-class-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-class-static-block@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-classes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-globals': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.0) + '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-computed-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/template': 7.29.7 - '@babel/plugin-transform-destructuring@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-destructuring@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-dotall-regex@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-dotall-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-duplicate-keys@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-duplicate-keys@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-dynamic-import@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-dynamic-import@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-explicit-resource-management@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-explicit-resource-management@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-exponentiation-operator@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-exponentiation-operator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-export-namespace-from@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-export-namespace-from@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-for-of@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-for-of@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-function-name@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-json-strings@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-literals@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-logical-assignment-operators@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-logical-assignment-operators@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-member-expression-literals@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-member-expression-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-modules-amd@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-amd@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-systemjs@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-umd@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-named-capturing-groups-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-new-target@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-new-target@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-nullish-coalescing-operator@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-nullish-coalescing-operator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-numeric-separator@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-numeric-separator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-object-rest-spread@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-object-rest-spread@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-parameters': 7.29.7(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-parameters': 7.29.7(@babel/core@7.29.7) '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-super@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-object-super@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.0) + '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-optional-catch-binding@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-optional-chaining@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-optional-chaining@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-parameters@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-private-methods@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-private-methods@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-private-property-in-object@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-annotate-as-pure': 7.29.7 - '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-property-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-regenerator@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-regenerator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-regexp-modifiers@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-regexp-modifiers@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-reserved-words@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-reserved-words@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-shorthand-properties@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-shorthand-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-spread@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-spread@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-sticky-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-template-literals@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-template-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-typeof-symbol@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-typeof-symbol@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-unicode-escapes@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-escapes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-unicode-property-regex@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-property-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-unicode-regex@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-unicode-sets-regex@7.29.7(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-sets-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 - '@babel/preset-env@7.29.7(@babel/core@7.29.0)': + '@babel/preset-env@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/compat-data': 7.29.7 - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-validator-option': 7.29.7 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) - '@babel/plugin-syntax-import-assertions': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-syntax-import-attributes': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) - '@babel/plugin-transform-arrow-functions': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-async-generator-functions': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-async-to-generator': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-block-scoped-functions': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-block-scoping': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-class-properties': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-class-static-block': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-classes': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-computed-properties': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-dotall-regex': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-duplicate-keys': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-dynamic-import': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-explicit-resource-management': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-exponentiation-operator': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-export-namespace-from': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-for-of': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-function-name': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-json-strings': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-literals': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-logical-assignment-operators': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-member-expression-literals': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-modules-amd': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-modules-commonjs': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-modules-systemjs': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-modules-umd': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-named-capturing-groups-regex': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-new-target': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-numeric-separator': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-object-rest-spread': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-object-super': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-optional-catch-binding': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-parameters': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-private-methods': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-private-property-in-object': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-property-literals': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-regenerator': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-regexp-modifiers': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-reserved-words': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-shorthand-properties': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-spread': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-sticky-regex': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-template-literals': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-typeof-symbol': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-escapes': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-property-regex': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-sets-regex': 7.29.7(@babel/core@7.29.0) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) - babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) - babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.7) + '@babel/plugin-syntax-import-assertions': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-syntax-import-attributes': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.7) + '@babel/plugin-transform-arrow-functions': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-async-generator-functions': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-async-to-generator': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-block-scoped-functions': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-block-scoping': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-class-properties': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-class-static-block': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-classes': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-computed-properties': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-dotall-regex': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-duplicate-keys': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-dynamic-import': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-explicit-resource-management': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-exponentiation-operator': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-export-namespace-from': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-for-of': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-function-name': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-json-strings': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-literals': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-logical-assignment-operators': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-member-expression-literals': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-modules-amd': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-modules-commonjs': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-modules-systemjs': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-modules-umd': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-new-target': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-nullish-coalescing-operator': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-numeric-separator': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-object-rest-spread': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-object-super': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-optional-catch-binding': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-parameters': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-private-methods': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-private-property-in-object': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-property-literals': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-regenerator': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-regexp-modifiers': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-reserved-words': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-shorthand-properties': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-spread': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-sticky-regex': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-template-literals': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-typeof-symbol': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-unicode-escapes': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-unicode-property-regex': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-unicode-sets-regex': 7.29.7(@babel/core@7.29.7) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.7) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7) + babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.7) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.7) core-js-compat: 3.49.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/types': 7.29.7 esutils: 2.0.3 - '@babel/runtime@7.29.2': {} + '@babel/runtime@7.29.2': + optional: true + + '@babel/runtime@7.29.7': {} '@babel/template@7.28.6': dependencies: @@ -8089,6 +8694,12 @@ snapshots: transitivePeerDependencies: - supports-color + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + '@emnapi/core@1.9.2': dependencies: '@emnapi/wasi-threads': 1.2.1 @@ -8121,6 +8732,9 @@ snapshots: '@esbuild/aix-ppc64@0.27.7': optional: true + '@esbuild/aix-ppc64@0.28.1': + optional: true + '@esbuild/android-arm64@0.25.12': optional: true @@ -8130,6 +8744,9 @@ snapshots: '@esbuild/android-arm64@0.27.7': optional: true + '@esbuild/android-arm64@0.28.1': + optional: true + '@esbuild/android-arm@0.25.12': optional: true @@ -8139,6 +8756,9 @@ snapshots: '@esbuild/android-arm@0.27.7': optional: true + '@esbuild/android-arm@0.28.1': + optional: true + '@esbuild/android-x64@0.25.12': optional: true @@ -8148,6 +8768,9 @@ snapshots: '@esbuild/android-x64@0.27.7': optional: true + '@esbuild/android-x64@0.28.1': + optional: true + '@esbuild/darwin-arm64@0.25.12': optional: true @@ -8157,6 +8780,9 @@ snapshots: '@esbuild/darwin-arm64@0.27.7': optional: true + '@esbuild/darwin-arm64@0.28.1': + optional: true + '@esbuild/darwin-x64@0.25.12': optional: true @@ -8166,6 +8792,9 @@ snapshots: '@esbuild/darwin-x64@0.27.7': optional: true + '@esbuild/darwin-x64@0.28.1': + optional: true + '@esbuild/freebsd-arm64@0.25.12': optional: true @@ -8175,6 +8804,9 @@ snapshots: '@esbuild/freebsd-arm64@0.27.7': optional: true + '@esbuild/freebsd-arm64@0.28.1': + optional: true + '@esbuild/freebsd-x64@0.25.12': optional: true @@ -8184,6 +8816,9 @@ snapshots: '@esbuild/freebsd-x64@0.27.7': optional: true + '@esbuild/freebsd-x64@0.28.1': + optional: true + '@esbuild/linux-arm64@0.25.12': optional: true @@ -8193,6 +8828,9 @@ snapshots: '@esbuild/linux-arm64@0.27.7': optional: true + '@esbuild/linux-arm64@0.28.1': + optional: true + '@esbuild/linux-arm@0.25.12': optional: true @@ -8202,6 +8840,9 @@ snapshots: '@esbuild/linux-arm@0.27.7': optional: true + '@esbuild/linux-arm@0.28.1': + optional: true + '@esbuild/linux-ia32@0.25.12': optional: true @@ -8211,6 +8852,9 @@ snapshots: '@esbuild/linux-ia32@0.27.7': optional: true + '@esbuild/linux-ia32@0.28.1': + optional: true + '@esbuild/linux-loong64@0.25.12': optional: true @@ -8220,6 +8864,9 @@ snapshots: '@esbuild/linux-loong64@0.27.7': optional: true + '@esbuild/linux-loong64@0.28.1': + optional: true + '@esbuild/linux-mips64el@0.25.12': optional: true @@ -8229,6 +8876,9 @@ snapshots: '@esbuild/linux-mips64el@0.27.7': optional: true + '@esbuild/linux-mips64el@0.28.1': + optional: true + '@esbuild/linux-ppc64@0.25.12': optional: true @@ -8238,6 +8888,9 @@ snapshots: '@esbuild/linux-ppc64@0.27.7': optional: true + '@esbuild/linux-ppc64@0.28.1': + optional: true + '@esbuild/linux-riscv64@0.25.12': optional: true @@ -8247,6 +8900,9 @@ snapshots: '@esbuild/linux-riscv64@0.27.7': optional: true + '@esbuild/linux-riscv64@0.28.1': + optional: true + '@esbuild/linux-s390x@0.25.12': optional: true @@ -8256,6 +8912,9 @@ snapshots: '@esbuild/linux-s390x@0.27.7': optional: true + '@esbuild/linux-s390x@0.28.1': + optional: true + '@esbuild/linux-x64@0.25.12': optional: true @@ -8265,6 +8924,9 @@ snapshots: '@esbuild/linux-x64@0.27.7': optional: true + '@esbuild/linux-x64@0.28.1': + optional: true + '@esbuild/netbsd-arm64@0.25.12': optional: true @@ -8274,6 +8936,9 @@ snapshots: '@esbuild/netbsd-arm64@0.27.7': optional: true + '@esbuild/netbsd-arm64@0.28.1': + optional: true + '@esbuild/netbsd-x64@0.25.12': optional: true @@ -8283,6 +8948,9 @@ snapshots: '@esbuild/netbsd-x64@0.27.7': optional: true + '@esbuild/netbsd-x64@0.28.1': + optional: true + '@esbuild/openbsd-arm64@0.25.12': optional: true @@ -8292,6 +8960,9 @@ snapshots: '@esbuild/openbsd-arm64@0.27.7': optional: true + '@esbuild/openbsd-arm64@0.28.1': + optional: true + '@esbuild/openbsd-x64@0.25.12': optional: true @@ -8301,6 +8972,9 @@ snapshots: '@esbuild/openbsd-x64@0.27.7': optional: true + '@esbuild/openbsd-x64@0.28.1': + optional: true + '@esbuild/openharmony-arm64@0.25.12': optional: true @@ -8310,6 +8984,9 @@ snapshots: '@esbuild/openharmony-arm64@0.27.7': optional: true + '@esbuild/openharmony-arm64@0.28.1': + optional: true + '@esbuild/sunos-x64@0.25.12': optional: true @@ -8319,6 +8996,9 @@ snapshots: '@esbuild/sunos-x64@0.27.7': optional: true + '@esbuild/sunos-x64@0.28.1': + optional: true + '@esbuild/win32-arm64@0.25.12': optional: true @@ -8328,6 +9008,9 @@ snapshots: '@esbuild/win32-arm64@0.27.7': optional: true + '@esbuild/win32-arm64@0.28.1': + optional: true + '@esbuild/win32-ia32@0.25.12': optional: true @@ -8337,6 +9020,9 @@ snapshots: '@esbuild/win32-ia32@0.27.7': optional: true + '@esbuild/win32-ia32@0.28.1': + optional: true + '@esbuild/win32-x64@0.25.12': optional: true @@ -8346,6 +9032,9 @@ snapshots: '@esbuild/win32-x64@0.27.7': optional: true + '@esbuild/win32-x64@0.28.1': + optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@10.2.1(jiti@2.6.1))': dependencies: eslint: 10.2.1(jiti@2.6.1) @@ -8398,7 +9087,7 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.1 + js-yaml: 4.2.0 minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -8688,6 +9377,13 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 + optional: true + '@npmcli/fs@2.1.2': dependencies: '@gar/promisify': 1.1.3 @@ -8946,6 +9642,8 @@ snapshots: '@oxc-project/types@0.124.0': {} + '@oxc-project/types@0.133.0': {} + '@pinojs/redact@0.4.0': {} '@pkgjs/parseargs@0.11.0': @@ -8978,39 +9676,75 @@ snapshots: '@rolldown/binding-android-arm64@1.0.0-rc.15': optional: true + '@rolldown/binding-android-arm64@1.0.3': + optional: true + '@rolldown/binding-darwin-arm64@1.0.0-rc.15': optional: true + '@rolldown/binding-darwin-arm64@1.0.3': + optional: true + '@rolldown/binding-darwin-x64@1.0.0-rc.15': optional: true + '@rolldown/binding-darwin-x64@1.0.3': + optional: true + '@rolldown/binding-freebsd-x64@1.0.0-rc.15': optional: true + '@rolldown/binding-freebsd-x64@1.0.3': + optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.3': + optional: true + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': optional: true + '@rolldown/binding-linux-arm64-musl@1.0.3': + optional: true + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': optional: true + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + optional: true + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': optional: true + '@rolldown/binding-linux-s390x-gnu@1.0.3': + optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': optional: true + '@rolldown/binding-linux-x64-gnu@1.0.3': + optional: true + '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': optional: true + '@rolldown/binding-linux-x64-musl@1.0.3': + optional: true + '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': optional: true + '@rolldown/binding-openharmony-arm64@1.0.3': + optional: true + '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': dependencies: '@emnapi/core': 1.9.2 @@ -9018,134 +9752,224 @@ snapshots: '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) optional: true + '@rolldown/binding-wasm32-wasi@1.0.3': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.3': + optional: true + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': optional: true + '@rolldown/binding-win32-x64-msvc@1.0.3': + optional: true + '@rolldown/pluginutils@1.0.0-rc.13': {} '@rolldown/pluginutils@1.0.0-rc.15': {} - '@rollup/plugin-babel@6.1.0(@babel/core@7.29.0)(rollup@4.60.2)': + '@rolldown/pluginutils@1.0.1': {} + + '@rollup/plugin-babel@6.1.0(@babel/core@7.29.7)(rollup@4.62.0)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-module-imports': 7.29.7 - '@rollup/pluginutils': 5.4.0(rollup@4.60.2) + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) optionalDependencies: - rollup: 4.60.2 + rollup: 4.62.0 transitivePeerDependencies: - supports-color - '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.2)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.62.0)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.2) + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.12 optionalDependencies: - rollup: 4.60.2 + rollup: 4.62.0 - '@rollup/plugin-replace@6.0.3(rollup@4.60.2)': + '@rollup/plugin-replace@6.0.3(rollup@4.62.0)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.2) + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) magic-string: 0.30.21 optionalDependencies: - rollup: 4.60.2 + rollup: 4.62.0 - '@rollup/plugin-terser@1.0.0(rollup@4.60.2)': + '@rollup/plugin-terser@1.0.0(rollup@4.62.0)': dependencies: serialize-javascript: 7.0.5 smob: 1.6.2 terser: 5.48.0 optionalDependencies: - rollup: 4.60.2 + rollup: 4.62.0 - '@rollup/pluginutils@5.4.0(rollup@4.60.2)': + '@rollup/pluginutils@5.4.0(rollup@4.62.0)': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.4 optionalDependencies: - rollup: 4.60.2 + rollup: 4.62.0 '@rollup/rollup-android-arm-eabi@4.60.2': optional: true + '@rollup/rollup-android-arm-eabi@4.62.0': + optional: true + '@rollup/rollup-android-arm64@4.60.2': optional: true + '@rollup/rollup-android-arm64@4.62.0': + optional: true + '@rollup/rollup-darwin-arm64@4.60.2': optional: true + '@rollup/rollup-darwin-arm64@4.62.0': + optional: true + '@rollup/rollup-darwin-x64@4.60.2': optional: true + '@rollup/rollup-darwin-x64@4.62.0': + optional: true + '@rollup/rollup-freebsd-arm64@4.60.2': optional: true + '@rollup/rollup-freebsd-arm64@4.62.0': + optional: true + '@rollup/rollup-freebsd-x64@4.60.2': optional: true + '@rollup/rollup-freebsd-x64@4.62.0': + optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.62.0': + optional: true + '@rollup/rollup-linux-arm-musleabihf@4.60.2': optional: true + '@rollup/rollup-linux-arm-musleabihf@4.62.0': + optional: true + '@rollup/rollup-linux-arm64-gnu@4.60.2': optional: true + '@rollup/rollup-linux-arm64-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-arm64-musl@4.60.2': optional: true + '@rollup/rollup-linux-arm64-musl@4.62.0': + optional: true + '@rollup/rollup-linux-loong64-gnu@4.60.2': optional: true + '@rollup/rollup-linux-loong64-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-loong64-musl@4.60.2': optional: true + '@rollup/rollup-linux-loong64-musl@4.62.0': + optional: true + '@rollup/rollup-linux-ppc64-gnu@4.60.2': optional: true + '@rollup/rollup-linux-ppc64-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-ppc64-musl@4.60.2': optional: true + '@rollup/rollup-linux-ppc64-musl@4.62.0': + optional: true + '@rollup/rollup-linux-riscv64-gnu@4.60.2': optional: true + '@rollup/rollup-linux-riscv64-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-riscv64-musl@4.60.2': optional: true + '@rollup/rollup-linux-riscv64-musl@4.62.0': + optional: true + '@rollup/rollup-linux-s390x-gnu@4.60.2': optional: true + '@rollup/rollup-linux-s390x-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-x64-gnu@4.60.2': optional: true + '@rollup/rollup-linux-x64-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-x64-musl@4.60.2': optional: true + '@rollup/rollup-linux-x64-musl@4.62.0': + optional: true + '@rollup/rollup-openbsd-x64@4.60.2': optional: true + '@rollup/rollup-openbsd-x64@4.62.0': + optional: true + '@rollup/rollup-openharmony-arm64@4.60.2': optional: true + '@rollup/rollup-openharmony-arm64@4.62.0': + optional: true + '@rollup/rollup-win32-arm64-msvc@4.60.2': optional: true + '@rollup/rollup-win32-arm64-msvc@4.62.0': + optional: true + '@rollup/rollup-win32-ia32-msvc@4.60.2': optional: true + '@rollup/rollup-win32-ia32-msvc@4.62.0': + optional: true + '@rollup/rollup-win32-x64-gnu@4.60.2': optional: true + '@rollup/rollup-win32-x64-gnu@4.62.0': + optional: true + '@rollup/rollup-win32-x64-msvc@4.60.2': optional: true + '@rollup/rollup-win32-x64-msvc@4.62.0': + optional: true + '@sentry-internal/browser-utils@10.50.0': dependencies: '@sentry/core': 10.50.0 @@ -9295,19 +10119,23 @@ snapshots: '@standard-schema/spec@1.1.0': {} + '@sveltejs/acorn-typescript@1.0.10(acorn@8.17.0)': + dependencies: + acorn: 8.17.0 + '@sveltejs/acorn-typescript@1.0.9(acorn@8.16.0)': dependencies: acorn: 8.16.0 - '@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0))': + '@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4))': dependencies: '@standard-schema/spec': 1.1.0 - '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)) + '@sveltejs/acorn-typescript': 1.0.10(acorn@8.17.0) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)) '@types/cookie': 0.6.0 - acorn: 8.16.0 + acorn: 8.17.0 cookie: 0.6.0 - devalue: 5.7.1 + devalue: 5.8.1 esm-env: 1.2.2 kleur: 4.1.5 magic-string: 0.30.21 @@ -9315,20 +10143,20 @@ snapshots: set-cookie-parser: 3.1.0 sirv: 3.0.2 svelte: 5.55.4(@typescript-eslint/types@8.58.2) - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4) optionalDependencies: '@opentelemetry/api': 1.9.1 typescript: 5.8.3 - '@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))': + '@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))': dependencies: '@standard-schema/spec': 1.1.0 - '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + '@sveltejs/acorn-typescript': 1.0.10(acorn@8.17.0) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) '@types/cookie': 0.6.0 - acorn: 8.16.0 + acorn: 8.17.0 cookie: 0.6.0 - devalue: 5.7.1 + devalue: 5.8.1 esm-env: 1.2.2 kleur: 4.1.5 magic-string: 0.30.21 @@ -9336,46 +10164,46 @@ snapshots: set-cookie-parser: 3.1.0 sirv: 3.0.2 svelte: 5.55.4(@typescript-eslint/types@8.58.2) - vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) optionalDependencies: '@opentelemetry/api': 1.9.1 typescript: 6.0.3 optional: true - '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)) obug: 2.1.1 svelte: 5.55.4(@typescript-eslint/types@8.58.2) - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4) - '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) obug: 2.1.1 svelte: 5.55.4(@typescript-eslint/types@8.58.2) - vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) optional: true - '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0))': + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 svelte: 5.55.4(@typescript-eslint/types@8.58.2) - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0) - vitefu: 1.1.3(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4) + vitefu: 1.1.3(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)) - '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))': + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 svelte: 5.55.4(@typescript-eslint/types@8.58.2) - vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) - vitefu: 1.1.3(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) + vitefu: 1.1.3(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) optional: true '@swc/core-darwin-arm64@1.15.33': @@ -9508,12 +10336,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 - '@tailwindcss/vite@4.2.2(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0))': + '@tailwindcss/vite@4.2.2(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4))': dependencies: '@tailwindcss/node': 4.2.2 '@tailwindcss/oxide': 4.2.2 tailwindcss: 4.2.2 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4) '@tauri-apps/cli-darwin-arm64@2.11.1': optional: true @@ -9573,22 +10401,22 @@ snapshots: '@tsconfig/svelte@5.0.8': {} - '@turbo/darwin-64@2.9.14': + '@turbo/darwin-64@2.9.18': optional: true - '@turbo/darwin-arm64@2.9.14': + '@turbo/darwin-arm64@2.9.18': optional: true - '@turbo/linux-64@2.9.14': + '@turbo/linux-64@2.9.18': optional: true - '@turbo/linux-arm64@2.9.14': + '@turbo/linux-arm64@2.9.18': optional: true - '@turbo/windows-64@2.9.14': + '@turbo/windows-64@2.9.18': optional: true - '@turbo/windows-arm64@2.9.14': + '@turbo/windows-arm64@2.9.18': optional: true '@tybys/wasm-util@0.10.1': @@ -9596,6 +10424,11 @@ snapshots: tslib: 2.8.1 optional: true + '@tybys/wasm-util@0.10.2': + dependencies: + tslib: 2.8.1 + optional: true + '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.2.0 @@ -9624,6 +10457,8 @@ snapshots: '@types/estree@1.0.8': {} + '@types/estree@1.0.9': {} + '@types/fs-extra@9.0.13': dependencies: '@types/node': 24.12.2 @@ -9902,16 +10737,16 @@ snapshots: valibot: 1.3.1(typescript@5.8.3) optional: true - '@vercel/analytics@2.0.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vue-router@4.6.4(vue@3.5.32(typescript@6.0.3)))(vue@3.5.32(typescript@6.0.3))': + '@vercel/analytics@2.0.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vue-router@4.6.4(vue@3.5.32(typescript@6.0.3)))(vue@3.5.32(typescript@6.0.3))': optionalDependencies: - '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) svelte: 5.55.4(@typescript-eslint/types@8.58.2) vue: 3.5.32(typescript@6.0.3) vue-router: 4.6.4(vue@3.5.32(typescript@6.0.3)) - '@vercel/speed-insights@2.0.0(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vue-router@4.6.4(vue@3.5.32(typescript@6.0.3)))(vue@3.5.32(typescript@6.0.3))': + '@vercel/speed-insights@2.0.0(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vue-router@4.6.4(vue@3.5.32(typescript@6.0.3)))(vue@3.5.32(typescript@6.0.3))': optionalDependencies: - '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) svelte: 5.55.4(@typescript-eslint/types@8.58.2) vue: 3.5.32(typescript@6.0.3) vue-router: 4.6.4(vue@3.5.32(typescript@6.0.3)) @@ -9933,10 +10768,10 @@ snapshots: validator: 13.15.35 optional: true - '@vitejs/plugin-vue@6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(vue@3.5.32(typescript@6.0.3))': + '@vitejs/plugin-vue@6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(vue@3.5.32(typescript@6.0.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.13 - vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) vue: 3.5.32(typescript@6.0.3) '@vitest/expect@4.1.4': @@ -9948,13 +10783,21 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.4(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))': + '@vitest/mocker@4.1.4(vite@8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))': dependencies: '@vitest/spy': 4.1.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + vite: 8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) + + '@vitest/mocker@4.1.4(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))': + dependencies: + '@vitest/spy': 4.1.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) '@vitest/pretty-format@4.1.4': dependencies: @@ -10085,6 +10928,8 @@ snapshots: acorn@8.16.0: {} + acorn@8.17.0: {} + agent-base@6.0.2: dependencies: debug: 4.4.3 @@ -10165,7 +11010,7 @@ snapshots: hosted-git-info: 4.1.0 is-ci: 3.0.1 isbinaryfile: 5.0.7 - js-yaml: 4.1.1 + js-yaml: 4.2.0 json5: 2.2.3 lazy-val: 1.0.5 minimatch: 10.2.5 @@ -10282,27 +11127,27 @@ snapshots: axobject-query@4.1.0: {} - babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.7): dependencies: '@babel/compat-data': 7.29.7 - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): + babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): + babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) transitivePeerDependencies: - supports-color @@ -10323,15 +11168,15 @@ snapshots: dependencies: file-uri-to-path: 1.0.0 - bits-ui@2.18.0(@internationalized/date@3.12.1)(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)): + bits-ui@2.18.0(@internationalized/date@3.12.1)(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)): dependencies: '@floating-ui/core': 1.7.5 '@floating-ui/dom': 1.7.6 '@internationalized/date': 3.12.1 esm-env: 1.2.2 - runed: 0.35.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) + runed: 0.35.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) svelte: 5.55.4(@typescript-eslint/types@8.58.2) - svelte-toolbelt: 0.10.6(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) + svelte-toolbelt: 0.10.6(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) tabbable: 6.4.0 transitivePeerDependencies: - '@sveltejs/kit' @@ -10424,7 +11269,7 @@ snapshots: http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-ci: 3.0.1 - js-yaml: 4.1.1 + js-yaml: 4.2.0 source-map-support: 0.5.21 stat-mode: 1.0.0 temp-file: 3.4.0 @@ -10731,6 +11576,8 @@ snapshots: devalue@5.7.1: {} + devalue@5.8.1: {} + dir-compare@4.2.0: dependencies: minimatch: 3.1.5 @@ -10746,7 +11593,7 @@ snapshots: builder-util-runtime: 9.2.10 fs-extra: 10.1.0 iconv-lite: 0.6.3 - js-yaml: 4.1.1 + js-yaml: 4.2.0 optionalDependencies: dmg-license: 1.0.11 transitivePeerDependencies: @@ -10838,7 +11685,7 @@ snapshots: electron-to-chromium@1.5.357: {} - electron-vite@6.0.0-beta.1(@swc/core@1.15.33(@swc/helpers@0.5.21))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)): + electron-vite@6.0.0-beta.1(@swc/core@1.15.33(@swc/helpers@0.5.21))(vite@8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)): dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) @@ -10846,7 +11693,7 @@ snapshots: esbuild: 0.25.12 magic-string: 0.30.21 picocolors: 1.1.1 - vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + vite: 8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) optionalDependencies: '@swc/core': 1.15.33(@swc/helpers@0.5.21) transitivePeerDependencies: @@ -10888,6 +11735,13 @@ snapshots: error-stack-parser-es@1.0.5: {} + es-abstract-get@1.0.0: + dependencies: + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + is-callable: 1.2.7 + object-inspect: 1.13.4 + es-abstract@1.24.2: dependencies: array-buffer-byte-length: 1.0.2 @@ -10902,8 +11756,8 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.1.2 es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 + es-to-primitive: 1.3.1 + function.prototype.name: 1.2.0 get-intrinsic: 1.3.0 get-proto: 1.0.1 get-symbol-description: 1.1.0 @@ -10912,7 +11766,7 @@ snapshots: has-property-descriptors: 1.0.2 has-proto: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.3 + hasown: 2.0.4 internal-slot: 1.1.0 is-array-buffer: 3.0.5 is-callable: 1.2.7 @@ -10966,8 +11820,10 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.3 - es-to-primitive@1.3.0: + es-to-primitive@1.3.1: dependencies: + es-abstract-get: 1.0.0 + es-errors: 1.3.0 is-callable: 1.2.7 is-date-object: 1.1.0 is-symbol: 1.1.1 @@ -11062,6 +11918,35 @@ 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: {} @@ -11385,11 +12270,11 @@ snapshots: hasown: 2.0.3 mime-types: 2.1.35 - formsnap@2.0.1(svelte@5.55.4(@typescript-eslint/types@8.58.2))(sveltekit-superforms@2.30.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(@types/json-schema@7.0.15)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)): + formsnap@2.0.1(svelte@5.55.4(@typescript-eslint/types@8.58.2))(sveltekit-superforms@2.30.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(@types/json-schema@7.0.15)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)): dependencies: svelte: 5.55.4(@typescript-eslint/types@8.58.2) svelte-toolbelt: 0.5.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) - sveltekit-superforms: 2.30.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(@types/json-schema@7.0.15)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3) + sveltekit-superforms: 2.30.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(@types/json-schema@7.0.15)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3) forwarded-parse@2.1.2: {} @@ -11435,14 +12320,17 @@ snapshots: function-bind@1.1.2: {} - function.prototype.name@1.1.8: + function.prototype.name@1.2.0: dependencies: call-bind: 1.0.9 call-bound: 1.0.4 - define-properties: 1.2.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 functions-have-names: 1.2.3 - hasown: 2.0.3 + has-property-descriptors: 1.0.2 + hasown: 2.0.4 is-callable: 1.2.7 + is-document.all: 1.0.0 functions-have-names@1.2.3: {} @@ -11595,6 +12483,10 @@ snapshots: dependencies: function-bind: 1.1.2 + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + highlight.js@11.11.1: {} hono@4.12.23: {} @@ -11714,8 +12606,8 @@ snapshots: internal-slot@1.1.0: dependencies: es-errors: 1.3.0 - hasown: 2.0.3 - side-channel: 1.1.0 + hasown: 2.0.4 + side-channel: 1.1.1 ip-address@10.2.0: {} @@ -11752,7 +12644,7 @@ snapshots: is-core-module@2.16.2: dependencies: - hasown: 2.0.3 + hasown: 2.0.4 is-data-view@1.0.2: dependencies: @@ -11765,6 +12657,10 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-document.all@1.0.0: + dependencies: + call-bound: 1.0.4 + is-extglob@2.1.1: {} is-finalizationregistry@1.1.1: @@ -11815,7 +12711,7 @@ snapshots: call-bound: 1.0.4 gopd: 1.2.0 has-tostringtag: 1.0.2 - hasown: 2.0.3 + hasown: 2.0.4 is-regexp@1.0.0: {} @@ -11896,7 +12792,7 @@ snapshots: js-tokens@4.0.0: {} - js-yaml@4.1.1: + js-yaml@4.2.0: dependencies: argparse: 2.0.1 @@ -12236,6 +13132,8 @@ snapshots: nanoid@3.3.11: {} + nanoid@3.3.12: {} + napi-build-utils@2.0.0: {} natural-compare@1.4.0: {} @@ -12494,6 +13392,12 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postcss@8.5.15: + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + postgres-array@2.0.0: {} postgres-bytea@1.0.1: {} @@ -12651,13 +13555,13 @@ snapshots: regenerate: 1.4.2 regenerate-unicode-properties: 10.2.2 regjsgen: 0.8.0 - regjsparser: 0.13.1 + regjsparser: 0.13.2 unicode-match-property-ecmascript: 2.0.0 unicode-match-property-value-ecmascript: 2.2.1 regjsgen@0.8.0: {} - regjsparser@0.13.1: + regjsparser@0.13.2: dependencies: jsesc: 3.1.0 @@ -12733,6 +13637,27 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15 + rolldown@1.0.3: + dependencies: + '@oxc-project/types': 0.133.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.3 + '@rolldown/binding-darwin-arm64': 1.0.3 + '@rolldown/binding-darwin-x64': 1.0.3 + '@rolldown/binding-freebsd-x64': 1.0.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 + '@rolldown/binding-linux-arm64-gnu': 1.0.3 + '@rolldown/binding-linux-arm64-musl': 1.0.3 + '@rolldown/binding-linux-ppc64-gnu': 1.0.3 + '@rolldown/binding-linux-s390x-gnu': 1.0.3 + '@rolldown/binding-linux-x64-gnu': 1.0.3 + '@rolldown/binding-linux-x64-musl': 1.0.3 + '@rolldown/binding-openharmony-arm64': 1.0.3 + '@rolldown/binding-wasm32-wasi': 1.0.3 + '@rolldown/binding-win32-arm64-msvc': 1.0.3 + '@rolldown/binding-win32-x64-msvc': 1.0.3 + rollup@4.60.2: dependencies: '@types/estree': 1.0.8 @@ -12764,6 +13689,37 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.60.2 fsevents: 2.3.3 + rollup@4.62.0: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.62.0 + '@rollup/rollup-android-arm64': 4.62.0 + '@rollup/rollup-darwin-arm64': 4.62.0 + '@rollup/rollup-darwin-x64': 4.62.0 + '@rollup/rollup-freebsd-arm64': 4.62.0 + '@rollup/rollup-freebsd-x64': 4.62.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.62.0 + '@rollup/rollup-linux-arm-musleabihf': 4.62.0 + '@rollup/rollup-linux-arm64-gnu': 4.62.0 + '@rollup/rollup-linux-arm64-musl': 4.62.0 + '@rollup/rollup-linux-loong64-gnu': 4.62.0 + '@rollup/rollup-linux-loong64-musl': 4.62.0 + '@rollup/rollup-linux-ppc64-gnu': 4.62.0 + '@rollup/rollup-linux-ppc64-musl': 4.62.0 + '@rollup/rollup-linux-riscv64-gnu': 4.62.0 + '@rollup/rollup-linux-riscv64-musl': 4.62.0 + '@rollup/rollup-linux-s390x-gnu': 4.62.0 + '@rollup/rollup-linux-x64-gnu': 4.62.0 + '@rollup/rollup-linux-x64-musl': 4.62.0 + '@rollup/rollup-openbsd-x64': 4.62.0 + '@rollup/rollup-openharmony-arm64': 4.62.0 + '@rollup/rollup-win32-arm64-msvc': 4.62.0 + '@rollup/rollup-win32-ia32-msvc': 4.62.0 + '@rollup/rollup-win32-x64-gnu': 4.62.0 + '@rollup/rollup-win32-x64-msvc': 4.62.0 + fsevents: 2.3.3 + router@2.2.0: dependencies: debug: 4.4.3 @@ -12774,14 +13730,14 @@ snapshots: transitivePeerDependencies: - supports-color - runed@0.35.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)): + runed@0.35.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)): dependencies: dequal: 2.0.3 esm-env: 1.2.2 lz-string: 1.5.0 svelte: 5.55.4(@typescript-eslint/types@8.58.2) optionalDependencies: - '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)) + '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)) sade@1.8.1: dependencies: @@ -12829,6 +13785,8 @@ snapshots: semver@7.7.4: {} + semver@7.8.4: {} + send@1.2.1: dependencies: debug: 4.4.3 @@ -12954,6 +13912,14 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -13073,7 +14039,7 @@ snapshots: internal-slot: 1.1.0 regexp.prototype.flags: 1.5.4 set-function-name: 2.0.2 - side-channel: 1.1.0 + side-channel: 1.1.1 string.prototype.trim@1.2.11: dependencies: @@ -13172,10 +14138,10 @@ snapshots: optionalDependencies: svelte: 5.55.4(@typescript-eslint/types@8.58.2) - svelte-toolbelt@0.10.6(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)): + svelte-toolbelt@0.10.6(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)): dependencies: clsx: 2.1.1 - runed: 0.35.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) + runed: 0.35.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) style-to-object: 1.0.14 svelte: 5.55.4(@typescript-eslint/types@8.58.2) transitivePeerDependencies: @@ -13208,9 +14174,9 @@ snapshots: transitivePeerDependencies: - '@typescript-eslint/types' - sveltekit-superforms@2.30.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(@types/json-schema@7.0.15)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3): + sveltekit-superforms@2.30.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(@types/json-schema@7.0.15)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3): dependencies: - '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)) + '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@5.8.3)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)) devalue: 5.7.1 memoize-weak: 1.0.2 svelte: 5.55.4(@typescript-eslint/types@8.58.2) @@ -13292,7 +14258,7 @@ snapshots: terser@5.48.0: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.16.0 + acorn: 8.17.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -13312,6 +14278,11 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + tinyrainbow@3.1.0: {} tmp-promise@3.0.3: @@ -13356,18 +14327,24 @@ snapshots: tslib@2.8.1: {} + tsx@4.22.4: + dependencies: + esbuild: 0.28.1 + optionalDependencies: + fsevents: 2.3.3 + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 - turbo@2.9.14: + turbo@2.9.18: optionalDependencies: - '@turbo/darwin-64': 2.9.14 - '@turbo/darwin-arm64': 2.9.14 - '@turbo/linux-64': 2.9.14 - '@turbo/linux-arm64': 2.9.14 - '@turbo/windows-64': 2.9.14 - '@turbo/windows-arm64': 2.9.14 + '@turbo/darwin-64': 2.9.18 + '@turbo/darwin-arm64': 2.9.18 + '@turbo/linux-64': 2.9.18 + '@turbo/linux-arm64': 2.9.18 + '@turbo/windows-64': 2.9.18 + '@turbo/windows-arm64': 2.9.18 tw-animate-css@1.4.0: {} @@ -13535,25 +14512,25 @@ snapshots: extsprintf: 1.4.1 optional: true - vite-plugin-pwa@1.3.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0))(workbox-build@7.4.1)(workbox-window@7.4.1): + vite-plugin-pwa@1.3.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4))(workbox-build@7.4.1)(workbox-window@7.4.1): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 tinyglobby: 0.2.16 - vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) workbox-build: 7.4.1 workbox-window: 7.4.1 transitivePeerDependencies: - supports-color - vite-plugin-singlefile@2.3.3(rollup@4.60.2)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)): + vite-plugin-singlefile@2.3.3(rollup@4.60.2)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)): dependencies: micromatch: 4.0.8 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4) optionalDependencies: rollup: 4.60.2 - vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0): + vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) @@ -13567,8 +14544,24 @@ snapshots: jiti: 2.6.1 lightningcss: 1.32.0 terser: 5.48.0 + tsx: 4.22.4 + + vite@8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.15 + rolldown: 1.0.3 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 24.12.2 + esbuild: 0.28.1 + fsevents: 2.3.3 + jiti: 2.6.1 + terser: 5.48.0 + tsx: 4.22.4 - vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0): + vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -13581,20 +14574,49 @@ snapshots: fsevents: 2.3.3 jiti: 2.6.1 terser: 5.48.0 + tsx: 4.22.4 - vitefu@1.1.3(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)): + vitefu@1.1.3(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4)): optionalDependencies: - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.22.4) - vitefu@1.1.3(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)): + vitefu@1.1.3(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)): optionalDependencies: - vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) optional: true - vitest@4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)): + vitest@4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)): + dependencies: + '@vitest/expect': 4.1.4 + '@vitest/mocker': 4.1.4(vite@8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) + '@vitest/pretty-format': 4.1.4 + '@vitest/runner': 4.1.4 + '@vitest/snapshot': 4.1.4 + '@vitest/spy': 4.1.4 + '@vitest/utils': 4.1.4 + es-module-lexer: 2.0.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.1.1 + tinyglobby: 0.2.16 + tinyrainbow: 3.1.0 + vite: 8.0.16(@types/node@24.12.2)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) + why-is-node-running: 2.3.0 + optionalDependencies: + '@opentelemetry/api': 1.9.1 + '@types/node': 24.12.2 + transitivePeerDependencies: + - msw + + vitest@4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)): dependencies: '@vitest/expect': 4.1.4 - '@vitest/mocker': 4.1.4(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)) + '@vitest/mocker': 4.1.4(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4)) '@vitest/pretty-format': 4.1.4 '@vitest/runner': 4.1.4 '@vitest/snapshot': 4.1.4 @@ -13611,7 +14633,7 @@ snapshots: tinyexec: 1.1.1 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 - vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0) + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.22.4) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 @@ -13638,7 +14660,7 @@ snapshots: eslint-visitor-keys: 5.0.1 espree: 11.2.0 esquery: 1.7.0 - semver: 7.7.4 + semver: 7.8.4 transitivePeerDependencies: - supports-color @@ -13709,7 +14731,7 @@ snapshots: which-builtin-type@1.2.1: dependencies: call-bound: 1.0.4 - function.prototype.name: 1.1.8 + function.prototype.name: 1.2.0 has-tostringtag: 1.0.2 is-async-function: 2.1.1 is-date-object: 1.1.0 @@ -13766,13 +14788,13 @@ snapshots: workbox-build@7.4.1: dependencies: '@apideck/better-ajv-errors': 0.3.7(ajv@8.20.0) - '@babel/core': 7.29.0 - '@babel/preset-env': 7.29.7(@babel/core@7.29.0) - '@babel/runtime': 7.29.2 - '@rollup/plugin-babel': 6.1.0(@babel/core@7.29.0)(rollup@4.60.2) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.2) - '@rollup/plugin-replace': 6.0.3(rollup@4.60.2) - '@rollup/plugin-terser': 1.0.0(rollup@4.60.2) + '@babel/core': 7.29.7 + '@babel/preset-env': 7.29.7(@babel/core@7.29.7) + '@babel/runtime': 7.29.7 + '@rollup/plugin-babel': 6.1.0(@babel/core@7.29.7)(rollup@4.62.0) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.62.0) + '@rollup/plugin-replace': 6.0.3(rollup@4.62.0) + '@rollup/plugin-terser': 1.0.0(rollup@4.62.0) '@trickfilm400/rollup-plugin-off-main-thread': 3.0.0-pre1 ajv: 8.20.0 common-tags: 1.8.2 @@ -13781,7 +14803,7 @@ snapshots: fs-extra: 9.1.0 glob: 11.1.0 pretty-bytes: 5.6.0 - rollup: 4.60.2 + rollup: 4.62.0 source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 diff --git a/wrangler.toml b/wrangler.toml index 7c382c4..693d799 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -1,5 +1,5 @@ name = "weblink" -compatibility_date = "2024-01-01" +compatibility_date = "2026-06-01" [pages] build_output_dir = "apps/web/dist"