diff --git a/.env.electron b/.env.electron new file mode 100644 index 0000000..dc3c541 --- /dev/null +++ b/.env.electron @@ -0,0 +1,25 @@ +# Electron 生产构建环境变量(vite build --mode electron 时加载) +# +# 为什么需要:打包后的桌面端以 file:// 协议运行,没有 Vite 开发代理, +# 相对路径 /api、/ws 无法到达后端,必须配置后端绝对地址。 +# 更换服务器地址后需要重新打包。 +# +# 注意:Electron 本地开发(npm run dev:electron,mode=electron-dev)不会加载本文件, +# 开发时仍走 Vite 代理连本地后端,与 Web 开发体验一致。 + +# HTTP API 基础地址 +VITE_API_BASE_URL=https://g-ws.nailaoyun.cn/api + +# WebSocket 完整地址(wsManager 优先使用该配置) +VITE_WS_URL=wss://g-ws.nailaoyun.cn/ws + +# 静态资源(uploads 附件/头像等)域名 +VITE_API_ORIGIN=https://g-ws.nailaoyun.cn + +# ---------- 本地测试打包(npm run build:electron:test)---------- +# TEST_ 前缀字段:electron-test 模式构建时会去掉前缀、替代上面的正式配置, +# 打出的包连接本地后端,用于不发服务器就验证桌面端完整功能。 +# 正式打包(npm run build:electron)不会读取这些字段,可放心保留。 +TEST_VITE_API_BASE_URL=http://localhost:12080/api +TEST_VITE_WS_URL=ws://localhost:12080/ws +TEST_VITE_API_ORIGIN=http://localhost:12080 diff --git a/.gitignore b/.gitignore index 3e00e6d..536177f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,10 @@ dist dist-ssr *.local +# Electron 构建产物 +dist-electron +release + # Editor directories and files .vscode/* !.vscode/extensions.json diff --git a/build/icon.ico b/build/icon.ico new file mode 100644 index 0000000..f8f26a5 Binary files /dev/null and b/build/icon.ico differ diff --git a/build/icon.png b/build/icon.png new file mode 100644 index 0000000..d3a9eed Binary files /dev/null and b/build/icon.png differ diff --git a/build/logo-master.png b/build/logo-master.png new file mode 100644 index 0000000..ed1b9a5 Binary files /dev/null and b/build/logo-master.png differ diff --git a/electron/main.ts b/electron/main.ts new file mode 100644 index 0000000..d0d8194 --- /dev/null +++ b/electron/main.ts @@ -0,0 +1,428 @@ +/** + * Electron 主进程入口 + * + * 职责: + * 1. 应用生命周期管理:单实例锁、开机自启参数(--hidden)、退出行为 + * 2. 主窗口创建与加载:开发环境加载 Vite Dev Server(代理仍生效),生产环境加载打包后的 dist/index.html + * 3. 桌面能力:系统托盘、任务栏未读角标/闪烁、系统通知、文件下载(另存为对话框)、外链跳系统浏览器 + * 4. 应用内更新:electron-updater,更新包托管在自有服务器 /updates 目录(generic provider) + * 5. 通过 IPC 与渲染进程通信(渲染层只能访问 preload 暴露的 electronAPI,保证安全边界) + */ +import { app, BrowserWindow, Tray, Menu, ipcMain, shell, session, Notification, nativeImage } from 'electron' +// electron-updater 是 CJS 包且用 getter 定义导出,ESM 下具名导入可能解析失败, +// 必须默认导入后再解构(Node ESM 对 CJS 的默认导入即 module.exports 对象) +import electronUpdater from 'electron-updater' +import path from 'node:path' +import fs from 'node:fs' +import { fileURLToPath } from 'node:url' + +const { autoUpdater } = electronUpdater + +// ==================== 基础路径与环境 ==================== + +// 主进程以 ESM 产物运行(项目 package.json 为 "type": "module"), +// ESM 中没有全局 __dirname,需从 import.meta.url 派生(指向 dist-electron 目录) +const __dirname = path.dirname(fileURLToPath(import.meta.url)) + +// vite-plugin-electron 开发模式下会注入 VITE_DEV_SERVER_URL,以此区分开发/生产 +const devServerUrl = process.env.VITE_DEV_SERVER_URL +const isDev = !!devServerUrl + +// 静态资源目录:开发环境用项目 public/,生产环境用打包进 asar 的 dist/ +const publicDir = isDev ? path.join(__dirname, '../public') : path.join(__dirname, '../dist') +const appIconPath = path.join(publicDir, 'icons/icon.png') +const trayIconPath = path.join(publicDir, 'icons/tray.png') + +// ==================== 应用设置(持久化到 userData 目录) ==================== + +/** 应用本地设置:目前只有"关闭窗口时最小化到托盘",后续可扩展 */ +interface AppSettings { + closeToTray: boolean +} + +const DEFAULT_SETTINGS: AppSettings = { closeToTray: true } +let appSettings: AppSettings = { ...DEFAULT_SETTINGS } + +/** 设置文件路径(userData 目录随安装用户隔离,卸载可选保留) */ +function settingsFilePath(): string { + return path.join(app.getPath('userData'), 'app-settings.json') +} + +/** 读取本地设置,文件不存在或损坏时回退默认值 */ +function loadSettings(): AppSettings { + try { + const raw = fs.readFileSync(settingsFilePath(), 'utf-8') + return { ...DEFAULT_SETTINGS, ...JSON.parse(raw) } + } catch { + return { ...DEFAULT_SETTINGS } + } +} + +/** 持久化设置(同步写,数据量极小) */ +function saveSettings(settings: AppSettings): void { + try { + fs.writeFileSync(settingsFilePath(), JSON.stringify(settings, null, 2), 'utf-8') + } catch (err) { + console.error('[main] 保存设置失败:', err) + } +} + +// ==================== 窗口与托盘 ==================== + +let mainWindow: BrowserWindow | null = null +let tray: Tray | null = null +// 标记应用是否处于"真正退出"流程(托盘退出/安装更新时置 true,绕过关闭最小化逻辑) +let isQuitting = false +// 开机自启时带上 --hidden 参数:静默启动到托盘,不弹出主窗口打扰用户 +const startHidden = process.argv.includes('--hidden') + +/** 创建主窗口 */ +function createMainWindow(): void { + mainWindow = new BrowserWindow({ + width: 1280, + height: 800, + minWidth: 960, + minHeight: 600, + show: false, // 等 ready-to-show 再显示,避免加载过程白屏闪烁 + autoHideMenuBar: true, + backgroundColor: '#0f172a', // 与前端深色主题一致,减少启动闪白 + icon: nativeImage.createFromPath(appIconPath), + webPreferences: { + preload: path.join(__dirname, 'preload.cjs'), + // 安全基线:开启上下文隔离、禁用渲染进程 Node 能力, + // 渲染层只能通过 preload 的 contextBridge 访问受控 API + contextIsolation: true, + nodeIntegration: false, + }, + }) + + // 首帧渲染完成后再显示;开机自启(--hidden)时不显示,直接驻留托盘 + mainWindow.once('ready-to-show', () => { + if (!startHidden) { + mainWindow?.show() + } + }) + + if (isDev) { + mainWindow.loadURL(devServerUrl!) + mainWindow.webContents.openDevTools({ mode: 'detach' }) + } else { + // 生产环境加载打包产物;渲染层使用 hash 路由,file:// 协议下可正常工作 + mainWindow.loadFile(path.join(__dirname, '../dist/index.html')) + } + + // 外链(如消息里的 URL 卡片 window.open)交给系统默认浏览器打开,不在应用内新开窗口 + mainWindow.webContents.setWindowOpenHandler(({ url }) => { + if (/^https?:\/\//i.test(url)) { + shell.openExternal(url) + } + return { action: 'deny' } + }) + + // 安全兜底:阻止页面内导航到应用之外的地址(钓鱼链接/异常跳转),外部 http(s) 转交系统浏览器 + mainWindow.webContents.on('will-navigate', (event, url) => { + const isInternal = isDev ? url.startsWith(devServerUrl!) : url.startsWith('file:') + if (!isInternal) { + event.preventDefault() + if (/^https?:\/\//i.test(url)) { + shell.openExternal(url) + } + } + }) + + // 窗口获得焦点时停止任务栏闪烁(配合新消息 flashFrame 提醒) + mainWindow.on('focus', () => { + mainWindow?.flashFrame(false) + }) + + // 关闭行为:默认最小化到托盘(IM 常驻习惯),可在设置中改为直接退出 + mainWindow.on('close', (event) => { + if (!isQuitting && appSettings.closeToTray) { + event.preventDefault() + mainWindow?.hide() + } + }) + + mainWindow.on('closed', () => { + mainWindow = null + }) + + // F12 切换开发者工具(打包后保留,便于现场排查问题;应用菜单已移除,需手动注册按键) + mainWindow.webContents.on('before-input-event', (_event, input) => { + if (input.type === 'keyDown' && input.key === 'F12') { + mainWindow?.webContents.toggleDevTools() + } + }) +} + +/** 显示并聚焦主窗口(托盘点击/通知点击/二次启动共用) */ +function showMainWindow(): void { + if (!mainWindow) { + createMainWindow() + return + } + if (mainWindow.isMinimized()) { + mainWindow.restore() + } + mainWindow.show() + mainWindow.focus() +} + +/** 创建系统托盘:单击/双击显示主界面,右键菜单提供退出入口 */ +function createTray(): void { + tray = new Tray(nativeImage.createFromPath(trayIconPath)) + tray.setToolTip('NL-IM 即时通讯') + tray.setContextMenu( + Menu.buildFromTemplate([ + { label: '显示主界面', click: showMainWindow }, + { type: 'separator' }, + { + label: '退出', + click: () => { + isQuitting = true + app.quit() + }, + }, + ]) + ) + tray.on('click', showMainWindow) + tray.on('double-click', showMainWindow) +} + +// ==================== 权限控制 ==================== + +// 渲染层需要的权限白名单:音视频通话/语音消息(media)、系统通知、全屏播放、剪贴板 +const ALLOWED_PERMISSIONS = new Set([ + 'media', + 'notifications', + 'fullscreen', + 'clipboard-sanitized-write', + 'clipboard-read', + 'pointerLock', +]) + +/** 按白名单放行页面权限请求(getUserMedia、Notification 等),其余一律拒绝 */ +function setupPermissions(): void { + session.defaultSession.setPermissionRequestHandler((_webContents, permission, callback) => { + callback(ALLOWED_PERMISSIONS.has(permission)) + }) + session.defaultSession.setPermissionCheckHandler((_webContents, permission) => { + return ALLOWED_PERMISSIONS.has(permission) + }) +} + +// ==================== 文件下载 ==================== + +// 渲染层发起下载时记录期望文件名,用于 will-download 时设置"另存为"默认名 +// (file:// 环境下 跨域会失效,所以统一走主进程下载)。 +// 用 URL→文件名 的 Map 而不是单变量:用户连续下载多个文件时, +// 单变量会被后一次调用覆盖,导致"另存为"默认名错乱或落到错误条目上 +const pendingDownloadNames = new Map() + +/** 注册下载相关 IPC 与 will-download 处理:弹系统"另存为"对话框,完成后通知渲染层 */ +function setupDownloads(): void { + ipcMain.handle('download:start', (_event, url: string, fileName: string) => { + if (typeof url !== 'string' || !/^https?:\/\//i.test(url)) { + return + } + if (typeof fileName === 'string' && fileName) { + pendingDownloadNames.set(url, fileName) + } + mainWindow?.webContents.downloadURL(url) + }) + + session.defaultSession.on('will-download', (_event, item) => { + // 用重定向前的原始 URL(URLChain 首项)匹配发起时登记的文件名,用完即删 + const originURL = item.getURLChain()[0] || item.getURL() + const fileName = pendingDownloadNames.get(originURL) || item.getFilename() || `download_${Date.now()}` + pendingDownloadNames.delete(originURL) + // 弹出系统保存对话框,默认定位到系统"下载"目录 + item.setSaveDialogOptions({ + title: '保存文件', + defaultPath: path.join(app.getPath('downloads'), fileName), + }) + item.once('done', (_ev, state) => { + // state: completed=成功 / cancelled=用户取消 / interrupted=失败 + mainWindow?.webContents.send('download:done', { + state, + fileName, + savePath: state === 'completed' ? item.getSavePath() : '', + }) + }) + }) + + // "打开所在文件夹":下载完成 toast 的快捷操作 + ipcMain.handle('shell:show-item-in-folder', (_event, fullPath: string) => { + if (typeof fullPath === 'string' && fullPath) { + shell.showItemInFolder(fullPath) + } + }) +} + +// ==================== 应用内更新(electron-updater) ==================== + +/** + * 更新流程说明: + * - 更新源由 electron-builder 的 publish(generic) 配置决定,指向自有服务器 /updates 目录 + * - autoDownload 关闭:发现新版本后由用户在设置弹窗中确认再下载(避免流量/打扰) + * - 下载完成后用户可"立即重启安装",或退出应用时自动安装(autoInstallOnAppQuit) + */ +function setupUpdater(): void { + autoUpdater.autoDownload = false + autoUpdater.autoInstallOnAppQuit = true + + /** 统一向渲染层推送更新状态(设置弹窗/侧边栏红点据此展示) */ + const sendStatus = (payload: Record): void => { + mainWindow?.webContents.send('updater:status', payload) + } + + autoUpdater.on('checking-for-update', () => sendStatus({ type: 'checking' })) + autoUpdater.on('update-available', (info) => sendStatus({ type: 'available', version: info.version })) + autoUpdater.on('update-not-available', () => sendStatus({ type: 'not-available' })) + autoUpdater.on('download-progress', (progress) => + sendStatus({ + type: 'downloading', + percent: progress.percent, + bytesPerSecond: progress.bytesPerSecond, + transferred: progress.transferred, + total: progress.total, + }) + ) + autoUpdater.on('update-downloaded', (info) => sendStatus({ type: 'downloaded', version: info.version })) + autoUpdater.on('error', (err) => sendStatus({ type: 'error', message: err?.message || String(err) })) + + ipcMain.handle('updater:check', () => { + // 开发模式没有安装包上下文,electron-updater 无法工作,直接告知渲染层 + if (!app.isPackaged) { + sendStatus({ type: 'dev' }) + return + } + // 错误已通过 error 事件上报,这里 catch 避免未处理的 Promise 拒绝 + autoUpdater.checkForUpdates().catch(() => {}) + }) + + ipcMain.handle('updater:download', () => { + autoUpdater.downloadUpdate().catch(() => {}) + }) + + ipcMain.handle('updater:install', () => { + // 置退出标记,绕过"关闭最小化到托盘"逻辑,否则 quitAndInstall 会被 close 拦截 + isQuitting = true + autoUpdater.quitAndInstall() + }) +} + +// ==================== 其余 IPC(通知/角标/自启/设置) ==================== + +/** 注册通用 IPC 处理器 */ +function setupIpc(): void { + // 应用版本号(设置弹窗"关于"区块展示) + ipcMain.handle('app:get-version', () => app.getVersion()) + + // 聚焦主窗口(渲染层可主动调用,如点击应用内横幅) + ipcMain.handle('win:focus', () => showMainWindow()) + + // 系统通知:点击通知聚焦主窗口。silent=true 是因为渲染层已有自己的提示音,避免双重响铃 + ipcMain.handle('app:notify', (_event, options: { title?: string; body?: string }) => { + if (!Notification.isSupported()) { + return + } + const notification = new Notification({ + title: options?.title || 'NL-IM', + body: options?.body || '', + icon: nativeImage.createFromPath(appIconPath), + silent: true, + }) + notification.on('click', showMainWindow) + notification.show() + }) + + // 任务栏未读角标:主进程没有 DOM/Canvas,角标图由渲染层 canvas 生成后以 dataURL 传入 + ipcMain.handle('win:set-badge', (_event, count: number, dataURL: string) => { + if (!mainWindow) { + return + } + if (count > 0 && dataURL) { + mainWindow.setOverlayIcon(nativeImage.createFromDataURL(dataURL), `${count} 条未读消息`) + } else { + mainWindow.setOverlayIcon(null, '') + } + }) + + // 任务栏闪烁:仅窗口未聚焦时闪烁,聚焦后由 focus 事件自动取消 + ipcMain.handle('win:flash', () => { + if (mainWindow && !mainWindow.isFocused()) { + mainWindow.flashFrame(true) + } + }) + + // 开机自启查询/设置。开发模式 no-op:否则会把 electron.exe 写进系统自启项,污染开发机 + ipcMain.handle('app:get-auto-launch', () => { + if (!app.isPackaged) { + return false + } + return app.getLoginItemSettings().openAtLogin + }) + ipcMain.handle('app:set-auto-launch', (_event, enable: boolean) => { + if (!app.isPackaged) { + return false + } + // --hidden:开机自启时静默启动到托盘,不弹主窗口 + app.setLoginItemSettings({ openAtLogin: !!enable, args: enable ? ['--hidden'] : [] }) + return app.getLoginItemSettings().openAtLogin + }) + + // 应用设置读写(closeToTray 等) + ipcMain.handle('app:get-settings', () => appSettings) + ipcMain.handle('app:set-settings', (_event, patch: Partial) => { + appSettings = { ...appSettings, ...patch } + saveSettings(appSettings) + return appSettings + }) +} + +// ==================== 应用启动引导 ==================== + +// 单实例锁:IM 应用不允许多开,二次启动时聚焦已有窗口 +if (!app.requestSingleInstanceLock()) { + app.quit() +} else { + app.on('second-instance', showMainWindow) + + // Windows 通知归属标识,必须与 electron-builder 的 appId 一致,否则系统通知不显示应用名/图标 + app.setAppUserModelId('cn.nailaoyun.nlim') + + // 移除默认应用菜单(File/Edit/View...),IM 客户端不需要 + Menu.setApplicationMenu(null) + + app.whenReady().then(() => { + appSettings = loadSettings() + setupPermissions() + setupIpc() + setupDownloads() + setupUpdater() + createMainWindow() + createTray() + }) + + // 托盘退出/系统关机等触发退出前,置标记绕过关闭拦截 + app.on('before-quit', () => { + isQuitting = true + }) + + // 所有窗口关闭即退出(closeToTray 开启时 close 会被拦截为隐藏,不会走到这里) + app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit() + } + }) + + // macOS Dock 图标点击时恢复窗口(预留跨平台行为) + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createMainWindow() + } else { + showMainWindow() + } + }) +} diff --git a/electron/preload.ts b/electron/preload.ts new file mode 100644 index 0000000..9f06bec --- /dev/null +++ b/electron/preload.ts @@ -0,0 +1,79 @@ +/** + * Electron 预加载脚本 + * + * 作用:在上下文隔离(contextIsolation)环境下,通过 contextBridge 向渲染进程暴露 + * 受控的桌面能力 API(window.electronAPI)。渲染进程无法直接访问 Node/Electron, + * 只能调用这里明确列出的方法,保证安全边界。 + * + * 渲染层对应的类型声明见 src/types/electron.d.ts(两边需保持同步)。 + */ +import { contextBridge, ipcRenderer } from 'electron' +import type { IpcRendererEvent } from 'electron' + +/** 订阅主进程事件的通用封装:返回取消订阅函数,方便组件卸载时清理 */ +function subscribe(channel: string, callback: (payload: T) => void): () => void { + const listener = (_event: IpcRendererEvent, payload: T) => callback(payload) + ipcRenderer.on(channel, listener) + return () => { + ipcRenderer.removeListener(channel, listener) + } +} + +const electronAPI = { + /** 当前运行平台(win32/darwin/linux),渲染层可用于平台差异化处理 */ + platform: process.platform, + + // ---------- 应用信息 ---------- + /** 获取应用版本号(package.json version,设置弹窗展示用) */ + getVersion: (): Promise => ipcRenderer.invoke('app:get-version'), + + // ---------- 窗口 ---------- + /** 显示并聚焦主窗口 */ + focusWindow: (): Promise => ipcRenderer.invoke('win:focus'), + /** 设置任务栏未读角标;count=0 清除。角标图片由渲染层 canvas 生成(主进程无 DOM) */ + setBadge: (count: number, dataURL?: string): Promise => + ipcRenderer.invoke('win:set-badge', count, dataURL || ''), + /** 请求任务栏闪烁提醒(仅窗口未聚焦时生效,聚焦后自动停止) */ + flashFrame: (): Promise => ipcRenderer.invoke('win:flash'), + + // ---------- 系统通知 ---------- + /** 发送系统级通知(点击通知会显示并聚焦主窗口) */ + notify: (options: { title: string; body: string }): Promise => + ipcRenderer.invoke('app:notify', options), + + // ---------- 开机自启与应用设置 ---------- + /** 查询是否已设置开机自启 */ + getAutoLaunch: (): Promise => ipcRenderer.invoke('app:get-auto-launch'), + /** 设置开机自启,返回设置后的实际状态 */ + setAutoLaunch: (enable: boolean): Promise => ipcRenderer.invoke('app:set-auto-launch', enable), + /** 读取应用本地设置(closeToTray 等) */ + getAppSettings: (): Promise<{ closeToTray: boolean }> => ipcRenderer.invoke('app:get-settings'), + /** 增量更新应用本地设置,返回更新后的完整设置 */ + setAppSettings: (patch: Partial<{ closeToTray: boolean }>): Promise<{ closeToTray: boolean }> => + ipcRenderer.invoke('app:set-settings', patch), + + // ---------- 文件下载 ---------- + /** 下载文件:走主进程弹系统"另存为"对话框(file:// 下 跨域失效的替代方案) */ + downloadFile: (url: string, fileName: string): Promise => + ipcRenderer.invoke('download:start', url, fileName), + /** 订阅下载完成事件(state: completed/cancelled/interrupted),返回取消订阅函数 */ + onDownloadDone: ( + callback: (payload: { state: string; fileName: string; savePath: string }) => void + ): (() => void) => subscribe('download:done', callback), + /** 在系统文件管理器中显示指定文件(下载完成 toast 的"打开文件夹"操作) */ + showItemInFolder: (fullPath: string): Promise => + ipcRenderer.invoke('shell:show-item-in-folder', fullPath), + + // ---------- 应用内更新 ---------- + /** 检查更新(结果通过 onUpdateStatus 推送) */ + checkForUpdate: (): Promise => ipcRenderer.invoke('updater:check'), + /** 开始下载更新包(进度通过 onUpdateStatus 推送) */ + downloadUpdate: (): Promise => ipcRenderer.invoke('updater:download'), + /** 退出并安装已下载的更新 */ + quitAndInstall: (): Promise => ipcRenderer.invoke('updater:install'), + /** 订阅更新状态事件(checking/available/not-available/downloading/downloaded/error/dev) */ + onUpdateStatus: (callback: (payload: Record) => void): (() => void) => + subscribe('updater:status', callback), +} + +contextBridge.exposeInMainWorld('electronAPI', electronAPI) diff --git a/index.html b/index.html index 3365b07..f0bbdfd 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + NL-IM 即时通讯系统 diff --git a/package.json b/package.json index 1aa5d10..9b7ab66 100644 --- a/package.json +++ b/package.json @@ -1,30 +1,80 @@ { "name": "nl-im-vue-ts", "version": "1.0.0", + "description": "NL-IM 即时通讯 PC 客户端", + "author": "NL-IM Team", "type": "module", + "main": "dist-electron/main.mjs", "scripts": { "dev": "vite", "build": "vue-tsc && vite build", - "preview": "vite preview" - }, - "dependencies": { - "@ant-design/icons-vue": "^7.0.0", - "@fortawesome/fontawesome-free": "^7.1.0", - "axios": "^1.6.0", - "flv.js": "^1.6.2", - "pinia": "^2.1.0", - "vue": "^3.4.0", - "vue-router": "^4.2.0" + "preview": "vite preview", + "dev:electron": "vite --mode electron-dev", + "build:electron": "vite build --mode electron && electron-builder", + "build:electron:test": "vite build --mode electron-test && electron-builder --dir", + "icons": "node scripts/generate-icons.mjs" }, "devDependencies": { + "@ant-design/icons-vue": "^7.0.0", + "@fortawesome/fontawesome-free": "^7.1.0", + "@types/node": "^26.2.0", "@vitejs/plugin-vue": "^5.0.0", "@vueuse/core": "^10.7.0", "autoprefixer": "^10.4.0", + "axios": "^1.6.0", + "electron": "^43.3.0", + "electron-builder": "^26.15.3", + "flv.js": "^1.6.2", + "pinia": "^2.1.0", "postcss": "^8.4.0", "sass": "^1.94.2", "tailwindcss": "^3.4.18", "typescript": "^5.3.3", "vite": "^5.0.0", + "vite-plugin-electron": "^1.1.1", + "vue": "^3.4.0", + "vue-router": "^4.2.0", "vue-tsc": "^1.8.8" + }, + "build": { + "appId": "cn.nailaoyun.nlim", + "productName": "NL-IM", + "asar": true, + "directories": { + "output": "release", + "buildResources": "build" + }, + "files": [ + "dist/**", + "dist-electron/**" + ], + "win": { + "icon": "build/icon.ico", + "target": [ + { + "target": "nsis", + "arch": [ + "x64" + ] + } + ], + "artifactName": "${productName}-Setup-${version}.${ext}" + }, + "nsis": { + "oneClick": false, + "perMachine": false, + "allowToChangeInstallationDirectory": true, + "createDesktopShortcut": true, + "createStartMenuShortcut": true + }, + "publish": [ + { + "provider": "generic", + "url": "https://g-ws.nailaoyun.cn/updates/" + } + ] + }, + "dependencies": { + "electron-updater": "^6.8.9" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 879fd10..b560de3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,37 +8,43 @@ importers: .: dependencies: + electron-updater: + specifier: ^6.8.9 + version: 6.8.9(supports-color@7.2.0) + devDependencies: '@ant-design/icons-vue': specifier: ^7.0.0 version: 7.0.1(vue@3.5.25(typescript@5.3.3)) '@fortawesome/fontawesome-free': specifier: ^7.1.0 version: 7.1.0 - axios: - specifier: ^1.6.0 - version: 1.13.2 - flv.js: - specifier: ^1.6.2 - version: 1.6.2 - pinia: - specifier: ^2.1.0 - version: 2.3.1(typescript@5.3.3)(vue@3.5.25(typescript@5.3.3)) - vue: - specifier: ^3.4.0 - version: 3.5.25(typescript@5.3.3) - vue-router: - specifier: ^4.2.0 - version: 4.6.3(vue@3.5.25(typescript@5.3.3)) - devDependencies: + '@types/node': + specifier: ^26.2.0 + version: 26.2.0 '@vitejs/plugin-vue': specifier: ^5.0.0 - version: 5.2.4(vite@5.4.21(lightningcss@1.30.2)(sass@1.94.2))(vue@3.5.25(typescript@5.3.3)) + version: 5.2.4(vite@5.4.21(@types/node@26.2.0)(lightningcss@1.30.2)(sass@1.94.2))(vue@3.5.25(typescript@5.3.3)) '@vueuse/core': specifier: ^10.7.0 version: 10.11.1(vue@3.5.25(typescript@5.3.3)) autoprefixer: specifier: ^10.4.0 version: 10.4.22(postcss@8.5.6) + axios: + specifier: ^1.6.0 + version: 1.13.2(debug@4.4.3(supports-color@7.2.0)) + electron: + specifier: ^43.3.0 + version: 43.3.0(supports-color@7.2.0) + electron-builder: + specifier: ^26.15.3 + version: 26.15.3(electron-builder-squirrel-windows@26.15.3)(supports-color@7.2.0) + flv.js: + specifier: ^1.6.2 + version: 1.6.2 + pinia: + specifier: ^2.1.0 + version: 2.3.1(typescript@5.3.3)(vue@3.5.25(typescript@5.3.3)) postcss: specifier: ^8.4.0 version: 8.5.6 @@ -53,7 +59,16 @@ importers: version: 5.3.3 vite: specifier: ^5.0.0 - version: 5.4.21(lightningcss@1.30.2)(sass@1.94.2) + version: 5.4.21(@types/node@26.2.0)(lightningcss@1.30.2)(sass@1.94.2) + vite-plugin-electron: + specifier: ^1.1.1 + version: 1.1.1 + vue: + specifier: ^3.4.0 + version: 3.5.25(typescript@5.3.3) + vue-router: + specifier: ^4.2.0 + version: 4.6.3(vue@3.5.25(typescript@5.3.3)) vue-tsc: specifier: ^1.8.8 version: 1.8.8(typescript@5.3.3) @@ -96,6 +111,50 @@ packages: resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} engines: {node: '>=10'} + '@electron-internal/extract-zip@1.0.5': + resolution: {integrity: sha512-+bqFCP98pLI0Tt0XQo1TmlXtwjWchISndDOxCkEcIuUgXWpBnLyRI+2DU+mesvnMMX6L1XDqYNA0lXNDHd/yiA==} + engines: {node: '>=22.12.0'} + + '@electron/asar@3.4.1': + resolution: {integrity: sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==} + engines: {node: '>=10.12.0'} + hasBin: true + + '@electron/fuses@1.8.0': + resolution: {integrity: sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==} + hasBin: true + + '@electron/get@3.1.0': + resolution: {integrity: sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==} + engines: {node: '>=14'} + + '@electron/get@5.1.0': + resolution: {integrity: sha512-3kSBtG8ObcTVfXanm5vVJ6UnBLEVmVsRk1M+vGqCuMBV+XLCbJYuWQful+yIy0GQDsSlK0kHEriEHn7SPk4EnA==} + engines: {node: '>=22.12.0'} + + '@electron/notarize@2.5.0': + resolution: {integrity: sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==} + engines: {node: '>= 10.0.0'} + + '@electron/osx-sign@1.3.3': + resolution: {integrity: sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==} + engines: {node: '>=12.0.0'} + hasBin: true + + '@electron/rebuild@4.2.0': + resolution: {integrity: sha512-RKL/O+jGoXJMxrx/5771y1n0xTKmFuOYGO3gMmwypBM6rsH0kou0mswwdXA2JrhIkE4xyC7v9vGk0n6NPzgOxQ==} + engines: {node: '>=22.12.0'} + hasBin: true + + '@electron/universal@2.0.3': + resolution: {integrity: sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==} + engines: {node: '>=16.4'} + + '@electron/windows-sign@1.2.2': + resolution: {integrity: sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==} + engines: {node: '>=14.14'} + hasBin: true + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -238,6 +297,10 @@ packages: resolution: {integrity: sha512-+WxNld5ZCJHvPQCr/GnzCTVREyStrAJjisUPtUxG5ngDA8TMlPnKp6dddlTpai4+1GNmltAeuk1hJEkBohwZYA==} engines: {node: '>=6'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -251,6 +314,22 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@malept/cross-spawn-promise@2.0.0': + resolution: {integrity: sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==} + engines: {node: '>= 12.13.0'} + + '@malept/flatpak-bundler@0.4.0': + resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} + engines: {node: '>= 10.0.0'} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/hashes@2.3.0': + resolution: {integrity: sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==} + engines: {node: '>= 20.19.0'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -351,6 +430,20 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} + '@peculiar/asn1-schema@2.8.0': + resolution: {integrity: sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q==} + + '@peculiar/json-schema@1.1.12': + resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==} + engines: {node: '>=8.0.0'} + + '@peculiar/utils@2.0.3': + resolution: {integrity: sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==} + + '@peculiar/webcrypto@1.7.1': + resolution: {integrity: sha512-ODOov0sGMJMf3jPonOkgGqPknTsu+DdQ7kD++gz8aI+aFMOMHFbWAA2taqXXVTdP+OTOQR/znGvSpmkeI0WTYQ==} + engines: {node: '>=14.18.0'} + '@rollup/rollup-android-arm-eabi@4.53.3': resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} cpu: [arm] @@ -472,9 +565,44 @@ packages: cpu: [x64] os: [win32] + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + + '@types/cacheable-request@6.0.3': + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/fs-extra@9.0.13': + resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} + + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} + + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@24.13.3': + resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} + + '@types/node@26.2.0': + resolution: {integrity: sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==} + + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + '@types/web-bluetooth@0.0.20': resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} @@ -493,6 +621,11 @@ packages: '@volar/typescript@1.10.10': resolution: {integrity: sha512-4a2r5bdUub2m+mYVnLu2wt59fuoYWe7nf0uXtGHU8QQ5LDNfzAR0wK7NgDiQ9rcl2WT3fxT2AA9AylAwFtj50A==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true '@vue/compiler-core@3.5.25': resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} @@ -546,6 +679,34 @@ packages: '@vueuse/shared@10.11.1': resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} + '@xmldom/xmldom@0.8.13': + resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==} + engines: {node: '>=10.0.0'} + + abbrev@4.0.0: + resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==} + engines: {node: ^20.17.0 || >=22.9.0} + + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -553,12 +714,37 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + app-builder-lib@26.15.3: + resolution: {integrity: sha512-2VnyWkqsP5v5XbBhL3tD5Syx8iNPBYsoU7kY4S2fz7wg8Rj/nztWKCUzGKaFRTv0Xwf3/H058CR1Kvtd/3lRow==} + engines: {node: '>=14.0.0'} + peerDependencies: + dmg-builder: 26.15.3 + electron-builder-squirrel-windows: 26.15.3 + arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + asn1js@3.0.10: + resolution: {integrity: sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==} + engines: {node: '>=12.0.0'} + + async-exit-hook@2.0.1: + resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==} + engines: {node: '>=0.12.0'} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + autoprefixer@10.4.22: resolution: {integrity: sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==} engines: {node: ^10 || ^12 || >=14} @@ -566,12 +752,22 @@ packages: peerDependencies: postcss: ^8.1.0 + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + axios@1.13.2: resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.8.32: resolution: {integrity: sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==} hasBin: true @@ -580,9 +776,23 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + boolean@3.2.0: + resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + brace-expansion@1.1.18: + resolution: {integrity: sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==} + brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.9: + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + engines: {node: 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -592,6 +802,29 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + builder-util-runtime@9.7.0: + resolution: {integrity: sha512-g/kR520giAFYkSXTzcmF3kqQq7wi8F6N6SzeDgZrqTBN+VHdmgWOyTdD1yD7AATDId/yXLvuP34CxW46/BwCdw==} + engines: {node: '>=12.0.0'} + + builder-util@26.15.3: + resolution: {integrity: sha512-q2hn7Mbo2nFNkVekPiHFx6Nfo3hURmES3tfBn+k5Pqxl2RkmP3QGqZUhH/q9Pch/4G05NRhPjDlVj1O8q4Txvw==} + engines: {node: '>=14.0.0'} + + bytestreamjs@2.0.1: + resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} + engines: {node: '>=6.0.0'} + + cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + + cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -603,6 +836,10 @@ packages: caniuse-lite@1.0.30001757: resolution: {integrity: sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -611,6 +848,35 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + chromium-pickle-js@0.2.0: + resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==} + + ci-info@4.3.1: + resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} + engines: {node: '>=8'} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -619,6 +885,37 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + + compare-version@0.1.2: + resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==} + engines: {node: '>=0.10.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cross-dirname@0.1.0: + resolution: {integrity: sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -630,6 +927,31 @@ packages: de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -643,23 +965,88 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + dir-compare@4.2.0: + resolution: {integrity: sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==} + dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dmg-builder@26.15.3: + resolution: {integrity: sha512-O3zJUFUYHJKgzPqioHxfxzBzlSC1eXCSr79gMSBKBP5AgjjpmrydMsMLotEg9fAJF36vdUncb+4ndRNxoPdlSQ==} + + dotenv-expand@11.0.7: + resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} + engines: {node: '>=12'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-builder-squirrel-windows@26.15.3: + resolution: {integrity: sha512-Jc19XPV9y9+2bAdZPkXuVNGNIEFBq9poHC61l8Kv6FdK7DRG3+Ic0rerC0DXOaeHNz8yW0fg/JnF8GQROOF5MA==} + + electron-builder@26.15.3: + resolution: {integrity: sha512-a1KM5heqS3gQCZzizXEI8RjJy3QVogULPdeSknt76uLDpBIW/HDGsMg/XgP0riP6PI9COsRvFITKKGDqA8fJxA==} + engines: {node: '>=14.0.0'} + hasBin: true + + electron-publish@26.15.3: + resolution: {integrity: sha512-g/2bn8YTavY4cuS5F+jOS7zmZbXXBV8KZ8yHKfJjFPoKtzBqrpCdNPxBd3tqdBwP7BVd0lGzf7Bk2s0KesWZ4Q==} + electron-to-chromium@1.5.263: resolution: {integrity: sha512-DrqJ11Knd+lo+dv+lltvfMDLU27g14LMdH2b0O3Pio4uk0x+z7OR+JrmyacTPN2M8w3BrZ7/RTwG3R9B7irPlg==} + electron-updater@6.8.9: + resolution: {integrity: sha512-ZhVxM9iGONUpZGI1FxdMRgJjUFXi7AYGVa5PwKlO1tV1/4zDxQmfKpXOHVztKrd6L9rLcFjERvi1Mf2vxyTkig==} + + electron-winstaller@5.4.0: + resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} + engines: {node: '>=8.0.0'} + + electron@43.3.0: + resolution: {integrity: sha512-nLlvu0WFjftWsSaTkV2B/c4NDuJBspTyXu8vKSQ6vLvFt8uG3NgN49LLKcXddwX0GqVvAQDhciWp+4xOdTdhew==} + engines: {node: '>= 22.12.0'} + hasBin: true + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -676,6 +1063,9 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} + es6-error@4.1.1: + resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + es6-promise@4.2.8: resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} @@ -688,13 +1078,29 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + + exsolve@1.1.1: + resolution: {integrity: sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} + fast-uri@3.1.5: + resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} + fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -707,6 +1113,9 @@ packages: picomatch: optional: true + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -730,6 +1139,33 @@ packages: fraction.js@5.3.4: resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@11.3.1: + resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==} + engines: {node: '>=14.14'} + + fs-extra@11.4.0: + resolution: {integrity: sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==} + engines: {node: '>=14.14'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -738,6 +1174,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -746,6 +1186,10 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -754,10 +1198,36 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + global-agent@3.0.0: + resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} + engines: {node: '>=10.0'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} @@ -774,9 +1244,35 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + immutable@5.1.4: resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -789,6 +1285,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -797,10 +1297,71 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isbinaryfile@4.0.10: + resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} + engines: {node: '>= 8.0.0'} + + isbinaryfile@5.0.7: + resolution: {integrity: sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==} + engines: {node: '>= 18.0.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@3.1.5: + resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} + engines: {node: '>=18'} + + isexe@4.0.0: + resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} + engines: {node: '>=20'} + + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + engines: {node: '>=10'} + hasBin: true + jiti@1.21.7: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + js-yaml@4.3.1: + resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.2.1: + resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + lazy-val@1.0.5: + resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==} + lightningcss-android-arm64@1.30.2: resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} engines: {node: '>= 12.0.0'} @@ -882,9 +1443,35 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + local-pkg@1.2.1: + resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} + engines: {node: '>=14'} + + lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + matcher@3.0.0: + resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} + engines: {node: '>=10'} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -905,10 +1492,55 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + muggle-string@0.3.1: resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} @@ -920,12 +1552,32 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + node-abi@4.33.0: + resolution: {integrity: sha512-vLBWCKb+7LWsX+TbfzWOkw0W81m377tyx3hOweBTjO43CXZnRGS1/JPWs20fr0PgZyDXk6ROYrylsEycK8raDA==} + engines: {node: '>=22.12.0'} + node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + node-api-version@0.2.1: + resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==} + + node-gyp@12.4.0: + resolution: {integrity: sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + nopt@9.0.0: + resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -934,6 +1586,10 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -942,12 +1598,42 @@ packages: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pe-library@0.4.1: + resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==} + engines: {node: '>=12', npm: '>=6'} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -976,6 +1662,20 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.3.1: + resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==} + + pkijs@3.4.0: + resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} + engines: {node: '>=16.0.0'} + + plist@3.1.0: + resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} + engines: {node: '>=10.4.0'} + postcss-import@15.1.0: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} @@ -1023,15 +1723,62 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + postject@1.0.0-alpha.6: + resolution: {integrity: sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==} + engines: {node: '>=14.0.0'} + hasBin: true + + proc-log@6.1.0: + resolution: {integrity: sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.2.0: + resolution: {integrity: sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==} + engines: {node: '>=16.0.0'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + read-binary-file-arch@1.0.6: + resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} + hasBin: true + read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -1040,15 +1787,46 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resedit@1.7.2: + resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==} + engines: {node: '>=12', npm: '>=6'} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + resolve@1.22.11: resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} hasBin: true + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rimraf@2.6.3: + resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + roarr@2.15.4: + resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} + engines: {node: '>=8.0'} + rollup@4.53.3: resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -1057,25 +1835,98 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + sanitize-filename@1.6.4: + resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==} + sass@1.94.2: resolution: {integrity: sha512-N+7WK20/wOr7CzA2snJcUSSNTCzeCGUTFY3OgeQP3mZ1aj9NMQ0mSTXwlrnd89j33zzQJGqIN52GIOmYrfq46A==} engines: {node: '>=14.0.0'} hasBin: true + sax@1.6.1: + resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} + engines: {node: '>=11.0.0'} + + semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true + serialize-error@7.0.1: + resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} + engines: {node: '>=10'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + stat-mode@1.0.0: + resolution: {integrity: sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==} + engines: {node: '>= 6'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + sucrase@3.35.1: resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true + sumchecker@3.0.1: + resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} + engines: {node: '>= 8.0'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -1085,6 +1936,17 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + tar@7.5.22: + resolution: {integrity: sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==} + engines: {node: '>=18'} + + temp-file@3.4.0: + resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==} + + temp@0.9.4: + resolution: {integrity: sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==} + engines: {node: '>=6.0.0'} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -1092,31 +1954,93 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tiny-async-pool@1.3.0: + resolution: {integrity: sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==} + + tiny-typed-emitter@2.1.0: + resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tmp-promise@3.0.3: + resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} + + tmp@0.2.7: + resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} + engines: {node: '>=14.14'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + truncate-utf8-bytes@1.0.2: + resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} + ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-fest@0.13.1: + resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} + engines: {node: '>=10'} + typescript@5.3.3: resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} engines: {node: '>=14.17'} hasBin: true + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + + undici@6.28.0: + resolution: {integrity: sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==} + engines: {node: '>=18.17'} + + undici@7.29.0: + resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==} + engines: {node: '>=20.18.1'} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unzipper@0.12.5: + resolution: {integrity: sha512-tXYOi9R57Uj/2Z25SOs5RRSzq886MBQj2gY8dPL+xl/kv6s6SvByoKfAtvfVeEuhntWDgjd2o9p2lb4TVPAz0A==} + update-browserslist-db@1.1.4: resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' + utf8-byte-length@1.0.5: + resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + vite-plugin-electron@1.1.1: + resolution: {integrity: sha512-qvfiA20hQiQydIzPIhMgH9ZmqPHh7uVGfI76pK8TVOIYJyhaqpsHrMNwa7OmKpUXYFffXwOIZ4zL0Vprb4KP8Q==} + peerDependencies: + vite-plugin-electron-renderer: '*' + peerDependenciesMeta: + vite-plugin-electron-renderer: + optional: true + vite@5.4.21: resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1181,9 +2105,61 @@ packages: typescript: optional: true + webcrypto-core@1.9.2: + resolution: {integrity: sha512-gsXecm82UQNlTBURJGuqOWy1Ww08S3kZUcr3aOJS02Pk0xLtkfeUAVC0u0xhgdonFme80edSJUIJyuvL/7250Q==} + webworkify-webpack@2.1.5: resolution: {integrity: sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw==} + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + which@6.0.1: + resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + xmlbuilder@15.1.1: + resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} + engines: {node: '>=8.0'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.3: + resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -1215,6 +2191,100 @@ snapshots: '@ctrl/tinycolor@3.6.1': {} + '@electron-internal/extract-zip@1.0.5': {} + + '@electron/asar@3.4.1': + dependencies: + commander: 5.1.0 + glob: 7.2.3 + minimatch: 3.1.5 + + '@electron/fuses@1.8.0': + dependencies: + chalk: 4.1.2 + fs-extra: 9.1.0 + minimist: 1.2.8 + + '@electron/get@3.1.0(supports-color@7.2.0)': + dependencies: + debug: 4.4.3(supports-color@7.2.0) + env-paths: 2.2.1 + fs-extra: 8.1.0 + got: 11.8.6 + progress: 2.0.3 + semver: 6.3.1 + sumchecker: 3.0.1(supports-color@7.2.0) + optionalDependencies: + global-agent: 3.0.0 + transitivePeerDependencies: + - supports-color + + '@electron/get@5.1.0(supports-color@7.2.0)': + dependencies: + debug: 4.4.3(supports-color@7.2.0) + env-paths: 3.0.0 + graceful-fs: 4.2.11 + progress: 2.0.3 + semver: 7.7.3 + sumchecker: 3.0.1(supports-color@7.2.0) + optionalDependencies: + undici: 7.29.0 + transitivePeerDependencies: + - supports-color + + '@electron/notarize@2.5.0(supports-color@7.2.0)': + dependencies: + debug: 4.4.3(supports-color@7.2.0) + fs-extra: 9.1.0 + promise-retry: 2.0.1 + transitivePeerDependencies: + - supports-color + + '@electron/osx-sign@1.3.3(supports-color@7.2.0)': + dependencies: + compare-version: 0.1.2 + debug: 4.4.3(supports-color@7.2.0) + fs-extra: 10.1.0 + isbinaryfile: 4.0.10 + minimist: 1.2.8 + plist: 3.1.0 + transitivePeerDependencies: + - supports-color + + '@electron/rebuild@4.2.0(supports-color@7.2.0)': + dependencies: + '@malept/cross-spawn-promise': 2.0.0 + debug: 4.4.3(supports-color@7.2.0) + node-abi: 4.33.0 + node-api-version: 0.2.1 + node-gyp: 12.4.0 + read-binary-file-arch: 1.0.6(supports-color@7.2.0) + transitivePeerDependencies: + - supports-color + + '@electron/universal@2.0.3(supports-color@7.2.0)': + dependencies: + '@electron/asar': 3.4.1 + '@malept/cross-spawn-promise': 2.0.0 + debug: 4.4.3(supports-color@7.2.0) + dir-compare: 4.2.0 + fs-extra: 11.4.0 + minimatch: 9.0.5 + plist: 3.1.0 + transitivePeerDependencies: + - supports-color + + '@electron/windows-sign@1.2.2(supports-color@7.2.0)': + dependencies: + cross-dirname: 0.1.0 + debug: 4.4.3(supports-color@7.2.0) + fs-extra: 11.4.0 + minimist: 1.2.8 + postject: 1.0.0-alpha.6 + transitivePeerDependencies: + - supports-color + optional: true + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -1286,6 +2356,10 @@ snapshots: '@fortawesome/fontawesome-free@7.1.0': {} + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.3 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -1300,6 +2374,23 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@malept/cross-spawn-promise@2.0.0': + dependencies: + cross-spawn: 7.0.6 + + '@malept/flatpak-bundler@0.4.0(supports-color@7.2.0)': + dependencies: + debug: 4.4.3(supports-color@7.2.0) + fs-extra: 9.1.0 + lodash: 4.18.1 + tmp-promise: 3.0.3 + transitivePeerDependencies: + - supports-color + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@2.3.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1373,6 +2464,28 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.1 optional: true + '@peculiar/asn1-schema@2.8.0': + dependencies: + '@peculiar/utils': 2.0.3 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/json-schema@1.1.12': + dependencies: + tslib: 2.8.1 + + '@peculiar/utils@2.0.3': + dependencies: + tslib: 2.8.1 + + '@peculiar/webcrypto@1.7.1': + dependencies: + '@peculiar/asn1-schema': 2.8.0 + '@peculiar/json-schema': 1.1.12 + '@peculiar/utils': 2.0.3 + tslib: 2.8.1 + webcrypto-core: 1.9.2 + '@rollup/rollup-android-arm-eabi@4.53.3': optional: true @@ -1439,13 +2552,54 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.53.3': optional: true + '@sindresorhus/is@4.6.0': {} + + '@szmarczak/http-timer@4.0.6': + dependencies: + defer-to-connect: 2.0.1 + + '@types/cacheable-request@6.0.3': + dependencies: + '@types/http-cache-semantics': 4.2.0 + '@types/keyv': 3.1.4 + '@types/node': 26.2.0 + '@types/responselike': 1.0.3 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/estree@1.0.8': {} + '@types/fs-extra@9.0.13': + dependencies: + '@types/node': 26.2.0 + + '@types/http-cache-semantics@4.2.0': {} + + '@types/keyv@3.1.4': + dependencies: + '@types/node': 26.2.0 + + '@types/ms@2.1.0': {} + + '@types/node@24.13.3': + dependencies: + undici-types: 7.18.2 + + '@types/node@26.2.0': + dependencies: + undici-types: 8.3.0 + + '@types/responselike@1.0.3': + dependencies: + '@types/node': 26.2.0 + '@types/web-bluetooth@0.0.20': {} - '@vitejs/plugin-vue@5.2.4(vite@5.4.21(lightningcss@1.30.2)(sass@1.94.2))(vue@3.5.25(typescript@5.3.3))': + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@26.2.0)(lightningcss@1.30.2)(sass@1.94.2))(vue@3.5.25(typescript@5.3.3))': dependencies: - vite: 5.4.21(lightningcss@1.30.2)(sass@1.94.2) + vite: 5.4.21(@types/node@26.2.0)(lightningcss@1.30.2)(sass@1.94.2) vue: 3.5.25(typescript@5.3.3) '@volar/language-core@1.10.10': @@ -1456,10 +2610,12 @@ snapshots: dependencies: muggle-string: 0.3.1 - '@volar/typescript@1.10.10': + '@volar/typescript@1.10.10(typescript@5.3.3)': dependencies: '@volar/language-core': 1.10.10 path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.3.3 '@vue/compiler-core@3.5.25': dependencies: @@ -1532,7 +2688,7 @@ snapshots: '@vue/typescript@1.8.8(typescript@5.3.3)': dependencies: - '@volar/typescript': 1.10.10 + '@volar/typescript': 1.10.10(typescript@5.3.3) '@vue/language-core': 1.8.8(typescript@5.3.3) transitivePeerDependencies: - typescript @@ -1556,6 +2712,27 @@ snapshots: - '@vue/composition-api' - vue + '@xmldom/xmldom@0.8.13': {} + + abbrev@4.0.0: {} + + acorn@8.18.0: {} + + agent-base@7.1.4: {} + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.5 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + any-promise@1.3.0: {} anymatch@3.1.3: @@ -1563,10 +2740,72 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + app-builder-lib@26.15.3(dmg-builder@26.15.3)(electron-builder-squirrel-windows@26.15.3)(supports-color@7.2.0): + dependencies: + '@electron/asar': 3.4.1 + '@electron/fuses': 1.8.0 + '@electron/get': 3.1.0(supports-color@7.2.0) + '@electron/notarize': 2.5.0(supports-color@7.2.0) + '@electron/osx-sign': 1.3.3(supports-color@7.2.0) + '@electron/rebuild': 4.2.0(supports-color@7.2.0) + '@electron/universal': 2.0.3(supports-color@7.2.0) + '@malept/flatpak-bundler': 0.4.0(supports-color@7.2.0) + '@noble/hashes': 2.3.0 + '@peculiar/webcrypto': 1.7.1 + '@types/fs-extra': 9.0.13 + ajv: 8.20.0 + asn1js: 3.0.10 + async-exit-hook: 2.0.1 + builder-util: 26.15.3(supports-color@7.2.0) + builder-util-runtime: 9.7.0(supports-color@7.2.0) + chromium-pickle-js: 0.2.0 + ci-info: 4.3.1 + debug: 4.4.3(supports-color@7.2.0) + dmg-builder: 26.15.3(electron-builder-squirrel-windows@26.15.3)(supports-color@7.2.0) + dotenv: 16.6.1 + dotenv-expand: 11.0.7 + ejs: 3.1.10 + electron-builder-squirrel-windows: 26.15.3(dmg-builder@26.15.3)(supports-color@7.2.0) + electron-publish: 26.15.3(supports-color@7.2.0) + fs-extra: 10.1.0 + hosted-git-info: 4.1.0 + isbinaryfile: 5.0.7 + jiti: 2.7.0 + js-yaml: 4.3.1 + json5: 2.2.3 + lazy-val: 1.0.5 + minimatch: 10.2.6 + pkijs: 3.4.0 + plist: 3.1.0 + proper-lockfile: 4.1.2 + resedit: 1.7.2 + semver: 7.7.3 + tar: 7.5.22 + temp-file: 3.4.0 + tiny-async-pool: 1.3.0 + unzipper: 0.12.5 + which: 5.0.0 + transitivePeerDependencies: + - supports-color + arg@5.0.2: {} + argparse@2.0.1: {} + + asn1js@3.0.10: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.2.0 + tslib: 2.8.1 + + async-exit-hook@2.0.1: {} + + async@3.2.6: {} + asynckit@0.4.0: {} + at-least-node@1.0.0: {} + autoprefixer@10.4.22(postcss@8.5.6): dependencies: browserslist: 4.28.0 @@ -1577,9 +2816,11 @@ snapshots: postcss: 8.5.6 postcss-value-parser: 4.2.0 - axios@1.13.2: + aws4@1.13.2: {} + + axios@1.13.2(debug@4.4.3(supports-color@7.2.0)): dependencies: - follow-redirects: 1.15.11 + follow-redirects: 1.15.11(debug@4.4.3(supports-color@7.2.0)) form-data: 4.0.5 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -1587,14 +2828,32 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + + base64-js@1.5.1: {} + baseline-browser-mapping@2.8.32: {} binary-extensions@2.3.0: {} + bluebird@3.7.2: {} + + boolean@3.2.0: + optional: true + + brace-expansion@1.1.18: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.9: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -1607,6 +2866,48 @@ snapshots: node-releases: 2.0.27 update-browserslist-db: 1.1.4(browserslist@4.28.0) + buffer-from@1.1.2: {} + + builder-util-runtime@9.7.0(supports-color@7.2.0): + dependencies: + debug: 4.4.3(supports-color@7.2.0) + sax: 1.6.1 + transitivePeerDependencies: + - supports-color + + builder-util@26.15.3(supports-color@7.2.0): + dependencies: + '@types/debug': 4.1.13 + builder-util-runtime: 9.7.0(supports-color@7.2.0) + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3(supports-color@7.2.0) + fs-extra: 10.1.0 + http-proxy-agent: 7.0.2(supports-color@7.2.0) + https-proxy-agent: 7.0.6(supports-color@7.2.0) + js-yaml: 4.3.1 + sanitize-filename: 1.6.4 + source-map-support: 0.5.21 + stat-mode: 1.0.0 + temp-file: 3.4.0 + tiny-async-pool: 1.3.0 + transitivePeerDependencies: + - supports-color + + bytestreamjs@2.0.1: {} + + cacheable-lookup@5.0.4: {} + + cacheable-request@7.0.4: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -1616,6 +2917,11 @@ snapshots: caniuse-lite@1.0.30001757: {} + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -1632,18 +2938,92 @@ snapshots: dependencies: readdirp: 4.1.2 + chownr@3.0.0: {} + + chromium-pickle-js@0.2.0: {} + + ci-info@4.3.1: {} + + ci-info@4.4.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 commander@4.1.1: {} + commander@5.1.0: {} + + commander@9.5.0: + optional: true + + compare-version@0.1.2: {} + + concat-map@0.0.1: {} + + confbox@0.1.8: {} + + confbox@0.2.4: {} + + core-util-is@1.0.3: {} + + cross-dirname@0.1.0: + optional: true + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + cssesc@3.0.0: {} csstype@3.2.3: {} de-indent@1.0.2: {} + debug@4.4.3(supports-color@7.2.0): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 7.2.0 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + defer-to-connect@2.0.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + optional: true + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + optional: true + delayed-stream@1.0.0: {} detect-libc@1.0.3: @@ -1652,20 +3032,136 @@ snapshots: detect-libc@2.1.2: optional: true + detect-node@2.1.0: + optional: true + didyoumean@1.2.2: {} + dir-compare@4.2.0: + dependencies: + minimatch: 3.1.5 + p-limit: 3.1.0 + dlv@1.1.3: {} + dmg-builder@26.15.3(electron-builder-squirrel-windows@26.15.3)(supports-color@7.2.0): + dependencies: + app-builder-lib: 26.15.3(dmg-builder@26.15.3)(electron-builder-squirrel-windows@26.15.3)(supports-color@7.2.0) + builder-util: 26.15.3(supports-color@7.2.0) + fs-extra: 10.1.0 + js-yaml: 4.3.1 + transitivePeerDependencies: + - electron-builder-squirrel-windows + - supports-color + + dotenv-expand@11.0.7: + dependencies: + dotenv: 16.6.1 + + dotenv@16.6.1: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 es-errors: 1.3.0 gopd: 1.2.0 + duplexer2@0.1.4: + dependencies: + readable-stream: 2.3.8 + + ejs@3.1.10: + dependencies: + jake: 10.9.4 + + electron-builder-squirrel-windows@26.15.3(dmg-builder@26.15.3)(supports-color@7.2.0): + dependencies: + app-builder-lib: 26.15.3(dmg-builder@26.15.3)(electron-builder-squirrel-windows@26.15.3)(supports-color@7.2.0) + builder-util: 26.15.3(supports-color@7.2.0) + electron-winstaller: 5.4.0(supports-color@7.2.0) + transitivePeerDependencies: + - dmg-builder + - supports-color + + electron-builder@26.15.3(electron-builder-squirrel-windows@26.15.3)(supports-color@7.2.0): + dependencies: + app-builder-lib: 26.15.3(dmg-builder@26.15.3)(electron-builder-squirrel-windows@26.15.3)(supports-color@7.2.0) + builder-util: 26.15.3(supports-color@7.2.0) + builder-util-runtime: 9.7.0(supports-color@7.2.0) + chalk: 4.1.2 + ci-info: 4.4.0 + dmg-builder: 26.15.3(electron-builder-squirrel-windows@26.15.3)(supports-color@7.2.0) + fs-extra: 10.1.0 + lazy-val: 1.0.5 + simple-update-notifier: 2.0.0 + yargs: 17.7.3 + transitivePeerDependencies: + - electron-builder-squirrel-windows + - supports-color + + electron-publish@26.15.3(supports-color@7.2.0): + dependencies: + '@types/fs-extra': 9.0.13 + aws4: 1.13.2 + builder-util: 26.15.3(supports-color@7.2.0) + builder-util-runtime: 9.7.0(supports-color@7.2.0) + chalk: 4.1.2 + form-data: 4.0.5 + fs-extra: 10.1.0 + lazy-val: 1.0.5 + mime: 2.6.0 + transitivePeerDependencies: + - supports-color + electron-to-chromium@1.5.263: {} + electron-updater@6.8.9(supports-color@7.2.0): + dependencies: + builder-util-runtime: 9.7.0(supports-color@7.2.0) + fs-extra: 10.1.0 + js-yaml: 4.3.1 + lazy-val: 1.0.5 + lodash.escaperegexp: 4.1.2 + lodash.isequal: 4.5.0 + semver: 7.7.3 + tiny-typed-emitter: 2.1.0 + transitivePeerDependencies: + - supports-color + + electron-winstaller@5.4.0(supports-color@7.2.0): + dependencies: + '@electron/asar': 3.4.1 + debug: 4.4.3(supports-color@7.2.0) + fs-extra: 7.0.1 + lodash: 4.18.1 + temp: 0.9.4 + optionalDependencies: + '@electron/windows-sign': 1.2.2(supports-color@7.2.0) + transitivePeerDependencies: + - supports-color + + electron@43.3.0(supports-color@7.2.0): + dependencies: + '@electron-internal/extract-zip': 1.0.5 + '@electron/get': 5.1.0(supports-color@7.2.0) + '@types/node': 24.13.3 + transitivePeerDependencies: + - supports-color + + emoji-regex@8.0.0: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + entities@4.5.0: {} + env-paths@2.2.1: {} + + env-paths@3.0.0: {} + + err-code@2.0.3: {} + es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -1681,6 +3177,9 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + es6-error@4.1.1: + optional: true + es6-promise@4.2.8: {} esbuild@0.21.5: @@ -1711,8 +3210,17 @@ snapshots: escalade@3.2.0: {} + escape-string-regexp@4.0.0: + optional: true + estree-walker@2.0.2: {} + exponential-backoff@3.1.3: {} + + exsolve@1.1.1: {} + + fast-deep-equal@3.1.3: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1721,6 +3229,8 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-uri@3.1.5: {} + fastq@1.19.1: dependencies: reusify: 1.1.0 @@ -1729,6 +3239,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + filelist@1.0.6: + dependencies: + minimatch: 5.1.9 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -1738,7 +3252,9 @@ snapshots: es6-promise: 4.2.8 webworkify-webpack: 2.1.5 - follow-redirects@1.15.11: {} + follow-redirects@1.15.11(debug@4.4.3(supports-color@7.2.0)): + optionalDependencies: + debug: 4.4.3(supports-color@7.2.0) form-data@4.0.5: dependencies: @@ -1750,11 +3266,52 @@ snapshots: fraction.js@5.3.4: {} + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs-extra@11.3.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs-extra@11.4.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true function-bind@1.1.2: {} + get-caller-file@2.0.5: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -1773,6 +3330,10 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + get-stream@5.2.0: + dependencies: + pump: 3.0.4 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -1781,8 +3342,56 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + global-agent@3.0.0: + dependencies: + boolean: 3.2.0 + es6-error: 4.1.1 + matcher: 3.0.0 + roarr: 2.15.4 + semver: 7.7.3 + serialize-error: 7.0.1 + optional: true + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + optional: true + gopd@1.2.0: {} + got@11.8.6: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + + graceful-fs@4.2.11: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + optional: true + has-symbols@1.1.0: {} has-tostringtag@1.0.2: @@ -1795,8 +3404,40 @@ snapshots: he@1.2.0: {} + hosted-git-info@4.1.0: + dependencies: + lru-cache: 6.0.0 + + http-cache-semantics@4.2.0: {} + + http-proxy-agent@7.0.2(supports-color@7.2.0): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@7.2.0) + transitivePeerDependencies: + - supports-color + + http2-wrapper@1.0.3: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + https-proxy-agent@7.0.6(supports-color@7.2.0): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@7.2.0) + transitivePeerDependencies: + - supports-color + immutable@5.1.4: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -1807,14 +3448,65 @@ snapshots: is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 is-number@7.0.0: {} + isarray@1.0.0: {} + + isbinaryfile@4.0.10: {} + + isbinaryfile@5.0.7: {} + + isexe@2.0.0: {} + + isexe@3.1.5: {} + + isexe@4.0.0: {} + + jake@10.9.4: + dependencies: + async: 3.2.6 + filelist: 1.0.6 + picocolors: 1.1.1 + jiti@1.21.7: {} + jiti@2.7.0: {} + + js-yaml@4.3.1: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@1.0.0: {} + + json-stringify-safe@5.0.1: + optional: true + + json5@2.2.3: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@6.2.1: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + lazy-val@1.0.5: {} + lightningcss-android-arm64@1.30.2: optional: true @@ -1869,10 +3561,33 @@ snapshots: lines-and-columns@1.2.4: {} + local-pkg@1.2.1: + dependencies: + mlly: 1.8.2 + pkg-types: 2.3.1 + quansync: 0.2.11 + + lodash.escaperegexp@4.1.2: {} + + lodash.isequal@4.5.0: {} + + lodash@4.18.1: {} + + lowercase-keys@2.0.0: {} + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + matcher@3.0.0: + dependencies: + escape-string-regexp: 4.0.0 + optional: true + math-intrinsics@1.1.0: {} merge2@1.4.1: {} @@ -1888,10 +3603,49 @@ snapshots: dependencies: mime-db: 1.52.0 + mime@2.6.0: {} + + mimic-response@1.0.1: {} + + mimic-response@3.1.0: {} + + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.9 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.18 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.0.2 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.2 + minimist@1.2.8: {} + + minipass@7.1.3: {} + + minizlib@3.1.0: + dependencies: + minipass: 7.1.3 + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mlly@1.8.2: + dependencies: + acorn: 8.18.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.4 + + ms@2.1.3: {} + muggle-string@0.3.1: {} mz@2.7.0: @@ -1902,23 +3656,73 @@ snapshots: nanoid@3.3.11: {} + node-abi@4.33.0: + dependencies: + semver: 7.7.3 + node-addon-api@7.1.1: optional: true + node-api-version@0.2.1: + dependencies: + semver: 7.7.3 + + node-gyp@12.4.0: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + graceful-fs: 4.2.11 + nopt: 9.0.0 + proc-log: 6.1.0 + semver: 7.7.3 + tar: 7.5.22 + tinyglobby: 0.2.15 + undici: 6.28.0 + which: 6.0.1 + + node-int64@0.4.0: {} + node-releases@2.0.27: {} + nopt@9.0.0: + dependencies: + abbrev: 4.0.0 + normalize-path@3.0.0: {} normalize-range@0.1.2: {} + normalize-url@6.1.0: {} + object-assign@4.1.1: {} object-hash@3.0.0: {} + object-keys@1.1.1: + optional: true + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + p-cancelable@2.1.1: {} + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + path-browserify@1.0.1: {} + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + path-parse@1.0.7: {} + pathe@2.0.3: {} + + pe-library@0.4.1: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -1939,6 +3743,33 @@ snapshots: pirates@4.0.7: {} + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + pkg-types@2.3.1: + dependencies: + confbox: 0.2.4 + exsolve: 1.1.1 + pathe: 2.0.3 + + pkijs@3.4.0: + dependencies: + '@noble/hashes': 1.4.0 + asn1js: 3.0.10 + bytestreamjs: 2.0.1 + pvtsutils: 1.3.6 + pvutils: 1.2.0 + tslib: 2.8.1 + + plist@3.1.0: + dependencies: + '@xmldom/xmldom': 0.8.13 + base64-js: 1.5.1 + xmlbuilder: 15.1.1 + postcss-import@15.1.0(postcss@8.5.6): dependencies: postcss: 8.5.6 @@ -1976,28 +3807,111 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postject@1.0.0-alpha.6: + dependencies: + commander: 9.5.0 + optional: true + + proc-log@6.1.0: {} + + process-nextick-args@2.0.1: {} + + progress@2.0.3: {} + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + proxy-from-env@1.1.0: {} + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + + pvutils@1.2.0: {} + + quansync@0.2.11: {} + queue-microtask@1.2.3: {} + quick-lru@5.1.1: {} + + read-binary-file-arch@1.0.6(supports-color@7.2.0): + dependencies: + debug: 4.4.3(supports-color@7.2.0) + transitivePeerDependencies: + - supports-color + read-cache@1.0.0: dependencies: pify: 2.3.0 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 readdirp@4.1.2: {} + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + resedit@1.7.2: + dependencies: + pe-library: 0.4.1 + + resolve-alpn@1.2.1: {} + resolve@1.22.11: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + + retry@0.12.0: {} + reusify@1.1.0: {} + rimraf@2.6.3: + dependencies: + glob: 7.2.3 + + roarr@2.15.4: + dependencies: + boolean: 3.2.0 + detect-node: 2.1.0 + globalthis: 1.0.4 + json-stringify-safe: 5.0.1 + semver-compare: 1.0.0 + sprintf-js: 1.1.3 + optional: true + rollup@4.53.3: dependencies: '@types/estree': 1.0.8 @@ -2030,6 +3944,12 @@ snapshots: dependencies: queue-microtask: 1.2.3 + safe-buffer@5.1.2: {} + + sanitize-filename@1.6.4: + dependencies: + truncate-utf8-bytes: 1.0.2 + sass@1.94.2: dependencies: chokidar: 4.0.3 @@ -2038,10 +3958,62 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.5.1 + sax@1.6.1: {} + + semver-compare@1.0.0: + optional: true + + semver@5.7.2: {} + + semver@6.3.1: {} + semver@7.7.3: {} + serialize-error@7.0.1: + dependencies: + type-fest: 0.13.1 + optional: true + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@3.0.7: {} + + simple-update-notifier@2.0.0: + dependencies: + semver: 7.7.3 + source-map-js@1.2.1: {} + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + sprintf-js@1.1.3: + optional: true + + stat-mode@1.0.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -2052,6 +4024,16 @@ snapshots: tinyglobby: 0.2.15 ts-interface-checker: 0.1.13 + sumchecker@3.0.1(supports-color@7.2.0): + dependencies: + debug: 4.4.3(supports-color@7.2.0) + transitivePeerDependencies: + - supports-color + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} tailwindcss@3.4.18: @@ -2082,6 +4064,24 @@ snapshots: - tsx - yaml + tar@7.5.22: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.3 + minizlib: 3.1.0 + yallist: 5.0.0 + + temp-file@3.4.0: + dependencies: + async-exit-hook: 2.0.1 + fs-extra: 10.1.0 + + temp@0.9.4: + dependencies: + mkdirp: 0.5.6 + rimraf: 2.6.3 + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -2090,33 +4090,84 @@ snapshots: dependencies: any-promise: 1.3.0 + tiny-async-pool@1.3.0: + dependencies: + semver: 5.7.2 + + tiny-typed-emitter@2.1.0: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tmp-promise@3.0.3: + dependencies: + tmp: 0.2.7 + + tmp@0.2.7: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + truncate-utf8-bytes@1.0.2: + dependencies: + utf8-byte-length: 1.0.5 + ts-interface-checker@0.1.13: {} + tslib@2.8.1: {} + + type-fest@0.13.1: + optional: true + typescript@5.3.3: {} + ufo@1.6.4: {} + + undici-types@7.18.2: {} + + undici-types@8.3.0: {} + + undici@6.28.0: {} + + undici@7.29.0: + optional: true + + universalify@0.1.2: {} + + universalify@2.0.1: {} + + unzipper@0.12.5: + dependencies: + bluebird: 3.7.2 + duplexer2: 0.1.4 + fs-extra: 11.3.1 + graceful-fs: 4.2.11 + node-int64: 0.4.0 + update-browserslist-db@1.1.4(browserslist@4.28.0): dependencies: browserslist: 4.28.0 escalade: 3.2.0 picocolors: 1.1.1 + utf8-byte-length@1.0.5: {} + util-deprecate@1.0.2: {} - vite@5.4.21(lightningcss@1.30.2)(sass@1.94.2): + vite-plugin-electron@1.1.1: + dependencies: + local-pkg: 1.2.1 + + vite@5.4.21(@types/node@26.2.0)(lightningcss@1.30.2)(sass@1.94.2): dependencies: esbuild: 0.21.5 postcss: 8.5.6 rollup: 4.53.3 optionalDependencies: + '@types/node': 26.2.0 fsevents: 2.3.3 lightningcss: 1.30.2 sass: 1.94.2 @@ -2152,4 +4203,54 @@ snapshots: optionalDependencies: typescript: 5.3.3 + webcrypto-core@1.9.2: + dependencies: + '@peculiar/asn1-schema': 2.8.0 + '@peculiar/json-schema': 1.1.12 + '@peculiar/utils': 2.0.3 + asn1js: 3.0.10 + tslib: 2.8.1 + webworkify-webpack@2.1.5: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@5.0.0: + dependencies: + isexe: 3.1.5 + + which@6.0.1: + dependencies: + isexe: 4.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + xmlbuilder@15.1.1: {} + + y18n@5.0.8: {} + + yallist@4.0.0: {} + + yallist@5.0.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.3: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..87ba24e --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,17 @@ +# pnpm 项目级设置(pnpm 10+ 不再读取 package.json 的 pnpm 字段) +# +# allowBuilds:允许执行构建脚本的依赖白名单(pnpm 11 起替代 onlyBuiltDependencies)—— +# - electron:postinstall 下载运行时二进制,不放行则桌面端无法启动 +# - esbuild:postinstall 安装平台二进制,不放行则 Vite 构建不可用 +# - vue-demi / @parcel/watcher:@vueuse、sass 的运行时兼容与文件监听依赖 +# - electron-winstaller:electron-builder 的传递依赖 +allowBuilds: + electron: true + electron-winstaller: true + esbuild: true + vue-demi: true + '@parcel/watcher': true + +# 运行 pnpm run/exec 前不强制校验依赖状态 +# (避免历史安装记录的"跳过构建"状态导致所有 pnpm 命令被阻塞) +verifyDepsBeforeRun: false diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 0000000..8cc44d8 Binary files /dev/null and b/public/favicon.png differ diff --git a/public/icons/icon.png b/public/icons/icon.png new file mode 100644 index 0000000..d3a9eed Binary files /dev/null and b/public/icons/icon.png differ diff --git a/public/icons/tray.png b/public/icons/tray.png new file mode 100644 index 0000000..0d486c6 Binary files /dev/null and b/public/icons/tray.png differ diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..d3a9eed Binary files /dev/null and b/public/logo.png differ diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index 119d59b..0000000 --- a/public/vite.svg +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/scripts/cdp-screenshot.mjs b/scripts/cdp-screenshot.mjs new file mode 100644 index 0000000..c773784 --- /dev/null +++ b/scripts/cdp-screenshot.mjs @@ -0,0 +1,57 @@ +/** + * CDP 截屏小工具:连接正在运行的 Electron/Chromium 远程调试端口,截取页面渲染结果 + * 用途:打包后无头验证渲染层 UI(登录页 logo、页面是否白屏等),无需人工肉眼确认 + * 用法:node scripts/cdp-screenshot.mjs <输出png路径> + * 依赖:Node 22+(内置全局 WebSocket),无需安装任何包 + */ +import { writeFileSync } from 'node:fs' + +const port = process.argv[2] || '9223' +const outFile = process.argv[3] || 'screenshot.png' + +// 从调试端口拿到页面目标的 WebSocket 调试地址 +const targets = await (await fetch(`http://127.0.0.1:${port}/json/list`)).json() +const page = targets.find((t) => t.type === 'page') +if (!page) { + console.error('未找到 page 类型的调试目标') + process.exit(1) +} + +const ws = new WebSocket(page.webSocketDebuggerUrl) +let msgId = 0 +/** 发送 CDP 命令并等待对应 id 的响应 */ +function send(method, params = {}) { + const id = ++msgId + return new Promise((resolve, reject) => { + const onMessage = (event) => { + const data = JSON.parse(event.data) + if (data.id === id) { + ws.removeEventListener('message', onMessage) + data.error ? reject(new Error(data.error.message)) : resolve(data.result) + } + } + ws.addEventListener('message', onMessage) + ws.send(JSON.stringify({ id, method, params })) + }) +} + +ws.addEventListener('open', async () => { + try { + // 等一帧渲染稳定后截屏 + await send('Page.enable') + const { data } = await send('Page.captureScreenshot', { format: 'png' }) + writeFileSync(outFile, Buffer.from(data, 'base64')) + console.log(`截图已保存: ${outFile}`) + // 顺带收集页面控制台报错,辅助排查 + const { result } = await send('Runtime.evaluate', { + expression: 'document.title + " | " + location.hash', + returnByValue: true, + }) + console.log(`页面状态: ${result.value}`) + } catch (err) { + console.error('CDP 操作失败:', err.message) + process.exitCode = 1 + } finally { + ws.close() + } +}) diff --git a/scripts/generate-icons.mjs b/scripts/generate-icons.mjs new file mode 100644 index 0000000..03cdaf1 --- /dev/null +++ b/scripts/generate-icons.mjs @@ -0,0 +1,327 @@ +/** + * 全套 Logo/图标生成流水线(无第三方依赖,纯 Node 实现 PNG 解码、缩放、编码与 ICO 封装) + * + * 输入:build/logo-master.png(品牌主视觉源图,奶酪聊天气泡 + 年糕崽崽小猫,正方形大图) + * + * 输出(按用途划分): + * - build/icon.png 256 Electron 打包图标(png 备用) + * - build/icon.ico 16/24/32/48/64/128/256 多尺寸 Windows 图标(安装包/exe/快捷方式) + * - public/icons/icon.png 256 桌面端窗口图标 / 系统通知图标(主进程运行时读取) + * - public/icons/tray.png 32 桌面端系统托盘图标 + * - public/favicon.png 64 网站浏览器标签页图标 + * - public/logo.png 256 稳定 URL 的通用 logo(后台/外部页面可直接引用 /logo.png) + * - src/assets/logo.png 256 经 Vite 打包的应用内 logo(登录页、Web 通知图标) + * - ../nl-im-uniapp/src/static/logo.png 512 移动端 App 图标源图(HBuilderX 生成各尺寸时用,保留直角) + * + * 说明:除 uniapp 源图保留直角外,其余图标统一加 22% 圆角遮罩(带抗锯齿), + * 在任务栏/托盘/标签页中呈现现代应用图标观感。 + * + * 用法:node scripts/generate-icons.mjs(package.json 已配置 npm run icons) + * 更换品牌视觉时只需替换 build/logo-master.png 后重跑本脚本。 + */ +import { deflateSync, inflateSync } from 'node:zlib' +import { mkdirSync, writeFileSync, readFileSync, existsSync } from 'node:fs' +import { dirname, join, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' + +const projectRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..') +const masterFile = join(projectRoot, 'build', 'logo-master.png') + +// ---------- CRC32(PNG 块校验必需,Node zlib 没有直接暴露,自行实现查表版) ---------- +const CRC_TABLE = (() => { + const table = new Int32Array(256) + for (let n = 0; n < 256; n++) { + let c = n + for (let k = 0; k < 8; k++) { + c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1 + } + table[n] = c + } + return table +})() + +function crc32(buf) { + let c = -1 + for (let i = 0; i < buf.length; i++) { + c = CRC_TABLE[(c ^ buf[i]) & 0xff] ^ (c >>> 8) + } + return (c ^ -1) >>> 0 +} + +// ---------- PNG 解码(支持 8bit RGB/RGBA、非隔行,覆盖常见生成图格式) ---------- +/** 解码 PNG 为 RGBA 像素数据 */ +function decodePng(buf) { + const signature = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a] + for (let i = 0; i < 8; i++) { + if (buf[i] !== signature[i]) throw new Error('不是有效的 PNG 文件') + } + let pos = 8 + let width = 0 + let height = 0 + let bitDepth = 0 + let colorType = 0 + let interlace = 0 + const idatParts = [] + while (pos < buf.length) { + const len = buf.readUInt32BE(pos) + const type = buf.toString('ascii', pos + 4, pos + 8) + const data = buf.subarray(pos + 8, pos + 8 + len) + if (type === 'IHDR') { + width = data.readUInt32BE(0) + height = data.readUInt32BE(4) + bitDepth = data[8] + colorType = data[9] + interlace = data[12] + } else if (type === 'IDAT') { + idatParts.push(data) + } else if (type === 'IEND') { + break + } + pos += 12 + len + } + if (bitDepth !== 8 || (colorType !== 2 && colorType !== 6) || interlace !== 0) { + throw new Error(`暂不支持的 PNG 格式(bitDepth=${bitDepth} colorType=${colorType} interlace=${interlace}),请提供 8bit RGB/RGBA 非隔行 PNG`) + } + const bpp = colorType === 6 ? 4 : 3 + const stride = width * bpp + const raw = inflateSync(Buffer.concat(idatParts)) + const out = Buffer.alloc(width * height * 4) + // 每行首字节是滤波器类型,按 PNG 规范逐字节还原(Sub/Up/Average/Paeth) + let prevRow = Buffer.alloc(stride) + for (let y = 0; y < height; y++) { + const filter = raw[y * (stride + 1)] + const row = raw.subarray(y * (stride + 1) + 1, y * (stride + 1) + 1 + stride) + for (let i = 0; i < stride; i++) { + const a = i >= bpp ? row[i - bpp] : 0 // 左侧同通道 + const b = prevRow[i] // 上方 + const c = i >= bpp ? prevRow[i - bpp] : 0 // 左上 + let v = row[i] + switch (filter) { + case 0: + break + case 1: + v = (v + a) & 0xff + break + case 2: + v = (v + b) & 0xff + break + case 3: + v = (v + ((a + b) >> 1)) & 0xff + break + case 4: { + // Paeth 预测器:取最接近 p=a+b-c 的邻居 + const p = a + b - c + const pa = Math.abs(p - a) + const pb = Math.abs(p - b) + const pc = Math.abs(p - c) + const pr = pa <= pb && pa <= pc ? a : pb <= pc ? b : c + v = (v + pr) & 0xff + break + } + default: + throw new Error(`未知的 PNG 滤波器类型: ${filter}`) + } + row[i] = v + } + prevRow = row + for (let x = 0; x < width; x++) { + const si = x * bpp + const di = (y * width + x) * 4 + out[di] = row[si] + out[di + 1] = row[si + 1] + out[di + 2] = row[si + 2] + out[di + 3] = bpp === 4 ? row[si + 3] : 255 + } + } + return { width, height, data: out } +} + +// ---------- PNG 编码(8bit RGBA,无隔行扫描) ---------- +/** 组装一个 PNG 数据块:长度 + 类型 + 数据 + CRC */ +function pngChunk(type, data) { + const typeBuf = Buffer.from(type, 'ascii') + const lenBuf = Buffer.alloc(4) + lenBuf.writeUInt32BE(data.length) + const crcBuf = Buffer.alloc(4) + crcBuf.writeUInt32BE(crc32(Buffer.concat([typeBuf, data]))) + return Buffer.concat([lenBuf, typeBuf, data, crcBuf]) +} + +/** 将 RGBA 像素数据编码为 PNG 文件 Buffer */ +function encodePng(width, height, rgba) { + const signature = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]) + const ihdr = Buffer.alloc(13) + ihdr.writeUInt32BE(width, 0) + ihdr.writeUInt32BE(height, 4) + ihdr[8] = 8 // 位深 8bit + ihdr[9] = 6 // 颜色类型 6 = RGBA + const raw = Buffer.alloc((width * 4 + 1) * height) + for (let y = 0; y < height; y++) { + raw[y * (width * 4 + 1)] = 0 // 滤波器类型 0 = None + rgba.copy(raw, y * (width * 4 + 1) + 1, y * width * 4, (y + 1) * width * 4) + } + return Buffer.concat([ + signature, + pngChunk('IHDR', ihdr), + pngChunk('IDAT', deflateSync(raw, { level: 9 })), + pngChunk('IEND', Buffer.alloc(0)), + ]) +} + +// ---------- 图像处理 ---------- +/** 中心裁剪为正方形(源图若已是正方形则原样返回) */ +function cropSquare(img) { + const { width, height, data } = img + if (width === height) return img + const size = Math.min(width, height) + const ox = Math.floor((width - size) / 2) + const oy = Math.floor((height - size) / 2) + const out = Buffer.alloc(size * size * 4) + for (let y = 0; y < size; y++) { + data.copy(out, y * size * 4, ((y + oy) * width + ox) * 4, ((y + oy) * width + ox + size) * 4) + } + return { width: size, height: size, data: out } +} + +/** + * 面积平均法缩放(box filter): + * 缩小图标时每个目标像素取源区域的加权平均,比近邻采样平滑得多,小尺寸下依然清晰 + */ +function resizeRgba(src, sw, sh, tw, th) { + const dst = Buffer.alloc(tw * th * 4) + const xr = sw / tw + const yr = sh / th + for (let ty = 0; ty < th; ty++) { + const y0 = ty * yr + const y1 = y0 + yr + for (let tx = 0; tx < tw; tx++) { + const x0 = tx * xr + const x1 = x0 + xr + let r = 0 + let g = 0 + let b = 0 + let a = 0 + let area = 0 + for (let sy = Math.floor(y0); sy < y1 && sy < sh; sy++) { + const wy = Math.min(sy + 1, y1) - Math.max(sy, y0) + if (wy <= 0) continue + for (let sx = Math.floor(x0); sx < x1 && sx < sw; sx++) { + const wx = Math.min(sx + 1, x1) - Math.max(sx, x0) + if (wx <= 0) continue + const w = wx * wy + const i = (sy * sw + sx) * 4 + r += src[i] * w + g += src[i + 1] * w + b += src[i + 2] * w + a += src[i + 3] * w + area += w + } + } + const di = (ty * tw + tx) * 4 + dst[di] = Math.round(r / area) + dst[di + 1] = Math.round(g / area) + dst[di + 2] = Math.round(b / area) + dst[di + 3] = Math.round(a / area) + } + } + return dst +} + +/** 圆角矩形有符号距离场:返回值 <0 表示在内部,用于逐像素计算覆盖率实现抗锯齿 */ +function roundedRectDist(x, y, cx, cy, halfW, halfH, r) { + const dx = Math.abs(x - cx) - (halfW - r) + const dy = Math.abs(y - cy) - (halfH - r) + const ax = Math.max(dx, 0) + const ay = Math.max(dy, 0) + return Math.hypot(ax, ay) + Math.min(Math.max(dx, dy), 0) - r +} + +/** 应用圆角遮罩(半径 = 尺寸 * ratio,边缘 1px 平滑抗锯齿),现代应用图标观感 */ +function applyRoundedMask(data, size, ratio = 0.22) { + const r = size * ratio + const half = size / 2 + for (let y = 0; y < size; y++) { + for (let x = 0; x < size; x++) { + const dist = roundedRectDist(x + 0.5, y + 0.5, half, half, half, half, r) + const coverage = dist <= -0.5 ? 1 : dist >= 0.5 ? 0 : 0.5 - dist + if (coverage < 1) { + const i = (y * size + x) * 4 + data[i + 3] = Math.round(data[i + 3] * coverage) + } + } + } +} + +// ---------- ICO 封装 ---------- +/** + * 将多张 PNG 打包为 .ico 容器(ICO 支持直接内嵌 PNG 数据,Windows Vista+ 原生支持) + * 为什么自己生成:electron-builder 的 png→ico 原生转换工具在部分环境会崩溃, + * 直接提供 icon.ico 可让打包器跳过转换步骤 + */ +function encodeIco(pngBuffers) { + const count = pngBuffers.length + const header = Buffer.alloc(6) + header.writeUInt16LE(0, 0) // 保留位 + header.writeUInt16LE(1, 2) // 类型:1 = 图标 + header.writeUInt16LE(count, 4) + const entries = [] + const images = [] + let offset = 6 + 16 * count + for (const { size, data } of pngBuffers) { + const entry = Buffer.alloc(16) + entry[0] = size >= 256 ? 0 : size // 0 表示 256 + entry[1] = size >= 256 ? 0 : size + entry[2] = 0 // 调色板色数(真彩色为 0) + entry[3] = 0 // 保留位 + entry.writeUInt16LE(1, 4) // 颜色平面数 + entry.writeUInt16LE(32, 6) // 位深 + entry.writeUInt32LE(data.length, 8) // 数据字节数 + entry.writeUInt32LE(offset, 12) // 数据偏移 + entries.push(entry) + images.push(data) + offset += data.length + } + return Buffer.concat([header, ...entries, ...images]) +} + +// ---------- 主流程 ---------- +if (!existsSync(masterFile)) { + console.error(`未找到源图 ${masterFile},请先放置品牌主视觉 PNG(正方形大图,建议 1024x1024)`) + process.exit(1) +} + +const master = cropSquare(decodePng(readFileSync(masterFile))) +console.log(`源图 ${masterFile} (${master.width}x${master.height})`) + +/** 生成指定尺寸的 RGBA(可选圆角遮罩) */ +function renderSize(size, rounded) { + const data = resizeRgba(master.data, master.width, master.height, size, size) + if (rounded) { + applyRoundedMask(data, size) + } + return data +} + +/** 输出单个 PNG 文件 */ +function writePng(file, size, rounded) { + mkdirSync(dirname(file), { recursive: true }) + writeFileSync(file, encodePng(size, size, renderSize(size, rounded))) + console.log(`已生成 ${file} (${size}x${size}${rounded ? ' 圆角' : ''})`) +} + +// 桌面端 / 网站 / 通用(统一圆角) +writePng(join(projectRoot, 'build', 'icon.png'), 256, true) +writePng(join(projectRoot, 'public', 'icons', 'icon.png'), 256, true) +writePng(join(projectRoot, 'public', 'icons', 'tray.png'), 32, true) +writePng(join(projectRoot, 'public', 'favicon.png'), 64, true) +writePng(join(projectRoot, 'public', 'logo.png'), 256, true) +writePng(join(projectRoot, 'src', 'assets', 'logo.png'), 256, true) + +// 移动端 App 图标源图(保留直角,HBuilderX/应用商店会按平台规范自行裁切圆角) +writePng(join(projectRoot, '..', 'nl-im-uniapp', 'src', 'static', 'logo.png'), 512, false) + +// Windows 多尺寸 ICO(exe/安装包/快捷方式共用) +const icoSizes = [16, 24, 32, 48, 64, 128, 256] +const icoFile = join(projectRoot, 'build', 'icon.ico') +writeFileSync(icoFile, encodeIco(icoSizes.map((size) => ({ size, data: encodePng(size, size, renderSize(size, true)) })))) +console.log(`已生成 ${icoFile} (${icoSizes.join('/')})`) diff --git a/src/App.vue b/src/App.vue index 7b7b685..3ad89c7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -33,7 +33,7 @@ diff --git a/src/api/request/index.ts b/src/api/request/index.ts index ffabc16..9eca8e5 100644 --- a/src/api/request/index.ts +++ b/src/api/request/index.ts @@ -1,5 +1,6 @@ import axios, { type AxiosInstance, type AxiosResponse, type InternalAxiosRequestConfig } from 'axios' import type { ApiResponse } from './types' +import { API_BASE_URL } from '@/config/app' /** * 扩展 AxiosInstance 类型,修正返回值类型 @@ -14,8 +15,10 @@ interface CustomAxiosInstance extends Omit void export type SignalHandler = (message: ChatMessage) => void export type MomentNotifHandler = (payload: MomentNotifPayload) => void export type ReadReceiptHandler = (data: { message_ids?: number[]; room_id?: string }) => void +// 消息 extra 更新事件(URL 预览卡片异步抓取完成后服务端补推) +export type MessageExtraUpdateHandler = (data: { id?: number; room_id?: string; extra?: string }) => void /** * WebSocketManager @@ -31,6 +33,7 @@ class WebSocketManager { private signalHandlers: SignalHandler[] = [] private momentNotifHandlers: MomentNotifHandler[] = [] private readReceiptHandlers: ReadReceiptHandler[] = [] + private messageExtraUpdateHandlers: MessageExtraUpdateHandler[] = [] private reconnectAttempts = 0 private maxReconnectAttempts = 10 // 重连采用指数退避:baseDelay * 2^n,封顶 maxReconnectDelay, @@ -39,6 +42,9 @@ class WebSocketManager { private maxReconnectDelay = 30000 // 是否主动断开(登出场景):主动断开后不允许自动重连 private intentionalClose = false + // 在途的 connect Promise:握手期间的重复 connect 直接复用它, + // 避免重建连接把正在握手的 socket 关掉、并把上一个调用方的 Promise 误判为失败 + private connectPromise: Promise | null = null // 用于通知去重的缓存(存储最近处理过的通知ID) private recentMomentNotifs: Set = new Set() private notifCacheTimeout = 5000 // 5秒内相同通知视为重复 @@ -76,18 +82,35 @@ class WebSocketManager { * 调用方马上读 clientId 拿到 null,导致绑定被跳过、回声去重失效 */ connect(userId: string): Promise { - return new Promise((resolve, reject) => { - if (this.ws?.readyState === WebSocket.OPEN) { - resolve() - return - } + if (this.ws?.readyState === WebSocket.OPEN) { + return Promise.resolve() + } + // 握手进行中:复用同一个在途 Promise。 + // 若此时重建连接,会把正在握手的 socket 关掉,其 onclose 将把上一个调用方的 + // Promise 误判为失败(如自动重连与手动重连并发时弹出假的"重连失败"提示) + if (this.connectPromise && this.ws?.readyState === WebSocket.CONNECTING) { + return this.connectPromise + } + const promise = new Promise((resolve, reject) => { this.userId = userId this.intentionalClose = false const wsUrl = this.getWebSocketUrl() try { - this.ws = new WebSocket(wsUrl) + // 替换前先关掉未完成/残留的旧 socket,避免同时挂着两条连接; + // 旧 socket 的回调有下方的"实例守卫",其延迟关闭事件不会影响新连接 + if (this.ws) { + try { + this.ws.close() + } catch { + // 忽略关闭异常 + } + } + // 用局部变量捕获本次创建的实例,事件回调先做实例守卫(this.ws !== socket 即忽略): + // 否则旧连接延迟触发的 onclose 会把新连接的 this.ws 误置为 null 并多排一次重连 + const socket = new WebSocket(wsUrl) + this.ws = socket // resolve/reject 只允许触发一次 let settled = false @@ -103,14 +126,18 @@ class WebSocketManager { } } - this.ws.onopen = () => { + socket.onopen = () => { + // 实例守卫:仅当前活跃连接可重置重连计数、进入就绪流程 + if (this.ws !== socket) return console.log('✅ WebSocket connected') this.reconnectAttempts = 0 // 兜底:连上后 3 秒内未收到 clientId 也放行,避免服务端异常时 Promise 永久挂起 clientIdTimer = window.setTimeout(settleResolve, 3000) } - this.ws.onmessage = (event) => { + socket.onmessage = (event) => { + // 实例守卫:旧连接的迟到消息不处理,防止旧 clientId 覆盖新连接的 + if (this.ws !== socket) return try { // 处理可能的多行JSON或消息分割 const data = event.data.toString().trim() @@ -136,6 +163,11 @@ class WebSocketManager { this.handleReadReceipt(payload.data as { message_ids?: number[]; room_id?: string }) } + // 处理消息 extra 更新(URL 卡片异步就绪后补推,前端刷新对应消息的卡片) + if (payload.request_type === 'message_extra_update' && payload.data) { + this.handleMessageExtraUpdate(payload.data as { id?: number; room_id?: string; extra?: string }) + } + // 处理朋友圈通知 if (payload.request_type === 'moment_notification' && payload.data) { this.handleMomentNotification(payload.data as MomentNotifPayload) @@ -155,7 +187,8 @@ class WebSocketManager { } } - this.ws.onerror = (error) => { + // onerror 只结算本次连接自己的 Promise(错误必然属于本 socket 实例),无需实例守卫 + socket.onerror = (error) => { console.error('WebSocket error:', error) if (clientIdTimer !== null) { window.clearTimeout(clientIdTimer) @@ -167,8 +200,19 @@ class WebSocketManager { } } - this.ws.onclose = () => { + socket.onclose = () => { console.log('WebSocket closed') + // 连接在就绪前被关闭(含被新连接替换)时结算 Promise,避免调用方永久挂起 + if (clientIdTimer !== null) { + window.clearTimeout(clientIdTimer) + clientIdTimer = null + } + if (!settled) { + settled = true + reject(new Error('WebSocket 已关闭')) + } + // 实例守卫:旧连接延迟关闭不得清空新连接的 this.ws、更不能触发额外重连 + if (this.ws !== socket) return this.ws = null // 主动断开(登出)不重连;异常断开按指数退避自动重连 if (!this.intentionalClose) { @@ -179,6 +223,15 @@ class WebSocketManager { reject(error) } }) + + this.connectPromise = promise + // settle 后清掉引用,后续 connect 才会发起新的连接尝试; + // 用 then 的两个分支处理(而非 finally 链),避免派生出未捕获的拒绝 + promise.then( + () => { if (this.connectPromise === promise) this.connectPromise = null }, + () => { if (this.connectPromise === promise) this.connectPromise = null } + ) + return promise } /** @@ -191,6 +244,9 @@ class WebSocketManager { disconnect() { // 标记为主动断开,阻止 onclose 里的自动重连把连接又拉起来 this.intentionalClose = true + // 丢弃在途的连接尝试引用:其 Promise 会随 socket 关闭而 reject(属预期), + // 但不能让登出后紧接着的 connect 复用这个注定失败的 Promise + this.connectPromise = null if (this.ws) { this.ws.close() this.ws = null @@ -328,6 +384,32 @@ class WebSocketManager { this.readReceiptHandlers.forEach(handler => handler(data)) } + /** + * 添加消息 extra 更新处理器(URL 卡片异步补推) + */ + onMessageExtraUpdate(handler: MessageExtraUpdateHandler) { + if (!this.messageExtraUpdateHandlers.includes(handler)) { + this.messageExtraUpdateHandlers.push(handler) + } + } + + /** + * 移除消息 extra 更新处理器(与 onMessageExtraUpdate 对称,供组件卸载时清理) + */ + offMessageExtraUpdate(handler: MessageExtraUpdateHandler) { + const index = this.messageExtraUpdateHandlers.indexOf(handler) + if (index > -1) { + this.messageExtraUpdateHandlers.splice(index, 1) + } + } + + /** + * 内部处理消息 extra 更新事件 + */ + private handleMessageExtraUpdate(data: { id?: number; room_id?: string; extra?: string }) { + this.messageExtraUpdateHandlers.forEach(handler => handler(data)) + } + /** * 内部处理服务端错误推送(消息被拒收/禁言/会话不合法等) * 用动态 import 取 toastStore:wsManager 是模块级单例,模块加载时 pinia diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 0000000..d3a9eed Binary files /dev/null and b/src/assets/logo.png differ diff --git a/src/components/chat/bubble/File.vue b/src/components/chat/bubble/File.vue index 2956946..cfdc2e8 100644 --- a/src/components/chat/bubble/File.vue +++ b/src/components/chat/bubble/File.vue @@ -18,6 +18,7 @@ import { computed } from 'vue' import type { ChatMessage } from '@/types/api' import { formatSize } from '@/utils/format' import { resolveImageUrl } from '@/utils/image' +import { downloadViaElectron } from '@/utils/platform' const props = defineProps<{ message: ChatMessage @@ -45,6 +46,10 @@ function downloadFile() { if (!fileUrl.value) { return } + // Electron 桌面端走主进程下载(系统"另存为"对话框),Web 保持 + if (downloadViaElectron(fileUrl.value, fileName.value)) { + return + } const a = document.createElement('a') a.href = fileUrl.value a.download = fileName.value diff --git a/src/components/chat/bubble/Text.vue b/src/components/chat/bubble/Text.vue index a3aff5d..7c66767 100644 --- a/src/components/chat/bubble/Text.vue +++ b/src/components/chat/bubble/Text.vue @@ -1,9 +1,47 @@ - diff --git a/src/components/common/AppSettingsModal.vue b/src/components/common/AppSettingsModal.vue new file mode 100644 index 0000000..818254b --- /dev/null +++ b/src/components/common/AppSettingsModal.vue @@ -0,0 +1,231 @@ + + + diff --git a/src/components/common/AttachmentManager.vue b/src/components/common/AttachmentManager.vue index 2b76304..797d16a 100644 --- a/src/components/common/AttachmentManager.vue +++ b/src/components/common/AttachmentManager.vue @@ -221,6 +221,7 @@ import { ref, onMounted, watch } from 'vue' import * as attachmentApi from '@/api/modules/attachment' import type { Attachment } from '@/types/api' +import { downloadViaElectron } from '@/utils/platform' const props = defineProps<{ show: boolean @@ -300,6 +301,10 @@ function previewVideo(attachment: Attachment) { // 下载文件 function downloadFile(attachment: Attachment) { + // Electron 桌面端走主进程下载(系统"另存为"对话框),Web 保持 + if (downloadViaElectron(attachment.file_url, attachment.file_name)) { + return + } const link = document.createElement('a') link.href = attachment.file_url link.download = attachment.file_name diff --git a/src/components/common/HtmlPreviewModal.vue b/src/components/common/HtmlPreviewModal.vue new file mode 100644 index 0000000..ce2adb3 --- /dev/null +++ b/src/components/common/HtmlPreviewModal.vue @@ -0,0 +1,48 @@ + + + diff --git a/src/components/common/VideoPlayer.vue b/src/components/common/VideoPlayer.vue index c838573..783f815 100644 --- a/src/components/common/VideoPlayer.vue +++ b/src/components/common/VideoPlayer.vue @@ -231,6 +231,7 @@ diff --git a/src/views/login/LoginView.vue b/src/views/login/LoginView.vue index 42fd952..96f0a2e 100644 --- a/src/views/login/LoginView.vue +++ b/src/views/login/LoginView.vue @@ -1,6 +1,10 @@