diff --git a/.github/workflows/release-it.yml b/.github/workflows/release-it.yml index 339c5b6..71427d4 100644 --- a/.github/workflows/release-it.yml +++ b/.github/workflows/release-it.yml @@ -8,6 +8,7 @@ on: workflow_dispatch: inputs: increment: + description: 选择版本号递增方式 required: true default: patch type: choice diff --git a/README.md b/README.md index f1d09a7..83c8878 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 简体中文 | [English](README_EN.md) -

+

CodeNest Interface

diff --git a/README_EN.md b/README_EN.md index 2290295..cb37d3d 100644 --- a/README_EN.md +++ b/README_EN.md @@ -2,7 +2,7 @@ [简体中文](README.md) | English -

+

CodeNest Interface

diff --git a/electron/ipc.ts b/electron/ipc.ts new file mode 100644 index 0000000..1338f71 --- /dev/null +++ b/electron/ipc.ts @@ -0,0 +1,49 @@ +import { ipcMain } from 'electron' + +import * as dataFile from './services/dataFileService' +import * as dialogSvc from './services/dialogService' +import * as pathSvc from './services/pathService' +import * as projectSvc from './services/projectService' +import * as scanner from './services/scannerService' +import * as systemSvc from './services/systemService' +import * as themeSvc from './services/themeService' +import * as updateSvc from './services/updateService' + +// data file +ipcMain.handle('data:save', (_e, fileType, data) => dataFile.saveData(fileType, data)) +ipcMain.handle('data:load', (_e, fileType) => dataFile.loadData(fileType)) +ipcMain.handle('data:open', (_e, fileType) => dataFile.openData(fileType)) +ipcMain.handle('data:delete', (_e, fileType) => dataFile.deleteData(fileType)) + +// dialog +ipcMain.handle('dialog:open-folder', (_e, options) => dialogSvc.openFolder(options)) +ipcMain.handle('dialog:open-file', (_e, options) => dialogSvc.openFile(options)) + +// path +ipcMain.handle('path:format', (_e, filePath) => pathSvc.format(filePath)) +ipcMain.handle('path:check-existence', (_e, path) => pathSvc.checkExistence(path)) + +// project +ipcMain.handle('project:analyze', (e, folderPath) => projectSvc.analyzeProject(e, folderPath)) +ipcMain.handle('project:read-license', (_e, folderPath, maxLines) => projectSvc.readLicense(folderPath, maxLines)) +ipcMain.handle('project:open', (_e, idePath, projectPath) => projectSvc.openInIDE(idePath, projectPath)) +ipcMain.handle('project:delete', (_e, projectPath) => projectSvc.deleteProject(projectPath)) +ipcMain.handle('project:import', () => projectSvc.importProjects()) +ipcMain.handle('project:export', () => projectSvc.exportProjects()) + +// scanner +ipcMain.handle('scanner:start', (e, payload) => scanner.start(e, payload)) +ipcMain.handle('scanner:stop', (_e, sessionId) => scanner.stop(sessionId)) +ipcMain.handle('scanner:detect-jb-config-root-path', () => scanner.detectJetBrainsConfigRootPath()) +ipcMain.handle('scanner:detect-vsc-state-db-path', () => scanner.detectVscodeStateDbPath()) + +// system +ipcMain.handle('external:open', (_e, url) => systemSvc.openExternal(url)) +ipcMain.handle('explorer:open', (_e, folderPath) => systemSvc.openInExplorer(folderPath)) +ipcMain.handle('terminal:open', (_e, folderPath) => systemSvc.openInTerminal(folderPath)) + +// theme +ipcMain.handle('theme:set', (_e, theme) => themeSvc.setTheme(theme)) + +// update +ipcMain.handle('update:check', () => updateSvc.checkUpdate()) diff --git a/electron/ipc/dataFile.ts b/electron/ipc/dataFile.ts deleted file mode 100644 index 899572e..0000000 --- a/electron/ipc/dataFile.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { ipcMain } from 'electron' -import fs from 'fs-extra' - -import type { DataFileEnum } from '../utils/dataPath' -import { getDataFilePath } from '../utils/dataPath' - -// 保存数据到指定的 JSON 文件 -ipcMain.handle('data:save', async (_, fileType: DataFileEnum, data: string): Promise<{ success: boolean, error?: string }> => { - const filePath = getDataFilePath(fileType) - try { - await fs.ensureFile(filePath) // 确保文件存在 - await fs.writeJSON(filePath, JSON.parse(data), { spaces: 2 }) - return { success: true } - } - catch (error: unknown) { - if (error instanceof Error) { - console.error('Error saving data:', error.message) - return { success: false, error: error.message } - } - else { - console.error('Unknown error:', error) - return { success: false, error: 'Unknown error occurred' } - } - } -}) - -// 从指定的 JSON 文件加载数据 -ipcMain.handle('data:load', async (_, fileType: DataFileEnum): Promise<{ success: boolean, data?: string, error?: string }> => { - const filePath = getDataFilePath(fileType) - try { - const data = await fs.readJSON(filePath) - return { success: true, data: JSON.stringify(data) } - } - catch (error: unknown) { - if (error instanceof Error) { - console.error('Error loading data:', error.message) - return { success: false, error: error.message } - } - else { - console.error('Unknown error:', error) - return { success: false, error: 'Unknown error occurred' } - } - } -}) - -// 删除指定的 JSON 文件 -ipcMain.handle('data:delete', async (_, fileType: DataFileEnum): Promise<{ success: boolean, error?: string }> => { - const filePath = getDataFilePath(fileType) - try { - await fs.remove(filePath) - return { success: true } - } - catch (error: unknown) { - if (error instanceof Error) { - console.error('Error deleting data file:', error.message) - return { success: false, error: error.message } - } - else { - console.error('Unknown error:', error) - return { success: false, error: 'Unknown error occurred' } - } - } -}) diff --git a/electron/ipc/dialog.ts b/electron/ipc/dialog.ts deleted file mode 100644 index a7ad3d1..0000000 --- a/electron/ipc/dialog.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { dialog, ipcMain } from 'electron' - -// 打开文件夹选择对话框 -ipcMain.handle('dialog:open-folder', async (): Promise => { - const result = await dialog.showOpenDialog({ - properties: ['openDirectory'], // 只能选择文件夹 - }) - return result.filePaths -}) - -// 打开文件选择对话框 -ipcMain.handle('dialog:open-file', async (_, fileTypes: { name: string, extensions: string[] }[] = []): Promise => { - const result = await dialog.showOpenDialog({ - properties: ['openFile'], // 只能选择文件 - filters: fileTypes.length > 0 ? fileTypes : undefined, // 如果有文件类型,设置过滤器 - }) - return result.filePaths -}) diff --git a/electron/ipc/folder.ts b/electron/ipc/folder.ts deleted file mode 100644 index 95207a0..0000000 --- a/electron/ipc/folder.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as path from 'node:path' - -import { ipcMain } from 'electron' -import fs from 'fs-extra' - -// 获取目录下的文件夹列表 -ipcMain.handle('folder:get-list', async (_, folderPath: string): Promise<{ folders: string[], error?: string }> => { - try { - const stat = await fs.stat(folderPath) - - // 检查是否是目录 - if (!stat.isDirectory()) { - return { folders: [], error: 'Provided path is not a directory' } - } - - // 读取目录内容并过滤出文件夹,返回绝对路径 - const items = await fs.readdir(folderPath) - const folders: string[] = [] - - for (const item of items) { - const itemPath = path.join(folderPath, item) - const itemStat = await fs.stat(itemPath) - if (itemStat.isDirectory()) { - folders.push(itemPath) - } - } - - return { folders } - } - catch (error: unknown) { - if (error instanceof Error) { - console.error('Error getting folder list:', error.message) - return { folders: [], error: error.message } - } - else { - console.error('Unknown error:', error) - return { folders: [], error: 'Unknown error occurred' } - } - } -}) diff --git a/electron/ipc/index.ts b/electron/ipc/index.ts deleted file mode 100644 index e17908b..0000000 --- a/electron/ipc/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import './dataFile' -import './theme' -import './dialog' -import './folder' -import './path' -import './project' -import './settings' -import './system' -import './update' -import './scanner' diff --git a/electron/ipc/path.ts b/electron/ipc/path.ts deleted file mode 100644 index 32568e1..0000000 --- a/electron/ipc/path.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ipcMain } from 'electron' -import fs from 'fs-extra' - -import { formatPath } from '../utils/pathUtils' - -// 格式化文件路径 -ipcMain.handle('path:format', (_, filePath: string): string => { - return formatPath(filePath) -}) - -// 检查路径是否存在 -ipcMain.handle('path:check-existence', async (_, path: string): Promise<{ exists: boolean, error?: string }> => { - try { - const exists = await fs.pathExists(path) - return { exists } - } - catch (error: unknown) { - if (error instanceof Error) { - console.error('Error checking path existence:', error.message) - return { exists: false, error: error.message } - } - else { - console.error('Unknown error:', error) - return { exists: false, error: 'Unknown error occurred' } - } - } -}) diff --git a/electron/ipc/scanner.ts b/electron/ipc/scanner.ts deleted file mode 100644 index 534a5f9..0000000 --- a/electron/ipc/scanner.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { Worker } from 'node:worker_threads' - -import { ipcMain } from 'electron' - -interface ScanPayload { - roots: string[] - existingPaths: string[] -} - -interface ScanResultItem { - path: string - name: string - mainLang?: string - mainLangColor?: `#${string}` - langGroup?: Array<{ text: string, color: `#${string}`, percentage: number }> - error?: string -} - -// 兼容的批量扫描(返回数组) -ipcMain.handle('scanner:scan', async (_event, payload: ScanPayload): Promise => { - return new Promise((resolve, reject) => { - try { - const workerUrl = new URL('../workers/projectScanner.worker.js', import.meta.url) - const worker = new Worker(workerUrl, { type: 'module', workerData: payload } as any) - - const items: ScanResultItem[] = [] - const cleanup = () => worker.removeAllListeners() - - worker.on('message', (msg: any) => { - if (msg?.type === 'item' && msg.item) { - items.push(msg.item as ScanResultItem) - } - else if (msg?.type === 'done') { - cleanup() - resolve(items) - } - else if (msg?.type === 'error') { - cleanup() - reject(new Error(msg.error || 'scan error')) - } - }) - - worker.once('error', (err) => { - cleanup() - reject(err) - }) - worker.once('exit', (code) => { - if (code !== 0) - reject(new Error(`scanner worker exited with code ${code}`)) - }) - } - catch (e) { - reject(e) - } - }) -}) - -// 流式扫描:创建会话,逐条回推 -const sessions = new Map() -let nextSessionId = 1 - -ipcMain.handle('scanner:start', (event, payload: ScanPayload): { sessionId: number } => { - const sessionId = nextSessionId++ - const workerUrl = new URL('../workers/projectScanner.worker.js', import.meta.url) - const worker = new Worker(workerUrl, { type: 'module', workerData: payload } as any) - - sessions.set(sessionId, worker) - - const send = (channel: 'scanner:item' | 'scanner:done' | 'scanner:error', data?: any) => { - event.sender.send(channel, { sessionId, ...data }) - } - - const cleanup = () => { - worker.removeAllListeners() - sessions.delete(sessionId) - } - - worker.on('message', (msg: any) => { - if (msg?.type === 'item') { - send('scanner:item', { item: msg.item }) - } - else if (msg?.type === 'done') { - send('scanner:done') - cleanup() - } - else if (msg?.type === 'error') { - send('scanner:error', { error: msg.error }) - cleanup() - } - }) - - worker.once('error', (err) => { - send('scanner:error', { error: String(err) }) - cleanup() - }) - worker.once('exit', (code) => { - if (code !== 0) { - send('scanner:error', { error: `exit ${code}` }) - cleanup() - } - }) - - return { sessionId } -}) - -ipcMain.handle('scanner:stop', (_event, sessionId: number) => { - const worker = sessions.get(sessionId) - if (worker) { - try { - worker.terminate() - } - catch {} - worker.removeAllListeners() - sessions.delete(sessionId) - return { stopped: true } - } - return { stopped: false } -}) diff --git a/electron/ipc/settings.ts b/electron/ipc/settings.ts deleted file mode 100644 index 79eabdc..0000000 --- a/electron/ipc/settings.ts +++ /dev/null @@ -1,33 +0,0 @@ -import * as path from 'node:path' - -import { ipcMain } from 'electron' -import fs from 'fs-extra' - -import { settingsFilePath } from '../utils/dataPath' -import { openLocalFile } from '../utils/pathUtils' - -// 打开设置 JSON 文件 -ipcMain.handle('settings:open-json', async (): Promise => { - try { - // 如果文件不存在,创建一个新的 JSON 文件 - if (!fs.existsSync(settingsFilePath)) { - console.warn(`Settings file not found. Creating new file at: ${settingsFilePath}`) - - // 创建文件夹路径(如果不存在) - const dir = path.dirname(settingsFilePath) - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }) - } - - // 创建一个默认设置文件 - fs.writeFileSync(settingsFilePath, JSON.stringify({}), 'utf8') - } - - // 打开文件 - return openLocalFile(settingsFilePath) - } - catch (error) { - console.error(`Failed to open or create settings file: ${error}`) - return false - } -}) diff --git a/electron/main.ts b/electron/main.ts index 56f5b19..5c8a609 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -1,4 +1,4 @@ -import './ipc/index' +import './ipc' import * as path from 'node:path' import { fileURLToPath } from 'node:url' diff --git a/electron/preload.ts b/electron/preload.ts index 0c944cd..de67b8b 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -1,67 +1,117 @@ import { contextBridge, ipcRenderer } from 'electron' -contextBridge.exposeInMainWorld('api', { - // dialog - openFolderDialog: () => ipcRenderer.invoke('dialog:open-folder'), - openFileDialog: (fileTypes: { name: string, extensions: string[] }[] = []) => ipcRenderer.invoke('dialog:open-file', fileTypes), +/* ========================= + * Shared types + * ========================= */ +type Unlisten = () => void - // folder - getFolderList: (folderPath: string) => ipcRenderer.invoke('folder:get-list', folderPath), +interface DialogOpenOptions { + title?: string +} +interface FileTypeFilter { name: string, extensions: string[] } +type FileDialogOptions = DialogOpenOptions & { + fileTypes?: FileTypeFilter[] +} - // path +type ProjectAnalyzeStage = 'start' | 'checking' | 'analyzing' | 'done' +interface ProjectAnalyzeProgress { + folderPath: string + stage: ProjectAnalyzeStage +} + +interface ScanStartPayload { roots: string[], existingPaths: string[], projectPaths?: string[] } +interface ScannerItemEvent { sessionId: number, item: any } +interface ScannerDoneEvent { sessionId: number } +interface ScannerErrorEvent { sessionId: number, error: string } + +/* ========================= + * IPC helpers + * ========================= */ +function onIpc(channel: string, cb: (data: T) => void): Unlisten { + const handler = (_: unknown, data: T) => cb(data) + ipcRenderer.on(channel, handler) + return () => ipcRenderer.removeListener(channel, handler) +} + +const api = { + // ===== dialog ===== + openFolderDialog: (options?: DialogOpenOptions) => + ipcRenderer.invoke('dialog:open-folder', options), + + openFileDialog: (options?: FileDialogOptions) => + ipcRenderer.invoke('dialog:open-file', options), + + // ===== path ===== formatPath: (filePath: string) => ipcRenderer.invoke('path:format', filePath), - checkPathExistence: (path: string) => ipcRenderer.invoke('path:check-existence', path), - - // project - analyzeProject: (folderPath: string) => ipcRenderer.invoke('project:analyze', folderPath), - onProjectAnalyzeProgress: (cb: (data: { folderPath: string, stage: 'start' | 'checking' | 'analyzing' | 'done' }) => void) => { - const handler = (_: any, data: any) => cb(data) - ipcRenderer.on('project:analyze:progress', handler) - return () => ipcRenderer.removeListener('project:analyze:progress', handler) - }, - readProjectLicense: (folderPath: string, maxLines = 20) => ipcRenderer.invoke('project:read-license', folderPath, maxLines), - openProject: (idePath: string, projectPath: string) => ipcRenderer.invoke('project:open', idePath, projectPath), - deleteProject: (projectPath: string) => ipcRenderer.invoke('project:delete', projectPath), + + checkPathExistence: (path: string) => + ipcRenderer.invoke('path:check-existence', path), + + // ===== project ===== + analyzeProject: (folderPath: string) => + ipcRenderer.invoke('project:analyze', folderPath), + + onProjectAnalyzeProgress: (cb: (data: ProjectAnalyzeProgress) => void): Unlisten => + onIpc('project:analyze:progress', cb), + + readProjectLicense: (folderPath: string, maxLines = 20) => + ipcRenderer.invoke('project:read-license', folderPath, maxLines), + + openProject: (idePath: string, projectPath: string) => + ipcRenderer.invoke('project:open', idePath, projectPath), + + deleteProject: (projectPath: string) => + ipcRenderer.invoke('project:delete', projectPath), + importProject: () => ipcRenderer.invoke('project:import'), + exportProject: () => ipcRenderer.invoke('project:export'), - // settings - openSettingsJSON: () => ipcRenderer.invoke('settings:open-json'), + // ===== data ===== + saveData: (fileType: string, data: string) => + ipcRenderer.invoke('data:save', fileType, data), - // data - saveData: (fileType: string, data: string) => ipcRenderer.invoke('data:save', fileType, data), loadData: (fileType: string) => ipcRenderer.invoke('data:load', fileType), + + openData: (fileType: string) => ipcRenderer.invoke('data:open', fileType), + deleteData: (fileType: string) => ipcRenderer.invoke('data:delete', fileType), - // system + // ===== system ===== openExternal: (url: string) => ipcRenderer.invoke('external:open', url), + openInExplorer: (path: string) => ipcRenderer.invoke('explorer:open', path), + openInTerminal: (path: string) => ipcRenderer.invoke('terminal:open', path), - // update + // ===== update ===== checkUpdate: () => ipcRenderer.invoke('update:check'), - // scanner (batch) - scanProjects: (payload: { roots: string[], existingPaths: string[] }) => ipcRenderer.invoke('scanner:scan', payload), - // scanner (stream) - startProjectScan: (payload: { roots: string[], existingPaths: string[] }) => ipcRenderer.invoke('scanner:start', payload), - stopProjectScan: (sessionId: number) => ipcRenderer.invoke('scanner:stop', sessionId), - onScannerItem: (cb: (data: { sessionId: number, item: any }) => void) => { - const handler = (_: any, data: any) => cb(data) - ipcRenderer.on('scanner:item', handler) - return () => ipcRenderer.removeListener('scanner:item', handler) - }, - onScannerDone: (cb: (data: { sessionId: number }) => void) => { - const handler = (_: any, data: any) => cb(data) - ipcRenderer.on('scanner:done', handler) - return () => ipcRenderer.removeListener('scanner:done', handler) - }, - onScannerError: (cb: (data: { sessionId: number, error: string }) => void) => { - const handler = (_: any, data: any) => cb(data) - ipcRenderer.on('scanner:error', handler) - return () => ipcRenderer.removeListener('scanner:error', handler) - }, - - // theme - setWindowTheme: (currentTheme: 'light' | 'dark') => ipcRenderer.invoke('theme:set', currentTheme), -}) + // ===== scanner ===== + startProjectScan: (payload: ScanStartPayload) => + ipcRenderer.invoke('scanner:start', payload), + + stopProjectScan: (sessionId: number) => + ipcRenderer.invoke('scanner:stop', sessionId), + + onScannerItem: (cb: (data: ScannerItemEvent) => void): Unlisten => + onIpc('scanner:item', cb), + + onScannerDone: (cb: (data: ScannerDoneEvent) => void): Unlisten => + onIpc('scanner:done', cb), + + onScannerError: (cb: (data: ScannerErrorEvent) => void): Unlisten => + onIpc('scanner:error', cb), + + detectJetBrainsConfigRootPath: () => + ipcRenderer.invoke('scanner:detect-jb-config-root-path'), + + detectVscodeStateDbPath: () => + ipcRenderer.invoke('scanner:detect-vsc-state-db-path'), + + // ===== theme ===== + setWindowTheme: (currentTheme: 'light' | 'dark') => + ipcRenderer.invoke('theme:set', currentTheme), +} as const + +contextBridge.exposeInMainWorld('api', api) diff --git a/electron/services/dataFileService.ts b/electron/services/dataFileService.ts new file mode 100644 index 0000000..1fd2f57 --- /dev/null +++ b/electron/services/dataFileService.ts @@ -0,0 +1,85 @@ +import path from 'node:path' + +import { shell } from 'electron' +import fs from 'fs-extra' + +import type { DataFileEnum } from '../utils/dataPath' +import { getDataFilePath } from '../utils/dataPath' + +// 保存数据到指定的 JSON 文件 +export async function saveData(fileType: DataFileEnum, data: string) { + const filePath = getDataFilePath(fileType) + try { + await fs.ensureFile(filePath) + await fs.writeJSON(filePath, JSON.parse(data), { spaces: 2 }) + return { success: true as const } + } + catch (e: any) { + console.error('Error saving data:', e?.message || e) + return { success: false as const, error: e?.message || String(e) } + } +} + +// 从指定的 JSON 文件加载数据 +export async function loadData(fileType: DataFileEnum) { + const filePath = getDataFilePath(fileType) + try { + const data = await fs.readJSON(filePath) + return { success: true as const, data: JSON.stringify(data) } + } + catch (e: any) { + console.error('Error loading data:', e?.message || e) + return { success: false as const, error: e?.message || String(e) } + } +} + +/** + * 使用系统默认方式打开指定文件 + * @param filePath - 要打开的文件路径 + * @returns 是否成功打开 + */ +function openLocalFile(filePath: string): boolean { + if (!fs.existsSync(filePath)) { + console.error(`File not found: ${filePath}`) + return false + } + try { + shell.openPath(filePath) // 使用系统默认应用打开文件 + return true + } + catch (error) { + console.error(`Failed to open file: ${filePath}`, error) + return false + } +} + +// 打开指定的 JSON 文件 +export async function openData(fileType: DataFileEnum): Promise { + const filePath = getDataFilePath(fileType) + try { + if (!fs.existsSync(filePath)) { + const dir = path.dirname(filePath) + if (!fs.existsSync(dir)) + fs.mkdirSync(dir, { recursive: true }) + fs.writeFileSync(filePath, JSON.stringify({}), 'utf8') + } + return openLocalFile(filePath) + } + catch (e) { + console.error(`Failed to open or create json file: ${e}`) + return false + } +} + +// 删除指定的 JSON 文件 +export async function deleteData(fileType: DataFileEnum) { + const filePath = getDataFilePath(fileType) + try { + await fs.remove(filePath) + return { success: true as const } + } + catch (e: any) { + console.error('Error deleting data file:', e?.message || e) + return { success: false as const, error: e?.message || String(e) } + } +} diff --git a/electron/services/dialogService.ts b/electron/services/dialogService.ts new file mode 100644 index 0000000..fc06735 --- /dev/null +++ b/electron/services/dialogService.ts @@ -0,0 +1,20 @@ +import { dialog } from 'electron' + +// 打开文件夹选择对话框 +export async function openFolder(options?: { title?: string }) { + const result = await dialog.showOpenDialog({ + title: options?.title, + properties: ['openDirectory'], + }) + return result.filePaths +} + +// 打开文件选择对话框 +export async function openFile(options?: { title?: string, fileTypes?: { name: string, extensions: string[] }[] }) { + const result = await dialog.showOpenDialog({ + title: options?.title, + filters: options?.fileTypes, + properties: ['openFile'], + }) + return result.filePaths +} diff --git a/electron/utils/pathUtils.ts b/electron/services/pathService.ts similarity index 51% rename from electron/utils/pathUtils.ts rename to electron/services/pathService.ts index f587368..f51ab42 100644 --- a/electron/utils/pathUtils.ts +++ b/electron/services/pathService.ts @@ -1,6 +1,5 @@ import * as os from 'node:os' -import { shell } from 'electron' import fs from 'fs-extra' /** @@ -13,7 +12,7 @@ import fs from 'fs-extra' * - 输入: 'C:\\Users\\lenovo\\source', 'D:\\Documents\\project' * - 输出: '~\\source', 'D:\\Documents\\project' */ -export function formatPath(filePath: string): string { +export function format(filePath: string): string { const userHomeDir = os.homedir() if (filePath.startsWith(userHomeDir)) { @@ -22,22 +21,14 @@ export function formatPath(filePath: string): string { return filePath } -/** - * 使用系统默认方式打开指定文件 - * @param filePath - 要打开的文件路径 - * @returns 是否成功打开 - */ -export function openLocalFile(filePath: string): boolean { - if (!fs.existsSync(filePath)) { - console.error(`File not found: ${filePath}`) - return false - } +// 检查路径是否存在 +export async function checkExistence(path: string) { try { - shell.openPath(filePath) // 使用系统默认应用打开文件 - return true + const exists = await fs.pathExists(path) + return { exists } } - catch (error) { - console.error(`Failed to open file: ${filePath}`, error) - return false + catch (e: any) { + console.error('Error checking path existence:', e?.message || e) + return { exists: false, error: e?.message || String(e) } } } diff --git a/electron/ipc/project.ts b/electron/services/projectService.ts similarity index 92% rename from electron/ipc/project.ts rename to electron/services/projectService.ts index e05a7e4..7dbdcb2 100644 --- a/electron/ipc/project.ts +++ b/electron/services/projectService.ts @@ -2,7 +2,8 @@ import { exec } from 'node:child_process' import path from 'node:path' import { Worker } from 'node:worker_threads' -import { dialog, ipcMain } from 'electron' +import type { IpcMainInvokeEvent } from 'electron' +import { dialog } from 'electron' import fs from 'fs-extra' import trash from 'trash' @@ -10,7 +11,7 @@ import { projectsFilePath } from '../utils/dataPath' import type { LinguistResult } from '../utils/linguist' // 传入项目根目录,获取项目各编程语言的占比 -ipcMain.handle('project:analyze', async (event, folderPath): Promise => { +export async function analyzeProject(event: IpcMainInvokeEvent, folderPath: string): Promise { return await new Promise((resolve) => { try { const workerUrl = new URL('../workers/linguistAnalyze.worker.js', import.meta.url) @@ -56,10 +57,10 @@ ipcMain.handle('project:analyze', async (event, folderPath): Promise { +export async function readLicense(folderPath: string, maxLines = 20) { try { if (!folderPath || typeof folderPath !== 'string') return { success: false, message: 'Invalid project path' } @@ -120,10 +121,10 @@ ipcMain.handle('project:read-license', async (_evt, folderPath: string, maxLines catch (e: any) { return { success: false, message: String(e?.message || e) } } -}) +} // 使用IDE打开项目 -ipcMain.handle('project:open', async (_, idePath: string, projectPath: string): Promise => { +export async function openInIDE(idePath: string, projectPath: string): Promise { if (!idePath || !projectPath) { throw new Error('IDE 路径和项目路径不能为空') } @@ -148,10 +149,10 @@ ipcMain.handle('project:open', async (_, idePath: string, projectPath: string): console.error(err) throw new Error('打开项目时发生错误') } -}) +} // 删除项目 -ipcMain.handle('project:delete', async (_, projectPath: string) => { +export async function deleteProject(projectPath: string) { try { if (!fs.existsSync(projectPath)) { throw new Error('项目路径不存在') @@ -183,10 +184,10 @@ ipcMain.handle('project:delete', async (_, projectPath: string) => { return { success: false, message: '删除项目失败', error: (deleteError as Error).message } } } -}) +} // 导入数据 -ipcMain.handle('project:import', async () => { +export async function importProjects() { try { const result = await dialog.showOpenDialog({ properties: ['openFile'], @@ -208,10 +209,10 @@ ipcMain.handle('project:import', async () => { console.error('Error importing data file:', error) return { success: false, message: 'Failed to import data file' } } -}) +} // 导出数据 -ipcMain.handle('project:export', async () => { +export async function exportProjects() { try { const result = await dialog.showSaveDialog({ defaultPath: 'projects.json', @@ -233,4 +234,4 @@ ipcMain.handle('project:export', async () => { console.error('Error exporting data file:', error) return { success: false, message: 'Failed to export data file' } } -}) +} diff --git a/electron/services/scannerService.ts b/electron/services/scannerService.ts new file mode 100644 index 0000000..7104e41 --- /dev/null +++ b/electron/services/scannerService.ts @@ -0,0 +1,169 @@ +import fs from 'node:fs' +import path from 'node:path' +import process from 'node:process' +import { Worker } from 'node:worker_threads' + +import type { IpcMainInvokeEvent } from 'electron' +import { app } from 'electron' + +export interface ScanPayload { + // file system roots scanning + rootsEnabled: boolean + roots: string[] + + // IDE scanning toggles + ideEnabled: boolean + jetbrains: { + enabled: boolean + configRootPath: string + } + vscode: { + enabled: boolean + stateDbPath: string + } + visualStudio: { + enabled: boolean + } + + existingPaths: string[] +} + +// 流式扫描:创建会话,逐条回推 +const sessions = new Map() +let nextSessionId = 1 + +export function start(event: IpcMainInvokeEvent, payload: ScanPayload) { + const sessionId = nextSessionId++ + const workerUrl = new URL('../workers/projectScanner.worker.js', import.meta.url) + const worker = new Worker(workerUrl, { type: 'module', workerData: payload } as any) + + sessions.set(sessionId, worker) + + const send = (channel: 'scanner:item' | 'scanner:done' | 'scanner:error', data?: any) => { + event.sender.send(channel, { sessionId, ...data }) + } + + const cleanup = () => { + worker.removeAllListeners() + sessions.delete(sessionId) + } + + worker.on('message', (msg: any) => { + if (msg?.type === 'item') { + send('scanner:item', { item: msg.item }) + } + else if (msg?.type === 'done') { + send('scanner:done') + cleanup() + } + else if (msg?.type === 'error') { + send('scanner:error', { error: msg.error }) + cleanup() + } + }) + + worker.once('error', (err) => { + send('scanner:error', { error: String(err) }) + cleanup() + }) + worker.once('exit', (code) => { + if (code !== 0) { + send('scanner:error', { error: `exit ${code}` }) + cleanup() + } + }) + + return { sessionId } +} + +export function stop(sessionId: number) { + const worker = sessions.get(sessionId) + if (worker) { + try { + worker.terminate() + } + catch {} + worker.removeAllListeners() + sessions.delete(sessionId) + return { stopped: true } + } + return { stopped: false } +} + +/** + * 自动检测 JetBrains 配置根目录 + * 返回例如: + * - Windows: C:\\Users\\\\AppData\\Roaming\\JetBrains + * - macOS: ~/Library/Application Support/JetBrains + * - Linux: ~/.config/JetBrains 或 ~/.JetBrains(优先 .config/JetBrains) + */ +export function detectJetBrainsConfigRootPath() { + const candidates: string[] = [] + + switch (process.platform) { + case 'win32': { + // Roaming AppData + candidates.push(path.join(app.getPath('appData'), 'JetBrains')) + break + } + case 'darwin': { + candidates.push(path.join(app.getPath('home'), 'Library', 'Application Support', 'JetBrains')) + break + } + default: { + // linux + const home = app.getPath('home') + candidates.push(path.join(home, '.config', 'JetBrains')) + candidates.push(path.join(home, '.JetBrains')) // 一些老版本 + break + } + } + + for (const p of candidates) { + try { + if (fs.existsSync(p) && fs.statSync(p).isDirectory()) + return p + } + catch { + // ignore + } + } + + return null +} + +/** + * 自动检测 VSCode state.vscdb 路径 + * 全平台通用 + */ +export function detectVscodeStateDbPath() { + let dbPath: string + + switch (process.platform) { + case 'win32': + dbPath = path.join(app.getPath('appData'), 'Code', 'User', 'globalStorage', 'state.vscdb') + break + case 'darwin': + dbPath = path.join( + app.getPath('home'), + 'Library', + 'Application Support', + 'Code', + 'User', + 'globalStorage', + 'state.vscdb', + ) + break + default: // linux + dbPath = path.join( + app.getPath('home'), + '.config', + 'Code', + 'User', + 'globalStorage', + 'state.vscdb', + ) + } + + return fs.existsSync(dbPath) ? dbPath : null +} diff --git a/electron/ipc/system.ts b/electron/services/systemService.ts similarity index 69% rename from electron/ipc/system.ts rename to electron/services/systemService.ts index b910245..fc0ebd9 100644 --- a/electron/ipc/system.ts +++ b/electron/services/systemService.ts @@ -2,26 +2,22 @@ import { exec } from 'node:child_process' import * as path from 'node:path' import process from 'node:process' -import { ipcMain, shell } from 'electron' +import { shell } from 'electron' // 在系统默认浏览器中打开链接 -ipcMain.handle('external:open', async (_, url: string): Promise => { - shell.openExternal(url) - .then(() => {}) - .catch(err => console.error('Failed to open link:', err)) -}) +export async function openExternal(url: string): Promise { + await shell.openExternal(url).catch(err => console.error('Failed to open link:', err)) +} // 使用资源管理器打开路径 -ipcMain.handle('explorer:open', async (_, folderPath: string): Promise => { +export async function openInExplorer(folderPath: string): Promise { const resolvedPath = path.resolve(folderPath) // 使用系统默认的资源管理器打开文件夹 - shell.openPath(resolvedPath).catch((err) => { - console.error('打开资源管理器失败:', err) - }) -}) + await shell.openPath(resolvedPath).catch(err => console.error('打开资源管理器失败:', err)) +} // 使用终端打开路径 -ipcMain.handle('terminal:open', async (_, folderPath: string): Promise => { +export async function openInTerminal(folderPath: string): Promise { const resolvedPath = path.resolve(folderPath) // 根据操作系统选择合适的终端命令 const isWindows = process.platform === 'win32' @@ -52,4 +48,4 @@ ipcMain.handle('terminal:open', async (_, folderPath: string): Promise => else { console.error('不支持的操作系统') } -}) +} diff --git a/electron/ipc/theme.ts b/electron/services/themeService.ts similarity index 74% rename from electron/ipc/theme.ts rename to electron/services/themeService.ts index 82a8300..33fc1e0 100644 --- a/electron/ipc/theme.ts +++ b/electron/services/themeService.ts @@ -1,9 +1,7 @@ -import { ipcMain } from 'electron' - import { getMainWindow } from '../main' // 设置主题 -ipcMain.handle('theme:set', async (_, theme: string): Promise => { +export async function setTheme(theme: string): Promise { const colorSettings = theme === 'dark' ? { color: '#2B2D30', symbolColor: '#DFE1E5' } : { color: '#F2F2F2', symbolColor: '#222323' } @@ -12,4 +10,4 @@ ipcMain.handle('theme:set', async (_, theme: string): Promise => { color: colorSettings.color, symbolColor: colorSettings.symbolColor, }) -}) +} diff --git a/electron/ipc/update.ts b/electron/services/updateService.ts similarity index 94% rename from electron/ipc/update.ts rename to electron/services/updateService.ts index af8d206..39d380a 100644 --- a/electron/ipc/update.ts +++ b/electron/services/updateService.ts @@ -1,4 +1,4 @@ -import { app, ipcMain } from 'electron' +import { app } from 'electron' interface CheckUpdateResult { hasUpdate: boolean @@ -12,8 +12,9 @@ interface CheckUpdateResult { } function normalizeVersion(v: string | undefined): string { - if (!v) + if (!v) { return '0.0.0' + } // remove leading v/V and trim whitespace const cleaned = v.trim().replace(/^v/i, '') // drop pre-release/build metadata for comparison @@ -34,7 +35,7 @@ function compareSemver(a: string, b: string): number { return 0 } -ipcMain.handle('update:check', async (): Promise => { +export async function checkUpdate(): Promise { try { // robust version source for dev and packaged const currentVersion = app.getVersion() || '0.0.0' @@ -77,4 +78,4 @@ ipcMain.handle('update:check', async (): Promise => { const currentVersion = app.getVersion() || '0.0.0' return { hasUpdate: false, currentVersion, error: e?.message || String(e) } } -}) +} diff --git a/electron/utils/recent/jetbrainsRecent.ts b/electron/utils/recent/jetbrainsRecent.ts new file mode 100644 index 0000000..7acbf76 --- /dev/null +++ b/electron/utils/recent/jetbrainsRecent.ts @@ -0,0 +1,126 @@ +import fs from 'node:fs' +import os from 'node:os' +import path from 'node:path' +import process from 'node:process' + +import { XMLParser } from 'fast-xml-parser' + +import { uniqExistingDirs } from './shared' + +export interface JetbrainsRecentEntry { + path: string + ide: string | null // 例如 "PyCharm", "IntelliJIdea" +} + +const ideNameMap: Record = { + 'IntelliJIdea': 'intellij-idea', + 'PyCharm': 'pycharm', + 'PhpStorm': 'phpstorm', + 'GoLand': 'goLand', + 'Rider': 'rider', + 'CLion': 'clion', + 'RustRover': 'rust-rover', + 'WebStorm': 'webstorm', + 'RubyMine': 'rubymine', + 'Aqua': 'aqua', + 'Fleet': 'fleet', + 'AndroidStudio': 'android-studio', +} as const + +/** + * 获取 JetBrains 所有 IDE 的最近项目列表 + * @param configRoot JetBrains 配置根目录(例如 C:\Users\xxx\AppData\Roaming\JetBrains) + */ +function getAllJetbrainsRecentProjects( + configRoot: string, +): JetbrainsRecentEntry[] { + if (!fs.existsSync(configRoot)) { + throw new Error(`JetBrains config root not found: ${configRoot}`) + } + + const parser = new XMLParser({ + ignoreAttributes: false, + attributeNamePrefix: '', + }) + + const userHome = os.homedir() + const normalizePath = (p: string): string => + p.replace(/\$USER_HOME\$/g, userHome).replace(/\\/g, '/') + + const entries: JetbrainsRecentEntry[] = [] + + // 遍历 JetBrains 目录下的所有子目录 + for (const subdir of fs.readdirSync(configRoot)) { + const fullDir = path.join(configRoot, subdir) + if (!fs.statSync(fullDir).isDirectory()) + continue + + const xmlPath = path.join(fullDir, 'options', 'recentProjects.xml') + if (!fs.existsSync(xmlPath)) + continue + + const xmlContent = fs.readFileSync(xmlPath, 'utf-8') + const json = parser.parse(xmlContent) + + const ideNameRaw = subdir.replace(/\d.*$/, '') // 去掉版本号,比如 "PyCharm2025.1" -> "PyCharm" + const ideName = ideNameMap[ideNameRaw] ?? null + + const options = json?.application?.component?.option + if (!options) + continue + + // 可能是数组,也可能是单个对象 + const optionList = Array.isArray(options) ? options : [options] + + const additionalInfo = optionList.find(opt => opt.name === 'additionalInfo') + if (!additionalInfo?.map?.entry) + continue + + const projectEntries = additionalInfo.map.entry + + if (Array.isArray(projectEntries)) { + for (const e of projectEntries) { + if (e.key) + entries.push({ path: normalizePath(e.key), ide: ideName }) + } + } + else if (projectEntries?.key) { + entries.push({ path: normalizePath(projectEntries.key), ide: ideName }) + } + } + + // 去重:按 path 唯一 + const seen = new Set() + const uniqueEntries: JetbrainsRecentEntry[] = [] + for (const e of entries) { + if (!seen.has(e.path)) { + seen.add(e.path) + uniqueEntries.push(e) + } + } + + return uniqueEntries +} + +export function collectFromJetbrains(configRoot: string | null): JetbrainsRecentEntry[] { + if (!configRoot) { + return [] + } + let entries: JetbrainsRecentEntry[] = [] + try { + entries = getAllJetbrainsRecentProjects(configRoot) + } + catch { + return [] + } + const candidates: JetbrainsRecentEntry[] = [] + for (const e of entries) { + const p = e.path + // Skip placeholders and JetBrains light-edit/scratches etc. + if (!p || /\$[A-Z_]+\$/.test(p) || /light-edit|scratches/i.test(p)) + continue + const norm = process.platform === 'win32' ? p.replace(/\//g, '\\') : p + candidates.push({ path: norm, ide: e.ide }) + } + return uniqExistingDirs(candidates) +} diff --git a/electron/utils/recent/shared.ts b/electron/utils/recent/shared.ts new file mode 100644 index 0000000..916968d --- /dev/null +++ b/electron/utils/recent/shared.ts @@ -0,0 +1,37 @@ +import fs from 'node:fs' +import path from 'node:path' + +export function uniqExistingDirs( + paths: { path: string, ide: string | null }[], +): { path: string, ide: string | null }[] { + const seen = new Set() + const out: { path: string, ide: string | null }[] = [] + for (const item of paths) { + const p = item.path + if (!p) + continue + let fp = p + // Normalize windows backslashes, remove trailing slashes + fp = path.normalize(fp) + + try { + if (fs.existsSync(fp) && fs.statSync(fp).isDirectory()) { + // 统一大小写来判断唯一性(比如统一转小写) + const key = fp.toLowerCase() + + if (!seen.has(key)) { + seen.add(key) + + // 输出时修正盘符大写(只改第一个字母) + if (/^[a-z]:/.test(fp)) { + fp = fp.charAt(0).toUpperCase() + fp.slice(1) + } + + out.push({ path: fp, ide: item.ide }) + } + } + } + catch {} + } + return out +} diff --git a/electron/utils/recent/vscodeRecent.ts b/electron/utils/recent/vscodeRecent.ts new file mode 100644 index 0000000..2a45cd7 --- /dev/null +++ b/electron/utils/recent/vscodeRecent.ts @@ -0,0 +1,125 @@ +import fs from 'node:fs' +import path from 'node:path' +import process from 'node:process' + +import Database from 'better-sqlite3' + +import { uniqExistingDirs } from './shared' + +export interface VscodeRecentEntry { + folderUri?: string + fileUri?: string + workspace?: { id?: string, configPath: string } | string + label?: string + remoteAuthority?: string +} + +/** + * 获取 VSCode 最近打开项目列表 + * @param dbPath VSCode state.vscdb 文件路径 + */ +function getVscodeRecentProjects(dbPath: string): VscodeRecentEntry[] { + if (!fs.existsSync(dbPath)) { + throw new Error(`VSCode state file not found: ${dbPath}`) + } + + const db = new Database(dbPath, { readonly: true }) + try { + const row = db + .prepare('SELECT value FROM ItemTable WHERE key = \'history.recentlyOpenedPathsList\'') + .get() as { value: string } | undefined + + if (!row) + return [] + + try { + const history = JSON.parse(row.value.toString()) + return history.entries || [] + } + catch (e) { + console.error('Failed to parse VSCode recent list:', e) + return [] + } + } + finally { + try { + db.close() + } + catch {} + } +} + +function isFileUri(uri: string): boolean { + return /^file:\/\//i.test(uri) +} + +function decodeFileUriToFsPath(uri: string): string | null { + if (!isFileUri(uri)) + return null + try { + // Use WHATWG URL for robust parsing + const u = new URL(uri) + // On Windows, URL pathname starts with /c:/... + let p = decodeURIComponent(u.pathname) + if (process.platform === 'win32') { + if (p.startsWith('/')) + p = p.slice(1) + // Convert to backslashes + p = p.replace(/\//g, '\\') + } + return p + } + catch { + // Fallback: strip prefix and decode + try { + const raw = uri.replace(/^file:\/\//i, '') + const decoded = decodeURIComponent(raw) + return process.platform === 'win32' ? decoded.replace(/\//g, '\\') : `/${decoded}` + } + catch { + return null + } + } +} + +export function collectFromVscode(dbPath: string | null): { path: string, ide: string | null }[] { + if (!dbPath) + return [] + let entries: ReturnType = [] + try { + entries = getVscodeRecentProjects(dbPath) + } + catch { + return [] + } + + const candidates: { path: string, ide: string | null }[] = [] + for (const e of entries) { + // Skip remote entries + if ((e as any).remoteAuthority) + continue + + if (e.folderUri && isFileUri(e.folderUri)) { + const p = decodeFileUriToFsPath(e.folderUri) + if (p) + candidates.push({ path: p, ide: null }) + continue + } + if (e.workspace && typeof e.workspace === 'object') { + const cfg = (e.workspace as any).configPath + if (typeof cfg === 'string' && isFileUri(cfg)) { + const p = decodeFileUriToFsPath(cfg) + if (p) + candidates.push({ path: path.dirname(p), ide: null }) + } + continue + } + // Optional: handle fileUri by taking its directory + if (e.fileUri && isFileUri(e.fileUri)) { + const p = decodeFileUriToFsPath(e.fileUri) + if (p) + candidates.push({ path: path.dirname(p), ide: null }) + } + } + return uniqExistingDirs(candidates) +} diff --git a/electron/workers/projectScanner.worker.ts b/electron/workers/projectScanner.worker.ts index a9b4cc7..bf3a83e 100644 --- a/electron/workers/projectScanner.worker.ts +++ b/electron/workers/projectScanner.worker.ts @@ -1,13 +1,12 @@ import * as fs from 'node:fs/promises' import * as path from 'node:path' +import process from 'node:process' import { parentPort, workerData } from 'node:worker_threads' +import type { ScanPayload } from '../services/scannerService' import { analyzeFolder } from '../utils/linguist' - -interface ScanPayload { - roots: string[] - existingPaths: string[] -} +import { collectFromJetbrains } from '../utils/recent/jetbrainsRecent' +import { collectFromVscode } from '../utils/recent/vscodeRecent' interface LangResult { bytes: number @@ -23,6 +22,7 @@ interface ScanResultItem { mainLang?: string mainLangColor?: `#${string}` langGroup?: Array<{ text: string, color: `#${string}`, percentage: number }> + ide?: string | null // CodeEditorEnum,例如 "visual-studio-code" error?: string } @@ -33,6 +33,9 @@ type WorkerMessage const TYPE_PRIORITY: Record = { programming: 1, markup: 2, data: 3, prose: 4 } +// 最大扫描字节,超过则跳过语言分析(可通过环境变量 CODENEST_MAX_SCAN_BYTES 覆盖,默认 800MB) +const MAX_SCAN_BYTES: number = Number(process.env.CODENEST_MAX_SCAN_BYTES ?? 800 * 1024 * 1024) + function sortByMainLanguage(results: Record): [string, LangResult][] { return Object.entries(results).sort(([aK, aV], [bK, bV]) => { const pa = TYPE_PRIORITY[aV.type] ?? 5 @@ -63,6 +66,48 @@ function toLangGroup(sortedEntries: [string, LangResult][]): Array<{ text: strin return big } +// 计算目录大小(包含子目录),一旦超过 cap 就提前停止并返回当前累计大小 +async function getDirectorySizeCapped(dir: string, cap: number): Promise { + let total = 0 + + async function walk(current: string): Promise { + let entries: any[] = [] + try { + entries = await fs.readdir(current, { withFileTypes: true }) + } + catch { + return false + } + + for (const de of entries) { + const full = path.join(current, de.name) + try { + if (de.isDirectory()) { + // 避免跟随符号链接,减少循环风险 + if (typeof de.isSymbolicLink === 'function' && de.isSymbolicLink()) + continue + const exceeded = await walk(full) + if (exceeded) + return true + } + else if (de.isFile()) { + const st = await fs.stat(full) + total += st.size || 0 + if (total > cap) + return true + } + } + catch { + // 忽略不可读文件或权限问题 + } + } + return false + } + + const exceeded = await walk(dir) + return exceeded ? total : total +} + async function listImmediateSubDirs(root: string): Promise { try { const entries = await fs.readdir(root, { withFileTypes: true }) @@ -77,29 +122,64 @@ async function run() { const payload = workerData as ScanPayload const existing = new Set(payload.existingPaths) - try { + const dirsToScan: Set<{ path: string, ide: string | null }> = new Set() + + if (payload.rootsEnabled) { + // 根目录扫描 for (const root of payload.roots) { - const dirs = await listImmediateSubDirs(root) - for (const full of dirs) { - if (existing.has(full)) + (await listImmediateSubDirs(root)).forEach(dir => dirsToScan.add( + { path: dir, ide: null }, + )) + } + } + + if (payload.ideEnabled) { + // IDE 最近项目扫描 + if (payload.jetbrains.enabled) { + // JetBrains + const cfgRoot = payload.jetbrains.configRootPath + const results = collectFromJetbrains(cfgRoot || null) + results.forEach(result => dirsToScan.add( + { path: result.path, ide: result.ide }, + )) + } + if (payload.vscode.enabled) { + // VSCode + const dbPath = payload.vscode.stateDbPath + const results = collectFromVscode(dbPath || null) + results.forEach(result => dirsToScan.add( + { path: result.path, ide: 'visual-studio-code' }, + )) + } + } + + try { + for (const { path: full, ide } of dirsToScan) { + if (existing.has(full)) + continue + const name = path.basename(full) || 'Unnamed Project' + try { + // 在进行语言分析前,先测量目录大小,超过阈值则跳过分析 + const dirSize = await getDirectorySizeCapped(full, MAX_SCAN_BYTES) + if (dirSize > MAX_SCAN_BYTES) { + parentPort?.postMessage({ type: 'item', item: { path: full, name, ide } } satisfies WorkerMessage) continue - const name = path.basename(full) || 'Unnamed Project' - try { - const analyzed = await analyzeFolder(full) - const entries = Object.entries(analyzed.languages.results) - if (!entries.length) { - parentPort?.postMessage({ type: 'item', item: { path: full, name } } satisfies WorkerMessage) - continue - } - const sorted = sortByMainLanguage(Object.fromEntries(entries)) - const mainLang = sorted[0]?.[0] - const mainLangColor = sorted[0]?.[1]?.color as `#${string}` | undefined - const langGroup = toLangGroup(sorted) - parentPort?.postMessage({ type: 'item', item: { path: full, name, mainLang, mainLangColor, langGroup } } satisfies WorkerMessage) } - catch (e: any) { - parentPort?.postMessage({ type: 'item', item: { path: full, name, error: e?.message || String(e) } } satisfies WorkerMessage) + + const analyzed = await analyzeFolder(full) + const entries = Object.entries(analyzed.languages.results) + if (!entries.length) { + parentPort?.postMessage({ type: 'item', item: { path: full, name, ide } } satisfies WorkerMessage) + continue } + const sorted = sortByMainLanguage(Object.fromEntries(entries)) + const mainLang = sorted[0]?.[0] + const mainLangColor = sorted[0]?.[1]?.color as `#${string}` | undefined + const langGroup = toLangGroup(sorted) + parentPort?.postMessage({ type: 'item', item: { path: full, name, mainLang, mainLangColor, langGroup, ide } } satisfies WorkerMessage) + } + catch (e: any) { + parentPort?.postMessage({ type: 'item', item: { path: full, name, error: e?.message || String(e) } } satisfies WorkerMessage) } } parentPort?.postMessage({ type: 'done' } satisfies WorkerMessage) diff --git a/icons/jetBrains.svg b/icons/jetBrains.svg new file mode 100644 index 0000000..2476341 --- /dev/null +++ b/icons/jetBrains.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/jetv-ui/gallery/pages/InputGallery.vue b/jetv-ui/gallery/pages/InputGallery.vue index bb7b9a0..bd711d5 100644 --- a/jetv-ui/gallery/pages/InputGallery.vue +++ b/jetv-ui/gallery/pages/InputGallery.vue @@ -10,6 +10,7 @@ const dropdownValue = ref('option1') const toolbarDropdownValue = ref('tool1') const comboboxValue = ref('') const searchValue = ref('') +const folderValue = ref(null) const fileValue = ref(null) const dropdownOptions = [ @@ -73,7 +74,11 @@ const comboOptions = [ - + +
+ File: {{ folderValue }} +
+
File: {{ fileValue }}
diff --git a/jetv-ui/icons/anyType.svg b/jetv-ui/icons/anyType.svg new file mode 100644 index 0000000..d2edc47 --- /dev/null +++ b/jetv-ui/icons/anyType.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/jetv-ui/icons/anyType_dark.svg b/jetv-ui/icons/anyType_dark.svg new file mode 100644 index 0000000..3ebb0ee --- /dev/null +++ b/jetv-ui/icons/anyType_dark.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/jetv-ui/package.json b/jetv-ui/package.json index 7ceeede..3998b25 100644 --- a/jetv-ui/package.json +++ b/jetv-ui/package.json @@ -22,30 +22,30 @@ "postbuild": "pnpm prepare:icons" }, "devDependencies": { - "@antfu/eslint-config": "5.2.1", - "@iconify/tools": "^4.1.2", + "@antfu/eslint-config": "5.3.0", + "@iconify/tools": "^4.1.3", "@rollup/plugin-typescript": "^12.1.4", "@rushstack/eslint-patch": "^1.12.0", - "@types/node": "^24.3.0", - "@unocss/preset-mini": "^66.4.2", + "@types/node": "^24.5.2", + "@unocss/preset-mini": "^66.5.1", "@vitejs/plugin-vue": "^6.0.1", "@vue/tsconfig": "^0.8.1", - "@vueuse/core": "^13.8.0", - "eslint": "^9.34.0", + "@vueuse/core": "^13.9.0", + "eslint": "^9.35.0", "eslint-plugin-format": "^1.0.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-vue": "^10.4.0", "rollup-plugin-dts": "^6.2.3", - "sass": "^1.91.0", - "terser": "^5.43.1", + "sass": "^1.92.1", + "terser": "^5.44.0", "tslib": "^2.8.1", "typescript": "~5.9.2", - "unocss": "^66.4.2", + "unocss": "^66.5.1", "unplugin-auto-import": "^20.1.0", - "vite": "^7.1.3", - "vue": "^3.5.20", + "vite": "^7.1.6", + "vue": "^3.5.21", "vue-router": "^4.5.1", - "vue-tsc": "^3.0.6" + "vue-tsc": "^3.0.7" } } diff --git a/jetv-ui/pnpm-lock.yaml b/jetv-ui/pnpm-lock.yaml index 99dfb27..5d56eef 100644 --- a/jetv-ui/pnpm-lock.yaml +++ b/jetv-ui/pnpm-lock.yaml @@ -12,55 +12,55 @@ importers: .: devDependencies: '@antfu/eslint-config': - specifier: 5.2.1 - version: 5.2.1(@vue/compiler-sfc@3.5.21)(eslint-plugin-format@1.0.1(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + specifier: 5.3.0 + version: 5.3.0(@vue/compiler-sfc@3.5.21)(eslint-plugin-format@1.0.1(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) '@iconify/tools': - specifier: ^4.1.2 - version: 4.1.2 + specifier: ^4.1.3 + version: 4.1.3 '@rollup/plugin-typescript': specifier: ^12.1.4 - version: 12.1.4(rollup@4.50.0)(tslib@2.8.1)(typescript@5.9.2) + version: 12.1.4(rollup@4.51.0)(tslib@2.8.1)(typescript@5.9.2) '@rushstack/eslint-patch': specifier: ^1.12.0 version: 1.12.0 '@types/node': - specifier: ^24.3.0 - version: 24.3.0 + specifier: ^24.5.2 + version: 24.5.2 '@unocss/preset-mini': - specifier: ^66.4.2 - version: 66.5.0 + specifier: ^66.5.1 + version: 66.5.1 '@vitejs/plugin-vue': specifier: ^6.0.1 - version: 6.0.1(vite@7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.21(typescript@5.9.2)) + version: 6.0.1(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.21(typescript@5.9.2)) '@vue/tsconfig': specifier: ^0.8.1 version: 0.8.1(typescript@5.9.2)(vue@3.5.21(typescript@5.9.2)) '@vueuse/core': - specifier: ^13.8.0 + specifier: ^13.9.0 version: 13.9.0(vue@3.5.21(typescript@5.9.2)) eslint: - specifier: ^9.34.0 - version: 9.34.0(jiti@2.5.1) + specifier: ^9.35.0 + version: 9.35.0(jiti@2.5.1) eslint-plugin-format: specifier: ^1.0.1 - version: 1.0.1(eslint@9.34.0(jiti@2.5.1)) + version: 1.0.1(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-node: specifier: ^11.1.0 - version: 11.1.0(eslint@9.34.0(jiti@2.5.1)) + version: 11.1.0(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-simple-import-sort: specifier: ^12.1.1 - version: 12.1.1(eslint@9.34.0(jiti@2.5.1)) + version: 12.1.1(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-vue: specifier: ^10.4.0 - version: 10.4.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(vue-eslint-parser@10.2.0(eslint@9.34.0(jiti@2.5.1))) + version: 10.4.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(vue-eslint-parser@10.2.0(eslint@9.35.0(jiti@2.5.1))) rollup-plugin-dts: specifier: ^6.2.3 - version: 6.2.3(rollup@4.50.0)(typescript@5.9.2) + version: 6.2.3(rollup@4.51.0)(typescript@5.9.2) sass: - specifier: ^1.91.0 - version: 1.92.0 + specifier: ^1.92.1 + version: 1.92.1 terser: - specifier: ^5.43.1 + specifier: ^5.44.0 version: 5.44.0 tslib: specifier: ^2.8.1 @@ -69,28 +69,28 @@ importers: specifier: ~5.9.2 version: 5.9.2 unocss: - specifier: ^66.4.2 - version: 66.5.0(postcss@8.5.6)(vite@7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1)) + specifier: ^66.5.1 + version: 66.5.1(postcss@8.5.6)(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)) unplugin-auto-import: specifier: ^20.1.0 version: 20.1.0(@vueuse/core@13.9.0(vue@3.5.21(typescript@5.9.2))) vite: - specifier: ^7.1.3 - version: 7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1) + specifier: ^7.1.6 + version: 7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1) vue: - specifier: ^3.5.20 + specifier: ^3.5.21 version: 3.5.21(typescript@5.9.2) vue-router: specifier: ^4.5.1 version: 4.5.1(vue@3.5.21(typescript@5.9.2)) vue-tsc: - specifier: ^3.0.6 - version: 3.0.6(typescript@5.9.2) + specifier: ^3.0.7 + version: 3.0.7(typescript@5.9.2) packages: - '@antfu/eslint-config@5.2.1': - resolution: {integrity: sha512-EG/5kwDci1PFKSwAPMEMHDA/VYJFn0TAqwXLdnmE7zuFcaug3EGih7UOWmapMfL59Hqq6jbomaUHN31aVnL8NA==} + '@antfu/eslint-config@5.3.0': + resolution: {integrity: sha512-VzBemSi453rd06lF6gG6VkpP3HH7XKTf+sK6frSrGm7uMFkN57jry1XB074tQRKB3qOjhpsx3kKpWtOv9e5FnQ==} hasBin: true peerDependencies: '@eslint-react/eslint-plugin': ^1.38.4 @@ -174,8 +174,8 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.28.3': - resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} engines: {node: '>=6.0.0'} hasBin: true @@ -187,8 +187,8 @@ packages: resolution: {integrity: sha512-X6ZlfR/O/s5EQ/SnUSLzr+6kGnkg8HXGMzpgsMsrJVcfDtH1vIp6ctCN4eZ1LS5c0+te5Cb6Y514fASjMRJ1nw==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} '@clack/core@0.5.0': @@ -210,162 +210,162 @@ packages: resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} engines: {node: '>=18'} - '@es-joy/jsdoccomment@0.52.0': - resolution: {integrity: sha512-BXuN7BII+8AyNtn57euU2Yxo9yA/KUDNzrpXyi3pfqKmBhhysR6ZWOebFh3vyPoqA3/j1SOvGgucElMGwlXing==} + '@es-joy/jsdoccomment@0.56.0': + resolution: {integrity: sha512-c6EW+aA1w2rjqOMjbL93nZlwxp6c1Ln06vTYs5FjRRhmJXK8V/OrSXdT+pUr4aRYgjCgu8/OkiZr0tzeVrRSbw==} engines: {node: '>=20.11.0'} - '@esbuild/aix-ppc64@0.25.9': - resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} + '@esbuild/aix-ppc64@0.25.10': + resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.9': - resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} + '@esbuild/android-arm64@0.25.10': + resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.9': - resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} + '@esbuild/android-arm@0.25.10': + resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.9': - resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} + '@esbuild/android-x64@0.25.10': + resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.9': - resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} + '@esbuild/darwin-arm64@0.25.10': + resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.9': - resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} + '@esbuild/darwin-x64@0.25.10': + resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.9': - resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} + '@esbuild/freebsd-arm64@0.25.10': + resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.9': - resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} + '@esbuild/freebsd-x64@0.25.10': + resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.9': - resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} + '@esbuild/linux-arm64@0.25.10': + resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.9': - resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} + '@esbuild/linux-arm@0.25.10': + resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.9': - resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} + '@esbuild/linux-ia32@0.25.10': + resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.9': - resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} + '@esbuild/linux-loong64@0.25.10': + resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.9': - resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} + '@esbuild/linux-mips64el@0.25.10': + resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.9': - resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} + '@esbuild/linux-ppc64@0.25.10': + resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.9': - resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} + '@esbuild/linux-riscv64@0.25.10': + resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.9': - resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} + '@esbuild/linux-s390x@0.25.10': + resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.9': - resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} + '@esbuild/linux-x64@0.25.10': + resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.9': - resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} + '@esbuild/netbsd-arm64@0.25.10': + resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.9': - resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} + '@esbuild/netbsd-x64@0.25.10': + resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.9': - resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} + '@esbuild/openbsd-arm64@0.25.10': + resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.9': - resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} + '@esbuild/openbsd-x64@0.25.10': + resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.9': - resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} + '@esbuild/openharmony-arm64@0.25.10': + resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.9': - resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} + '@esbuild/sunos-x64@0.25.10': + resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.9': - resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} + '@esbuild/win32-arm64@0.25.10': + resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.9': - resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} + '@esbuild/win32-ia32@0.25.10': + resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.9': - resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} + '@esbuild/win32-x64@0.25.10': + resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -376,8 +376,8 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -411,8 +411,8 @@ packages: resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.34.0': - resolution: {integrity: sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==} + '@eslint/js@9.35.0': + resolution: {integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/markdown@7.2.0': @@ -431,24 +431,20 @@ packages: resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.3': resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@iconify/tools@4.1.2': - resolution: {integrity: sha512-q6NzLQYEN9zkDfcyBqD3vItHcZw97w/s++3H3TBxUORr57EfHxj6tOW6fyufDjMq+Vl56WXWaPx1csBPYlI5CA==} + '@iconify/tools@4.1.3': + resolution: {integrity: sha512-guPw9jvkrCCGFUvPr+NgUcQIpQcIll38NQzUzrEMK/1vrDmeJ9jstsp/Dx5LIP2na9BUBLHKOKXA6cERTpnGFw==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -456,8 +452,8 @@ packages: '@iconify/utils@2.3.0': resolution: {integrity: sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==} - '@iconify/utils@3.0.1': - resolution: {integrity: sha512-A78CUEnFGX8I/WlILxJCuIJXloL0j/OJ9PSchPAfCargEIKmUBWvvEMmKWB5oONwiUqlNt+5eRufdkLxeHIWYw==} + '@iconify/utils@3.0.2': + resolution: {integrity: sha512-EfJS0rLfVuRuJRn4psJHtK2A9TqVnkxPpHY6lYHiB9+8eSuudsxbwMiavocG45ujOo6FJ+CIRlRnlOGinzkaGQ==} '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -475,8 +471,8 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -602,8 +598,8 @@ packages: tslib: optional: true - '@rollup/pluginutils@5.2.0': - resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -611,108 +607,108 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.50.0': - resolution: {integrity: sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ==} + '@rollup/rollup-android-arm-eabi@4.51.0': + resolution: {integrity: sha512-VyfldO8T/C5vAXBGIobrAnUE+VJNVLw5z9h4NgSDq/AJZWt/fXqdW+0PJbk+M74xz7yMDRiHtlsuDV7ew6K20w==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.50.0': - resolution: {integrity: sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw==} + '@rollup/rollup-android-arm64@4.51.0': + resolution: {integrity: sha512-Z3ujzDZgsEVSokgIhmOAReh9SGT2qloJJX2Xo1Q3nPU1EhCXrV0PbpR3r7DWRgozqnjrPZQkLe5cgBPIYp70Vg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.50.0': - resolution: {integrity: sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg==} + '@rollup/rollup-darwin-arm64@4.51.0': + resolution: {integrity: sha512-T3gskHgArUdR6TCN69li5VELVAZK+iQ4iwMoSMNYixoj+56EC9lTj35rcxhXzIJt40YfBkvDy3GS+t5zh7zM6g==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.50.0': - resolution: {integrity: sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw==} + '@rollup/rollup-darwin-x64@4.51.0': + resolution: {integrity: sha512-Hh7n/fh0g5UjH6ATDF56Qdf5bzdLZKIbhp5KftjMYG546Ocjeyg15dxphCpH1FFY2PJ2G6MiOVL4jMq5VLTyrQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.50.0': - resolution: {integrity: sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ==} + '@rollup/rollup-freebsd-arm64@4.51.0': + resolution: {integrity: sha512-0EddADb6FBvfqYoxwVom3hAbAvpSVUbZqmR1wmjk0MSZ06hn/UxxGHKRqEQDMkts7XiZjejVB+TLF28cDTU+gA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.50.0': - resolution: {integrity: sha512-G/DKyS6PK0dD0+VEzH/6n/hWDNPDZSMBmqsElWnCRGrYOb2jC0VSupp7UAHHQ4+QILwkxSMaYIbQ72dktp8pKA==} + '@rollup/rollup-freebsd-x64@4.51.0': + resolution: {integrity: sha512-MpqaEDLo3JuVPF+wWV4mK7V8akL76WCz8ndfz1aVB7RhvXFO3k7yT7eu8OEuog4VTSyNu5ibvN9n6lgjq/qLEQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.50.0': - resolution: {integrity: sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==} + '@rollup/rollup-linux-arm-gnueabihf@4.51.0': + resolution: {integrity: sha512-WEWAGFNFFpvSWAIT3MYvxTkYHv/cJl9yWKpjhheg7ONfB0hetZt/uwBnM3GZqSHrk5bXCDYTFXg3jQyk/j7eXQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.50.0': - resolution: {integrity: sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==} + '@rollup/rollup-linux-arm-musleabihf@4.51.0': + resolution: {integrity: sha512-9bxtxj8QoAp++LOq5PGDGkEEOpCDk9rOEHUcXadnijedDH8IXrBt6PnBa4Y6NblvGWdoxvXZYghZLaliTCmAng==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.50.0': - resolution: {integrity: sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==} + '@rollup/rollup-linux-arm64-gnu@4.51.0': + resolution: {integrity: sha512-DdqA+fARqIsfqDYkKo2nrWMp0kvu/wPJ2G8lZ4DjYhn+8QhrjVuzmsh7tTkhULwjvHTN59nWVzAixmOi6rqjNA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.50.0': - resolution: {integrity: sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==} + '@rollup/rollup-linux-arm64-musl@4.51.0': + resolution: {integrity: sha512-2XVRNzcUJE1UJua8P4a1GXS5jafFWE+pQ6zhUbZzptOu/70p1F6+0FTi6aGPd6jNtnJqGMjtBCXancC2dhYlWw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.50.0': - resolution: {integrity: sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==} + '@rollup/rollup-linux-loong64-gnu@4.51.0': + resolution: {integrity: sha512-R8QhY0kLIPCAVXWi2yftDSpn7Jtejey/WhMoBESSfwGec5SKdFVupjxFlKoQ7clVRuaDpiQf7wNx3EBZf4Ey6g==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.50.0': - resolution: {integrity: sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==} + '@rollup/rollup-linux-ppc64-gnu@4.51.0': + resolution: {integrity: sha512-I498RPfxx9cMv1KTHQ9tg2Ku1utuQm+T5B+Xro+WNu3FzAFSKp4awKfgMoZwjoPgNbaFGINaOM25cQW6WuBhiQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.50.0': - resolution: {integrity: sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==} + '@rollup/rollup-linux-riscv64-gnu@4.51.0': + resolution: {integrity: sha512-o8COudsb8lvtdm9ixg9aKjfX5aeoc2x9KGE7WjtrmQFquoCRZ9jtzGlonujE4WhvXFepTraWzT4RcwyDDeHXjA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.50.0': - resolution: {integrity: sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==} + '@rollup/rollup-linux-riscv64-musl@4.51.0': + resolution: {integrity: sha512-0shJPgSXMdYzOQzpM5BJN2euXY1f8uV8mS6AnrbMcH2KrkNsbpMxWB1wp8UEdiJ1NtyBkCk3U/HfX5mEONBq6w==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.50.0': - resolution: {integrity: sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==} + '@rollup/rollup-linux-s390x-gnu@4.51.0': + resolution: {integrity: sha512-L7pV+ny7865jamSCQwyozBYjFRUKaTsPqDz7ClOtJCDu4paf2uAa0mrcHwSt4XxZP2ogFZS9uuitH3NXdeBEJA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.50.0': - resolution: {integrity: sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==} + '@rollup/rollup-linux-x64-gnu@4.51.0': + resolution: {integrity: sha512-4YHhP+Rv3T3+H3TPbUvWOw5tuSwhrVhkHHZhk4hC9VXeAOKR26/IsUAT4FsB4mT+kfIdxxb1BezQDEg/voPO8A==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.50.0': - resolution: {integrity: sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==} + '@rollup/rollup-linux-x64-musl@4.51.0': + resolution: {integrity: sha512-P7U7U03+E5w7WgJtvSseNLOX1UhknVPmEaqgUENFWfNxNBa1OhExT6qYGmyF8gepcxWSaSfJsAV5UwhWrYefdQ==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.50.0': - resolution: {integrity: sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==} + '@rollup/rollup-openharmony-arm64@4.51.0': + resolution: {integrity: sha512-FuD8g3u9W6RPwdO1R45hZFORwa1g9YXEMesAKP/sOi7mDqxjbni8S3zAXJiDcRfGfGBqpRYVuH54Gu3FTuSoEw==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.50.0': - resolution: {integrity: sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg==} + '@rollup/rollup-win32-arm64-msvc@4.51.0': + resolution: {integrity: sha512-zST+FdMCX3QAYfmZX3dp/Fy8qLUetfE17QN5ZmmFGPrhl86qvRr+E9u2bk7fzkIXsfQR30Z7ZRS7WMryPPn4rQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.50.0': - resolution: {integrity: sha512-XzNOVg/YnDOmFdDKcxxK410PrcbcqZkBmz+0FicpW5jtjKQxcW1BZJEQOF0NJa6JO7CZhett8GEtRN/wYLYJuw==} + '@rollup/rollup-win32-ia32-msvc@4.51.0': + resolution: {integrity: sha512-U+qhoCVAZmTHCmUKxdQxw1jwAFNFXmOpMME7Npt5GTb1W/7itfgAgNluVOvyeuSeqW+dEQLFuNZF3YZPO8XkMg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.50.0': - resolution: {integrity: sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==} + '@rollup/rollup-win32-x64-msvc@4.51.0': + resolution: {integrity: sha512-z6UpFzMhXSD8NNUfCi2HO+pbpSzSWIIPgb1TZsEZjmZYtk6RUIC63JYjlFBwbBZS3jt3f1q6IGfkj3g+GnBt2Q==} cpu: [x64] os: [win32] @@ -744,8 +740,8 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@24.3.0': - resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} + '@types/node@24.5.2': + resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} '@types/tar@6.1.13': resolution: {integrity: sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==} @@ -759,148 +755,148 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.42.0': - resolution: {integrity: sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==} + '@typescript-eslint/eslint-plugin@8.44.0': + resolution: {integrity: sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.42.0 + '@typescript-eslint/parser': ^8.44.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.42.0': - resolution: {integrity: sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==} + '@typescript-eslint/parser@8.44.0': + resolution: {integrity: sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.42.0': - resolution: {integrity: sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==} + '@typescript-eslint/project-service@8.44.0': + resolution: {integrity: sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.42.0': - resolution: {integrity: sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==} + '@typescript-eslint/scope-manager@8.44.0': + resolution: {integrity: sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.42.0': - resolution: {integrity: sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==} + '@typescript-eslint/tsconfig-utils@8.44.0': + resolution: {integrity: sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.42.0': - resolution: {integrity: sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==} + '@typescript-eslint/type-utils@8.44.0': + resolution: {integrity: sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.42.0': - resolution: {integrity: sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==} + '@typescript-eslint/types@8.44.0': + resolution: {integrity: sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.42.0': - resolution: {integrity: sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==} + '@typescript-eslint/typescript-estree@8.44.0': + resolution: {integrity: sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.42.0': - resolution: {integrity: sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==} + '@typescript-eslint/utils@8.44.0': + resolution: {integrity: sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.42.0': - resolution: {integrity: sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==} + '@typescript-eslint/visitor-keys@8.44.0': + resolution: {integrity: sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@unocss/astro@66.5.0': - resolution: {integrity: sha512-PueE1reSo0iu/yUos+bB4uYym3hZrNMGboXP5VmEjEL1PFVLuJYft1nLJ24p20nPyzWFNamYAxYTPveNW2BbWg==} + '@unocss/astro@66.5.1': + resolution: {integrity: sha512-f17+xfyBZ9prFx4jda3D9ngOigjO8btHsR3uG7WeDQPW6OBdhETfIGdXs8WD99J/3A3LJtk7J0u9p121S+RE8Q==} peerDependencies: vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 peerDependenciesMeta: vite: optional: true - '@unocss/cli@66.5.0': - resolution: {integrity: sha512-E1Q5FI2K2Xtiiw2bMx+qMCz+TADSw0pVamks4ZlS3FS4hqFtzxeUkOyTys/e8oXxYB4f1+K6UMUUv+Wzk7YiKw==} + '@unocss/cli@66.5.1': + resolution: {integrity: sha512-b9fTS6b7lqTmeftDkZyjkJiC1LoCKzCB4vuX/VdqoHd0QWh02i6ppsfe6C69fMlzOrju01H7CL0Bpad0JzBr2A==} engines: {node: '>=14'} hasBin: true - '@unocss/config@66.5.0': - resolution: {integrity: sha512-vNPqcfCPIVCuV3AU13d6qO/wSRrvdXeV8myQQUlUBVkvHezFBQ/atVOP77Ov5qUBARyx3zwUCkgQxYOCs60EGw==} + '@unocss/config@66.5.1': + resolution: {integrity: sha512-eL9P+WDX42B6ZkNGGSkMgOyR99xeuJ2Gkj0uarhag5kaRwvwHLn/CJptZ7/oZLLIn0uTH8TQ6MG8ErhK0ymewA==} engines: {node: '>=14'} - '@unocss/core@66.5.0': - resolution: {integrity: sha512-4JStg50nrwd4aJulbPYglqHyuVUHMEX2EltpdxrrxknvSjy4LriKCVUCEmIljsbTFDXm8xcPnPGs6VN/ZmlKlA==} + '@unocss/core@66.5.1': + resolution: {integrity: sha512-BUgN87sUIffco1d+1IuV4a1gKTI1YAFa7CTjxglLUAnopXPPJ+Q77G10zoBoFLzutiIOYLsesa3hzbQvDhosnA==} - '@unocss/extractor-arbitrary-variants@66.5.0': - resolution: {integrity: sha512-Em5jrB4wPJWHRwp4hBRPWbYH/brEdQzYFC5RUSNem5u3kToYSiBid4KwBRTBHmLAdDxcrDXBD1pbDot0PAQe2g==} + '@unocss/extractor-arbitrary-variants@66.5.1': + resolution: {integrity: sha512-SpI2uv6bWyPyY3Tv7CxsFnHBjSTlNRcPCnfvD8gSKbAt7R+RqV0nrdkv7wSW+Woc5TYl8PClLEFSBIvo0c1h9Q==} - '@unocss/inspector@66.5.0': - resolution: {integrity: sha512-eozYCqP0TF1a6BoRTOFnLaIczGvR/b5kwhv1RQdAVAUKw08YZQzASTWWL3xeOonXCvFOSRZ3YIWk9Fsk5myPKg==} + '@unocss/inspector@66.5.1': + resolution: {integrity: sha512-EyHcEM9BPZACJhl9YoTlgc/5i4as9MQ4zwaThAXbXoO9l+IfxdNrJoy3ED8qqkKLO5jgzyhPvy1COBdaoSlxsg==} - '@unocss/postcss@66.5.0': - resolution: {integrity: sha512-jwe06YHGGepllsjDIqLtOgh4jViq0XfP/wU81Efg9lQLlMzWkDIMQw8/LQn2UA3WkjWWiQFXvQKb8SWpXENYnA==} + '@unocss/postcss@66.5.1': + resolution: {integrity: sha512-waJSgjJv14cbbaA3fj0kgDid+e851KfArqx1l5/c2km3g9tiPZhSiY3Z7YslwMyM9CKRC8+qN8AWYB9l4YJrFw==} engines: {node: '>=14'} peerDependencies: postcss: ^8.4.21 - '@unocss/preset-attributify@66.5.0': - resolution: {integrity: sha512-kMx1dvQmnceMLD/drZop8dbqJcpZpc+uKpprcAXSio3im5IjXkS4A7H0mL0wXmGFy+2fl+rXEgjnOuofQt0bsw==} + '@unocss/preset-attributify@66.5.1': + resolution: {integrity: sha512-lRTwtg9y+f9c6OlRiiPrXrBco2r9SwVxNvzJ27Kc/DhJl3fphuMQuKWsZyiq1qsDVYZeGz4NQzE1FDKqFi4qqQ==} - '@unocss/preset-icons@66.5.0': - resolution: {integrity: sha512-7Qs5k2LWY9052UQVHiQOZ3yJJEwTgqVrJpEdEaZtvBBrObiXwJ03/oZiCSWpGErfp0WbH5gwaghGb2SjbOkiSw==} + '@unocss/preset-icons@66.5.1': + resolution: {integrity: sha512-vxlnPSzTaQZmLKcmVPhCWC6rpgpHCUSD7aFsn7jW3iZ/jTIwc4kgQjnOJZdL443LF5mxBqF15+Cm9hZRnvrWNw==} - '@unocss/preset-mini@66.5.0': - resolution: {integrity: sha512-aGnxlO47D0DMTEYTbwAZ/xICz8/QGUhin9hb4dsVhEorDvL1R0/qqvyjhyyIeTTDqPTxKTtczY7rP8XJqkuBXA==} + '@unocss/preset-mini@66.5.1': + resolution: {integrity: sha512-kBEbA0kEXRtoHQ98o4b6f9sp1u5BanPzi+GMnWdmOWvbLAiLw1vcgXGPTX3sO+gzIMrwu0Famw6xiztWzAFjWQ==} - '@unocss/preset-tagify@66.5.0': - resolution: {integrity: sha512-uH14GBc00c5G0AO7xpO7SAW+QYhdkFGFH5BVAf21qOPipLzQosgmpvfEapq0urgwhR+b25itdGhP5iEazTs2FQ==} + '@unocss/preset-tagify@66.5.1': + resolution: {integrity: sha512-94dVIqfTT3Nfs+g9XnOC/oZuVsiSp8zR36wA/Uucvg3n1zIo2wg6qokghfh7ee8aYNdTqnV7extlnCMJp0TFJQ==} - '@unocss/preset-typography@66.5.0': - resolution: {integrity: sha512-pMpzXa27zoanZQENT7tY/dJJSLZTEpuvItMruizTaizTYflanxhPpozj5fD6hGNfH4zIWiEu34KcHsTluj2R/A==} + '@unocss/preset-typography@66.5.1': + resolution: {integrity: sha512-5gmv/BN3WbwlZJuoC5qyToK7ufbnmXEszj6+3Rgtto4ptpyizBtJybyZe025ypcmExne3MwMpGWMmQPE5MzKgw==} - '@unocss/preset-uno@66.5.0': - resolution: {integrity: sha512-z39CWf3hI2ghmizPLqOefF1udcF8m/IJ50T6OO+sNpzJIkbL8FUaxGsdf0bKIVUl180EKRSV6kpIOST4nMN5Bg==} + '@unocss/preset-uno@66.5.1': + resolution: {integrity: sha512-nUjh1XMChHpVJng5zJhYXXZcXxVDfmh2dxdZS4DgKQ08F8HdvFXmZV+sJrrw6JdeUtpDytelLFJbA8ejmxHYhA==} - '@unocss/preset-web-fonts@66.5.0': - resolution: {integrity: sha512-OZ/sTpksNTNoMEJ55y4v9lkFkqMR+PFAh1yHYFo7PyAtfJHhr/vb7n4TINl1qmLIhV70GZRdMH7kUuDKaSkxaA==} + '@unocss/preset-web-fonts@66.5.1': + resolution: {integrity: sha512-XKrkoN7ncqJxRHDMxAqTCroBcqSPgryDUZIlLhhQ4mHilSp29AdYO1RgG6Ok04w9HNmqzo3d8A8v6Z5yGrGF0w==} - '@unocss/preset-wind3@66.5.0': - resolution: {integrity: sha512-LC3I2yzmWguOOdp4gLwhJG1/Nya6v9+GH2rXRn8LNSZN5yhdz0LwqjftSIsPxbIpoi7+pkGTzOiXHfV/XXbswA==} + '@unocss/preset-wind3@66.5.1': + resolution: {integrity: sha512-L1yMmKpwUWYUnScQq5jMTGvfMy/GBqVj40VS5afyOlzWnBeSkc/y4AxeW/khzGwqE/QaFcLWXiXwQVJIyxN02Q==} - '@unocss/preset-wind4@66.5.0': - resolution: {integrity: sha512-kR7TPqQ8vIwXrrLticKc5CbHLGbXiRnWI7xPFduC3l8RE0VPyShegmY62KRc6tX58Tarhnsrct+Teln7ZlEWKw==} + '@unocss/preset-wind4@66.5.1': + resolution: {integrity: sha512-i6UaZ/hRabu+bvEwUJcc3k/v/tF1sjKukvtQF027zaL3Q5k5QKKhDH989wVHU1k+i+W77+og2/K9+FzXN9+CzQ==} - '@unocss/preset-wind@66.5.0': - resolution: {integrity: sha512-fofrMsguz/iLkNhD/FaBnYUQGsgTe5Nk9jgJBaigDc6FqG2JcT6S7F7boyquFwfoCXN7Dj3SZ4HKfWH7AhisIw==} + '@unocss/preset-wind@66.5.1': + resolution: {integrity: sha512-YucMFPBa3Gwuxdtk+GlqWWcnCwMpzUJWkiB3BNyGk4wEJ0S/brkC+t1/DKpagOFLK9bc134mLxqLNDMWJwVbrg==} - '@unocss/reset@66.5.0': - resolution: {integrity: sha512-Sf27NbbNUg3e4BShQB7EsMCS1GtA6IORBm08SitSpUZZYOZAj+LAypYsOJ4rttAFs/Hp1h0AxtNShesXWK66oA==} + '@unocss/reset@66.5.1': + resolution: {integrity: sha512-NXDjDUn3cjATkxr7bbPdVnKkUHzEq6wSC1IRpnO8ISAXCw6JGPjuk3WJVYxHhnAlszhDxdqxVBjWRZ+zzVmrZw==} - '@unocss/rule-utils@66.5.0': - resolution: {integrity: sha512-+yqGZP8fR/G/gOkjXSXjmgTXFr4zGCQR+rA3Ana4xVoLIttcmPk4qO1IWcUVRQTDDqFmUjW/XwWmChta+rdQsA==} + '@unocss/rule-utils@66.5.1': + resolution: {integrity: sha512-GuBKHrDv3bdq5N1HfOr1tD864vI1EIiovBVJSfg7x9ERA4jJSnyMpGk/hbLuDIXF25EnVdZ1lFhEpJgur9+9sw==} engines: {node: '>=14'} - '@unocss/transformer-attributify-jsx@66.5.0': - resolution: {integrity: sha512-hydRGKT3ca2BmCR/Hud4svp6RXZKlPjJbNQjGIAuBaMtaFEvsOUhtTmEQlE3PIX2RvI8/LBBDKVcsKP/oOtDLw==} + '@unocss/transformer-attributify-jsx@66.5.1': + resolution: {integrity: sha512-uj3W0zSY6LyRFusqeIEj8VUy6WDbIhNMUajIHRulKdSqufFMxiymn6JLGriz7ArFRXBKBBmbN+kk6Fqi9gF6JA==} - '@unocss/transformer-compile-class@66.5.0': - resolution: {integrity: sha512-Mpi9PP/KZGw1DkNCr40LjgfCzzA8jHOcBfMqVOopUaRSLMLEtgBRKb8anJzoR//owrzJl8EyBBTWl30fTAdpCA==} + '@unocss/transformer-compile-class@66.5.1': + resolution: {integrity: sha512-dEfXxWLt3lbMW85CI2yi0S/fQHcSZ32s9FSfGS3KPxFTJ3EY7tYYesT1bdzVrSm+o7J8Os42E5AiFFPjhiTN6Q==} - '@unocss/transformer-directives@66.5.0': - resolution: {integrity: sha512-nZSi+nfaXL6aXoE7Lzw+qz9I9EHnIjkw9oE0Pu/6WmlJ7gjf+HWiyDaB90fi/Zn8M1VaKYXUCepJQ4ptqy4pjA==} + '@unocss/transformer-directives@66.5.1': + resolution: {integrity: sha512-+SErDMglrTI3NTaY8GYh2fCalXNIQDahf7b2AaBCiOf+SPPXeicIy04/1nx8cJ/qpsJ4Z4+ZBybFlATVSkInyQ==} - '@unocss/transformer-variant-group@66.5.0': - resolution: {integrity: sha512-dAhkSVYEtnaj6VC/JgkV8JeimCesF1uXN6k3WSnf7JMc4zlsBEtLf6Tg8JEBfpWNvhDFrnEXr9GXKflCNbcX1A==} + '@unocss/transformer-variant-group@66.5.1': + resolution: {integrity: sha512-ykUIXExfSCrmex0f8OvS4hYZ4M0EbinosW86xLKwc2GGcbWD6CwqyxxpVWgXSzcc2sIELuqF+K3oZnIlQt3Dug==} - '@unocss/vite@66.5.0': - resolution: {integrity: sha512-4ogtBEHMXZhB4dM+qmG4d+2ATGEV94zbdrdQLEeBrzr52QbALuPHvp4JIQ7q7vIT/XNbMGJkPAiW8cgWiMQsMQ==} + '@unocss/vite@66.5.1': + resolution: {integrity: sha512-qcZMh+SZbKYfTjJC2CP6B9Zxg0jlfhJSDVmXdjQBlUzhQR9FllnwlBdae6SCVFBc634Sm+pBJIri5ShPLvwq+Q==} peerDependencies: vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 @@ -911,8 +907,8 @@ packages: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vue: ^3.2.25 - '@vitest/eslint-plugin@1.3.6': - resolution: {integrity: sha512-sa/QAljHbUP+sMdPjK8e/6nS2+QB/bh1aDKEkAKMqsKVzBXqz4LRYfT7UVGIP8LMIrskGTxqAbHuiL+FOYWzHg==} + '@vitest/eslint-plugin@1.3.12': + resolution: {integrity: sha512-cSEyUYGj8j8SLqKrzN7BlfsJ3wG67eRT25819PXuyoSBogLXiyagdKx4MHWHV1zv+EEuyMXsEKkBEKzXpxyBrg==} peerDependencies: eslint: '>= 8.57.0' typescript: '>= 5.0.0' @@ -950,8 +946,8 @@ packages: '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - '@vue/language-core@3.0.6': - resolution: {integrity: sha512-e2RRzYWm+qGm8apUHW1wA5RQxzNhkqbbKdbKhiDUcmMrNAZGyM8aTiL3UrTqkaFI5s7wJRGGrp4u3jgusuBp2A==} + '@vue/language-core@3.0.7': + resolution: {integrity: sha512-0sqqyqJ0Gn33JH3TdIsZLCZZ8Gr4kwlg8iYOnOrDDkJKSjFurlQY/bEFQx5zs7SX2C/bjMkmPYq/NiyY1fTOkw==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -1037,12 +1033,16 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - axios@1.11.0: - resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} + axios@1.12.2: + resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + baseline-browser-mapping@2.8.6: + resolution: {integrity: sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==} + hasBin: true + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -1060,8 +1060,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.25.4: - resolution: {integrity: sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==} + browserslist@4.26.2: + resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1087,8 +1087,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001739: - resolution: {integrity: sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==} + caniuse-lite@1.0.30001743: + resolution: {integrity: sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1209,8 +1209,8 @@ packages: de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1266,8 +1266,8 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - electron-to-chromium@1.5.213: - resolution: {integrity: sha512-xr9eRzSLNa4neDO0xVFrkXu3vyIzG4Ay08dApecw42Z1NbmCt+keEpXdvlYGVe0wtvY5dhW0Ay0lY0IOfsCg0Q==} + electron-to-chromium@1.5.222: + resolution: {integrity: sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w==} empathic@2.0.0: resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} @@ -1307,8 +1307,8 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - esbuild@0.25.9: - resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} + esbuild@0.25.10: + resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} engines: {node: '>=18'} hasBin: true @@ -1409,8 +1409,8 @@ packages: typescript: optional: true - eslint-plugin-jsdoc@52.0.4: - resolution: {integrity: sha512-be5OzGlLExvcK13Il3noU7/v7WmAQGenTmCaBKf1pwVtPOb6X+PGFVnJad0QhMj4KKf45XjE4hbsBxv25q1fTg==} + eslint-plugin-jsdoc@54.7.0: + resolution: {integrity: sha512-u5Na4he2+6kY1rWqxzbQaAwJL3/tDCuT5ElDRc5UJ9stOeQeQ5L1JJ1kRRu7ldYMlOHMCJLsY8Mg/Tu3ExdZiQ==} engines: {node: '>=20.11.0'} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 @@ -1421,8 +1421,8 @@ packages: peerDependencies: eslint: '>=6.0.0' - eslint-plugin-n@17.21.3: - resolution: {integrity: sha512-MtxYjDZhMQgsWRm/4xYLL0i2EhusWT7itDxlJ80l1NND2AL2Vi5Mvneqv/ikG9+zpran0VsVRXTEHrpLmUZRNw==} + eslint-plugin-n@17.23.1: + resolution: {integrity: sha512-68PealUpYoHOBh332JLLD9Sj7OQUDkFpmcfqt8R9sySfFSeuGJjMTJQvCRRB96zO3A/PELRLkPrzsHmzEFQQ5A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.23.0' @@ -1465,8 +1465,8 @@ packages: peerDependencies: eslint: '>=6.0.0' - eslint-plugin-unicorn@60.0.0: - resolution: {integrity: sha512-QUzTefvP8stfSXsqKQ+vBQSEsXIlAiCduS/V1Em+FKgL9c21U/IIm20/e3MFy1jyCf14tHAhqC1sX8OTy6VUCg==} + eslint-plugin-unicorn@61.0.2: + resolution: {integrity: sha512-zLihukvneYT7f74GNbVJXfWIiNQmkc/a9vYBTE4qPkQZswolWNdu+Wsp9sIXno1JOzdn6OUwLPd19ekXVkahRA==} engines: {node: ^20.10.0 || >=21.0.0} peerDependencies: eslint: '>=9.29.0' @@ -1523,8 +1523,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.34.0: - resolution: {integrity: sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==} + eslint@9.35.0: + resolution: {integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -1695,8 +1695,8 @@ packages: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} - globals@16.3.0: - resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} + globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} engines: {node: '>=18'} globrex@0.1.2: @@ -1815,6 +1815,10 @@ packages: resolution: {integrity: sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==} engines: {node: '>=12.0.0'} + jsdoc-type-pratt-parser@5.1.1: + resolution: {integrity: sha512-DYYlVP1fe4QBMh2xTIs20/YeTz2GYVbWAEZweHSZD+qQ/Cx2d5RShuhhsdk64eTjNq0FeVnteP/qVOgaywSRbg==} + engines: {node: '>=12.0.0'} + jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} @@ -1869,8 +1873,8 @@ packages: longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - magic-string@0.30.18: - resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==} + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} @@ -2027,10 +2031,6 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - min-indent@1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} - minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2090,8 +2090,8 @@ packages: node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + node-releases@2.0.21: + resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -2282,8 +2282,8 @@ packages: rollup: ^3.29.4 || ^4 typescript: ^4.5 || ^5.0 - rollup@4.50.0: - resolution: {integrity: sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw==} + rollup@4.51.0: + resolution: {integrity: sha512-7cR0XWrdp/UAj2HMY/Y4QQEUjidn3l2AY1wSeZoFjMbD8aOMPoV9wgTFYbrJpPzzvejDEini1h3CiUP8wLzxQA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2293,8 +2293,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass@1.92.0: - resolution: {integrity: sha512-KDNI0BxgIRDAfJgzNm5wuy+4yOCIZyrUbjSpiU/JItfih+KGXAVefKL53MTml054MmBA3DDKIBMSI/7XLxZJ3A==} + sass@1.92.1: + resolution: {integrity: sha512-ffmsdbwqb3XeyR8jJR6KelIXARM9bFQe8A6Q3W4Klmwy5Ckd5gz7jgUNHo4UOqutU5Sk1DtKLbpDP0nLCg1xqQ==} engines: {node: '>=14.0.0'} hasBin: true @@ -2322,8 +2322,8 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - sirv@3.0.1: - resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} sisteransi@1.0.5: @@ -2349,8 +2349,8 @@ packages: spdx-license-ids@3.0.22: resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} - strip-indent@4.0.0: - resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + strip-indent@4.1.0: + resolution: {integrity: sha512-OA95x+JPmL7kc7zCu+e+TeYxEiaIyndRx0OrBcK2QPPH09oAndr2ALvymxWA+Lx1PYYvFUm4O63pRkdJAaW96w==} engines: {node: '>=12'} strip-json-comments@3.1.1: @@ -2397,8 +2397,8 @@ packages: tinyexec@1.0.1: resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} to-regex-range@5.0.1: @@ -2442,15 +2442,15 @@ packages: unconfig@7.3.3: resolution: {integrity: sha512-QCkQoOnJF8L107gxfHL0uavn7WD9b3dpBcFX6HtfQYmjw2YzWxGuFQ0N0J6tE9oguCBJn9KOvfqYDCMPHIZrBA==} - undici-types@7.10.0: - resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + undici-types@7.12.0: + resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} undici@6.21.3: resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} engines: {node: '>=18.17'} - unimport@5.2.0: - resolution: {integrity: sha512-bTuAMMOOqIAyjV4i4UH7P07pO+EsVxmhOzQ2YJ290J6mkLUdozNhb5I/YoOEheeNADC03ent3Qj07X0fWfUpmw==} + unimport@5.3.0: + resolution: {integrity: sha512-cty7t1DESgm0OPfCy9oyn5u9B5t0tMW6tH6bXTjAGIO3SkJsbg/DXYHjrPrUKqultqbAAoltAfYsuu/FEDocjg==} engines: {node: '>=18.12.0'} unist-util-is@6.0.0: @@ -2465,11 +2465,11 @@ packages: unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - unocss@66.5.0: - resolution: {integrity: sha512-dnrr3xqIm3B0t6OXyIxFYwfyMgdkp6MVRgrJXSEU0cEmea8lFf7ssU2MNx1Zice3JvQOOpe4FMVINtv/TBZCIA==} + unocss@66.5.1: + resolution: {integrity: sha512-e+9nqOy9v6NwPz0DxFdApGPefW22pCfU0Z1ALuodEoSHen03WlfTuEhkDkcKEpdo78tbIi/BbAYK9qT8p1d9sg==} engines: {node: '>=14'} peerDependencies: - '@unocss/webpack': 66.5.0 + '@unocss/webpack': 66.5.1 vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 peerDependenciesMeta: '@unocss/webpack': @@ -2489,10 +2489,6 @@ packages: '@vueuse/core': optional: true - unplugin-utils@0.2.5: - resolution: {integrity: sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==} - engines: {node: '>=18.12.0'} - unplugin-utils@0.3.0: resolution: {integrity: sha512-JLoggz+PvLVMJo+jZt97hdIIIZ2yTzGgft9e9q8iMrC4ewufl62ekeW7mixBghonn2gVb/ICjyvlmOCUBnJLQg==} engines: {node: '>=20.19.0'} @@ -2513,8 +2509,8 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite@7.1.4: - resolution: {integrity: sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw==} + vite@7.1.6: + resolution: {integrity: sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -2570,8 +2566,8 @@ packages: peerDependencies: vue: ^3.2.0 - vue-tsc@3.0.6: - resolution: {integrity: sha512-Tbs8Whd43R2e2nxez4WXPvvdjGbW24rOSgRhLOHXzWiT4pcP4G7KeWh0YCn18rF4bVwv7tggLLZ6MJnO6jXPBg==} + vue-tsc@3.0.7: + resolution: {integrity: sha512-BSMmW8GGEgHykrv7mRk6zfTdK+tw4MBZY/x6fFa7IkdXK3s/8hQRacPjG9/8YKFDIWGhBocwi6PlkQQ/93OgIQ==} hasBin: true peerDependencies: typescript: '>=5.0.0' @@ -2635,47 +2631,47 @@ packages: snapshots: - '@antfu/eslint-config@5.2.1(@vue/compiler-sfc@3.5.21)(eslint-plugin-format@1.0.1(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@antfu/eslint-config@5.3.0(@vue/compiler-sfc@3.5.21)(eslint-plugin-format@1.0.1(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@antfu/install-pkg': 1.1.0 '@clack/prompts': 0.11.0 - '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.34.0(jiti@2.5.1)) + '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.35.0(jiti@2.5.1)) '@eslint/markdown': 7.2.0 - '@stylistic/eslint-plugin': 5.3.1(eslint@9.34.0(jiti@2.5.1)) - '@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/parser': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - '@vitest/eslint-plugin': 1.3.6(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@stylistic/eslint-plugin': 5.3.1(eslint@9.35.0(jiti@2.5.1)) + '@typescript-eslint/eslint-plugin': 8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/parser': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@vitest/eslint-plugin': 1.3.12(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) ansis: 4.1.0 cac: 6.7.14 - eslint: 9.34.0(jiti@2.5.1) - eslint-config-flat-gitignore: 2.1.0(eslint@9.34.0(jiti@2.5.1)) + eslint: 9.35.0(jiti@2.5.1) + eslint-config-flat-gitignore: 2.1.0(eslint@9.35.0(jiti@2.5.1)) eslint-flat-config-utils: 2.1.1 - eslint-merge-processors: 2.0.0(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-antfu: 3.1.1(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-command: 3.3.1(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-import-lite: 0.3.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - eslint-plugin-jsdoc: 52.0.4(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-jsonc: 2.20.1(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-n: 17.21.3(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + eslint-merge-processors: 2.0.0(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-antfu: 3.1.1(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-command: 3.3.1(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-import-lite: 0.3.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + eslint-plugin-jsdoc: 54.7.0(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-jsonc: 2.20.1(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-n: 17.23.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) eslint-plugin-no-only-tests: 3.3.0 - eslint-plugin-perfectionist: 4.15.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - eslint-plugin-pnpm: 1.1.1(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-regexp: 2.10.0(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-toml: 0.12.0(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-unicorn: 60.0.0(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-unused-imports: 4.2.0(@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-vue: 10.4.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(vue-eslint-parser@10.2.0(eslint@9.34.0(jiti@2.5.1))) - eslint-plugin-yml: 1.18.0(eslint@9.34.0(jiti@2.5.1)) - eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.21)(eslint@9.34.0(jiti@2.5.1)) - globals: 16.3.0 + eslint-plugin-perfectionist: 4.15.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + eslint-plugin-pnpm: 1.1.1(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-regexp: 2.10.0(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-toml: 0.12.0(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-unicorn: 61.0.2(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-unused-imports: 4.2.0(@typescript-eslint/eslint-plugin@8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-vue: 10.4.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(vue-eslint-parser@10.2.0(eslint@9.35.0(jiti@2.5.1))) + eslint-plugin-yml: 1.18.0(eslint@9.35.0(jiti@2.5.1)) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.21)(eslint@9.35.0(jiti@2.5.1)) + globals: 16.4.0 jsonc-eslint-parser: 2.4.0 local-pkg: 1.1.2 parse-gitignore: 2.0.0 toml-eslint-parser: 0.10.0 - vue-eslint-parser: 10.2.0(eslint@9.34.0(jiti@2.5.1)) + vue-eslint-parser: 10.2.0(eslint@9.35.0(jiti@2.5.1)) yaml-eslint-parser: 1.3.0 optionalDependencies: - eslint-plugin-format: 1.0.1(eslint@9.34.0(jiti@2.5.1)) + eslint-plugin-format: 1.0.1(eslint@9.35.0(jiti@2.5.1)) transitivePeerDependencies: - '@eslint/json' - '@vue/compiler-sfc' @@ -2700,10 +2696,10 @@ snapshots: '@babel/generator@7.28.3': dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-string-parser@7.27.1': {} @@ -2712,17 +2708,17 @@ snapshots: '@babel/parser@7.27.7': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 - '@babel/parser@7.28.3': + '@babel/parser@7.28.4': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 '@babel/parser': 7.27.7 - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@babel/traverse@7.27.7': dependencies: @@ -2730,13 +2726,13 @@ snapshots: '@babel/generator': 7.28.3 '@babel/parser': 7.27.7 '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.1 + '@babel/types': 7.28.4 + debug: 4.4.3 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.28.2': + '@babel/types@7.28.4': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 @@ -2761,118 +2757,118 @@ snapshots: '@es-joy/jsdoccomment@0.50.2': dependencies: '@types/estree': 1.0.8 - '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/types': 8.44.0 comment-parser: 1.4.1 esquery: 1.6.0 jsdoc-type-pratt-parser: 4.1.0 - '@es-joy/jsdoccomment@0.52.0': + '@es-joy/jsdoccomment@0.56.0': dependencies: '@types/estree': 1.0.8 - '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/types': 8.44.0 comment-parser: 1.4.1 esquery: 1.6.0 - jsdoc-type-pratt-parser: 4.1.0 + jsdoc-type-pratt-parser: 5.1.1 - '@esbuild/aix-ppc64@0.25.9': + '@esbuild/aix-ppc64@0.25.10': optional: true - '@esbuild/android-arm64@0.25.9': + '@esbuild/android-arm64@0.25.10': optional: true - '@esbuild/android-arm@0.25.9': + '@esbuild/android-arm@0.25.10': optional: true - '@esbuild/android-x64@0.25.9': + '@esbuild/android-x64@0.25.10': optional: true - '@esbuild/darwin-arm64@0.25.9': + '@esbuild/darwin-arm64@0.25.10': optional: true - '@esbuild/darwin-x64@0.25.9': + '@esbuild/darwin-x64@0.25.10': optional: true - '@esbuild/freebsd-arm64@0.25.9': + '@esbuild/freebsd-arm64@0.25.10': optional: true - '@esbuild/freebsd-x64@0.25.9': + '@esbuild/freebsd-x64@0.25.10': optional: true - '@esbuild/linux-arm64@0.25.9': + '@esbuild/linux-arm64@0.25.10': optional: true - '@esbuild/linux-arm@0.25.9': + '@esbuild/linux-arm@0.25.10': optional: true - '@esbuild/linux-ia32@0.25.9': + '@esbuild/linux-ia32@0.25.10': optional: true - '@esbuild/linux-loong64@0.25.9': + '@esbuild/linux-loong64@0.25.10': optional: true - '@esbuild/linux-mips64el@0.25.9': + '@esbuild/linux-mips64el@0.25.10': optional: true - '@esbuild/linux-ppc64@0.25.9': + '@esbuild/linux-ppc64@0.25.10': optional: true - '@esbuild/linux-riscv64@0.25.9': + '@esbuild/linux-riscv64@0.25.10': optional: true - '@esbuild/linux-s390x@0.25.9': + '@esbuild/linux-s390x@0.25.10': optional: true - '@esbuild/linux-x64@0.25.9': + '@esbuild/linux-x64@0.25.10': optional: true - '@esbuild/netbsd-arm64@0.25.9': + '@esbuild/netbsd-arm64@0.25.10': optional: true - '@esbuild/netbsd-x64@0.25.9': + '@esbuild/netbsd-x64@0.25.10': optional: true - '@esbuild/openbsd-arm64@0.25.9': + '@esbuild/openbsd-arm64@0.25.10': optional: true - '@esbuild/openbsd-x64@0.25.9': + '@esbuild/openbsd-x64@0.25.10': optional: true - '@esbuild/openharmony-arm64@0.25.9': + '@esbuild/openharmony-arm64@0.25.10': optional: true - '@esbuild/sunos-x64@0.25.9': + '@esbuild/sunos-x64@0.25.10': optional: true - '@esbuild/win32-arm64@0.25.9': + '@esbuild/win32-arm64@0.25.10': optional: true - '@esbuild/win32-ia32@0.25.9': + '@esbuild/win32-ia32@0.25.10': optional: true - '@esbuild/win32-x64@0.25.9': + '@esbuild/win32-x64@0.25.10': optional: true - '@eslint-community/eslint-plugin-eslint-comments@4.5.0(eslint@9.34.0(jiti@2.5.1))': + '@eslint-community/eslint-plugin-eslint-comments@4.5.0(eslint@9.35.0(jiti@2.5.1))': dependencies: escape-string-regexp: 4.0.0 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) ignore: 5.3.2 - '@eslint-community/eslint-utils@4.7.0(eslint@9.34.0(jiti@2.5.1))': + '@eslint-community/eslint-utils@4.9.0(eslint@9.35.0(jiti@2.5.1))': dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/compat@1.3.2(eslint@9.34.0(jiti@2.5.1))': + '@eslint/compat@1.3.2(eslint@9.35.0(jiti@2.5.1))': optionalDependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.1 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -2886,7 +2882,7 @@ snapshots: '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.1 + debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -2897,7 +2893,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.34.0': {} + '@eslint/js@9.35.0': {} '@eslint/markdown@7.2.0': dependencies: @@ -2922,23 +2918,21 @@ snapshots: '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.6': + '@humanfs/node@0.16.7': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/retry': 0.4.3 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.3': {} - '@iconify/tools@4.1.2': + '@iconify/tools@4.1.3': dependencies: '@iconify/types': 2.0.0 '@iconify/utils': 2.3.0 '@types/tar': 6.1.13 - axios: 1.11.0 + axios: 1.12.2 cheerio: 1.0.0 domhandler: 5.0.3 extract-zip: 2.0.1 @@ -2957,7 +2951,7 @@ snapshots: '@antfu/install-pkg': 1.1.0 '@antfu/utils': 8.1.1 '@iconify/types': 2.0.0 - debug: 4.4.1 + debug: 4.4.3 globals: 15.15.0 kolorist: 1.8.0 local-pkg: 1.1.2 @@ -2965,12 +2959,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@iconify/utils@3.0.1': + '@iconify/utils@3.0.2': dependencies: '@antfu/install-pkg': 1.1.0 '@antfu/utils': 9.2.0 '@iconify/types': 2.0.0 - debug: 4.4.1 + debug: 4.4.3 globals: 15.15.0 kolorist: 1.8.0 local-pkg: 1.1.2 @@ -2981,23 +2975,23 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/remapping@2.3.5': dependencies: '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/source-map@0.3.11': dependencies: '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.30': + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 @@ -3087,93 +3081,93 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.29': {} - '@rollup/plugin-typescript@12.1.4(rollup@4.50.0)(tslib@2.8.1)(typescript@5.9.2)': + '@rollup/plugin-typescript@12.1.4(rollup@4.51.0)(tslib@2.8.1)(typescript@5.9.2)': dependencies: - '@rollup/pluginutils': 5.2.0(rollup@4.50.0) + '@rollup/pluginutils': 5.3.0(rollup@4.51.0) resolve: 1.22.10 typescript: 5.9.2 optionalDependencies: - rollup: 4.50.0 + rollup: 4.51.0 tslib: 2.8.1 - '@rollup/pluginutils@5.2.0(rollup@4.50.0)': + '@rollup/pluginutils@5.3.0(rollup@4.51.0)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.3 optionalDependencies: - rollup: 4.50.0 + rollup: 4.51.0 - '@rollup/rollup-android-arm-eabi@4.50.0': + '@rollup/rollup-android-arm-eabi@4.51.0': optional: true - '@rollup/rollup-android-arm64@4.50.0': + '@rollup/rollup-android-arm64@4.51.0': optional: true - '@rollup/rollup-darwin-arm64@4.50.0': + '@rollup/rollup-darwin-arm64@4.51.0': optional: true - '@rollup/rollup-darwin-x64@4.50.0': + '@rollup/rollup-darwin-x64@4.51.0': optional: true - '@rollup/rollup-freebsd-arm64@4.50.0': + '@rollup/rollup-freebsd-arm64@4.51.0': optional: true - '@rollup/rollup-freebsd-x64@4.50.0': + '@rollup/rollup-freebsd-x64@4.51.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.50.0': + '@rollup/rollup-linux-arm-gnueabihf@4.51.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.50.0': + '@rollup/rollup-linux-arm-musleabihf@4.51.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.50.0': + '@rollup/rollup-linux-arm64-gnu@4.51.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.50.0': + '@rollup/rollup-linux-arm64-musl@4.51.0': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.50.0': + '@rollup/rollup-linux-loong64-gnu@4.51.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.50.0': + '@rollup/rollup-linux-ppc64-gnu@4.51.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.50.0': + '@rollup/rollup-linux-riscv64-gnu@4.51.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.50.0': + '@rollup/rollup-linux-riscv64-musl@4.51.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.50.0': + '@rollup/rollup-linux-s390x-gnu@4.51.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.50.0': + '@rollup/rollup-linux-x64-gnu@4.51.0': optional: true - '@rollup/rollup-linux-x64-musl@4.50.0': + '@rollup/rollup-linux-x64-musl@4.51.0': optional: true - '@rollup/rollup-openharmony-arm64@4.50.0': + '@rollup/rollup-openharmony-arm64@4.51.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.50.0': + '@rollup/rollup-win32-arm64-msvc@4.51.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.50.0': + '@rollup/rollup-win32-ia32-msvc@4.51.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.50.0': + '@rollup/rollup-win32-x64-msvc@4.51.0': optional: true '@rushstack/eslint-patch@1.12.0': {} - '@stylistic/eslint-plugin@5.3.1(eslint@9.34.0(jiti@2.5.1))': + '@stylistic/eslint-plugin@5.3.1(eslint@9.35.0(jiti@2.5.1))': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) - '@typescript-eslint/types': 8.42.0 - eslint: 9.34.0(jiti@2.5.1) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) + '@typescript-eslint/types': 8.44.0 + eslint: 9.35.0(jiti@2.5.1) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -3195,13 +3189,13 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@24.3.0': + '@types/node@24.5.2': dependencies: - undici-types: 7.10.0 + undici-types: 7.12.0 '@types/tar@6.1.13': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.5.2 minipass: 4.2.8 '@types/unist@3.0.3': {} @@ -3210,18 +3204,18 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.5.2 optional: true - '@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.42.0 - '@typescript-eslint/type-utils': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/utils': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.42.0 - eslint: 9.34.0(jiti@2.5.1) + '@typescript-eslint/parser': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.44.0 + '@typescript-eslint/type-utils': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.0 + eslint: 9.35.0(jiti@2.5.1) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -3230,57 +3224,57 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.42.0 - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.42.0 - debug: 4.4.1 - eslint: 9.34.0(jiti@2.5.1) + '@typescript-eslint/scope-manager': 8.44.0 + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.0 + debug: 4.4.3 + eslint: 9.35.0(jiti@2.5.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.42.0(typescript@5.9.2)': + '@typescript-eslint/project-service@8.44.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2) - '@typescript-eslint/types': 8.42.0 - debug: 4.4.1 + '@typescript-eslint/tsconfig-utils': 8.44.0(typescript@5.9.2) + '@typescript-eslint/types': 8.44.0 + debug: 4.4.3 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.42.0': + '@typescript-eslint/scope-manager@8.44.0': dependencies: - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/visitor-keys': 8.42.0 + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/visitor-keys': 8.44.0 - '@typescript-eslint/tsconfig-utils@8.42.0(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.44.0(typescript@5.9.2)': dependencies: typescript: 5.9.2 - '@typescript-eslint/type-utils@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - debug: 4.4.1 - eslint: 9.34.0(jiti@2.5.1) + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + debug: 4.4.3 + eslint: 9.35.0(jiti@2.5.1) ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.42.0': {} + '@typescript-eslint/types@8.44.0': {} - '@typescript-eslint/typescript-estree@8.42.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.44.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.42.0(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2) - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/visitor-keys': 8.42.0 - debug: 4.4.1 + '@typescript-eslint/project-service': 8.44.0(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.44.0(typescript@5.9.2) + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/visitor-keys': 8.44.0 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -3290,182 +3284,182 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/utils@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) - '@typescript-eslint/scope-manager': 8.42.0 - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2) - eslint: 9.34.0(jiti@2.5.1) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) + '@typescript-eslint/scope-manager': 8.44.0 + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.9.2) + eslint: 9.35.0(jiti@2.5.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.42.0': + '@typescript-eslint/visitor-keys@8.44.0': dependencies: - '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/types': 8.44.0 eslint-visitor-keys: 4.2.1 - '@unocss/astro@66.5.0(vite@7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1))': + '@unocss/astro@66.5.1(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1))': dependencies: - '@unocss/core': 66.5.0 - '@unocss/reset': 66.5.0 - '@unocss/vite': 66.5.0(vite@7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1)) + '@unocss/core': 66.5.1 + '@unocss/reset': 66.5.1 + '@unocss/vite': 66.5.1(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)) optionalDependencies: - vite: 7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1) + vite: 7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1) - '@unocss/cli@66.5.0': + '@unocss/cli@66.5.1': dependencies: '@jridgewell/remapping': 2.3.5 - '@unocss/config': 66.5.0 - '@unocss/core': 66.5.0 - '@unocss/preset-uno': 66.5.0 + '@unocss/config': 66.5.1 + '@unocss/core': 66.5.1 + '@unocss/preset-uno': 66.5.1 cac: 6.7.14 chokidar: 3.6.0 colorette: 2.0.20 consola: 3.4.2 - magic-string: 0.30.18 + magic-string: 0.30.19 pathe: 2.0.3 perfect-debounce: 1.0.0 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 unplugin-utils: 0.3.0 - '@unocss/config@66.5.0': + '@unocss/config@66.5.1': dependencies: - '@unocss/core': 66.5.0 + '@unocss/core': 66.5.1 unconfig: 7.3.3 - '@unocss/core@66.5.0': {} + '@unocss/core@66.5.1': {} - '@unocss/extractor-arbitrary-variants@66.5.0': + '@unocss/extractor-arbitrary-variants@66.5.1': dependencies: - '@unocss/core': 66.5.0 + '@unocss/core': 66.5.1 - '@unocss/inspector@66.5.0': + '@unocss/inspector@66.5.1': dependencies: - '@unocss/core': 66.5.0 - '@unocss/rule-utils': 66.5.0 + '@unocss/core': 66.5.1 + '@unocss/rule-utils': 66.5.1 colorette: 2.0.20 gzip-size: 6.0.0 - sirv: 3.0.1 + sirv: 3.0.2 vue-flow-layout: 0.2.0 - '@unocss/postcss@66.5.0(postcss@8.5.6)': + '@unocss/postcss@66.5.1(postcss@8.5.6)': dependencies: - '@unocss/config': 66.5.0 - '@unocss/core': 66.5.0 - '@unocss/rule-utils': 66.5.0 + '@unocss/config': 66.5.1 + '@unocss/core': 66.5.1 + '@unocss/rule-utils': 66.5.1 css-tree: 3.1.0 postcss: 8.5.6 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 - '@unocss/preset-attributify@66.5.0': + '@unocss/preset-attributify@66.5.1': dependencies: - '@unocss/core': 66.5.0 + '@unocss/core': 66.5.1 - '@unocss/preset-icons@66.5.0': + '@unocss/preset-icons@66.5.1': dependencies: - '@iconify/utils': 3.0.1 - '@unocss/core': 66.5.0 + '@iconify/utils': 3.0.2 + '@unocss/core': 66.5.1 ofetch: 1.4.1 transitivePeerDependencies: - supports-color - '@unocss/preset-mini@66.5.0': + '@unocss/preset-mini@66.5.1': dependencies: - '@unocss/core': 66.5.0 - '@unocss/extractor-arbitrary-variants': 66.5.0 - '@unocss/rule-utils': 66.5.0 + '@unocss/core': 66.5.1 + '@unocss/extractor-arbitrary-variants': 66.5.1 + '@unocss/rule-utils': 66.5.1 - '@unocss/preset-tagify@66.5.0': + '@unocss/preset-tagify@66.5.1': dependencies: - '@unocss/core': 66.5.0 + '@unocss/core': 66.5.1 - '@unocss/preset-typography@66.5.0': + '@unocss/preset-typography@66.5.1': dependencies: - '@unocss/core': 66.5.0 - '@unocss/rule-utils': 66.5.0 + '@unocss/core': 66.5.1 + '@unocss/rule-utils': 66.5.1 - '@unocss/preset-uno@66.5.0': + '@unocss/preset-uno@66.5.1': dependencies: - '@unocss/core': 66.5.0 - '@unocss/preset-wind3': 66.5.0 + '@unocss/core': 66.5.1 + '@unocss/preset-wind3': 66.5.1 - '@unocss/preset-web-fonts@66.5.0': + '@unocss/preset-web-fonts@66.5.1': dependencies: - '@unocss/core': 66.5.0 + '@unocss/core': 66.5.1 ofetch: 1.4.1 - '@unocss/preset-wind3@66.5.0': + '@unocss/preset-wind3@66.5.1': dependencies: - '@unocss/core': 66.5.0 - '@unocss/preset-mini': 66.5.0 - '@unocss/rule-utils': 66.5.0 + '@unocss/core': 66.5.1 + '@unocss/preset-mini': 66.5.1 + '@unocss/rule-utils': 66.5.1 - '@unocss/preset-wind4@66.5.0': + '@unocss/preset-wind4@66.5.1': dependencies: - '@unocss/core': 66.5.0 - '@unocss/extractor-arbitrary-variants': 66.5.0 - '@unocss/rule-utils': 66.5.0 + '@unocss/core': 66.5.1 + '@unocss/extractor-arbitrary-variants': 66.5.1 + '@unocss/rule-utils': 66.5.1 - '@unocss/preset-wind@66.5.0': + '@unocss/preset-wind@66.5.1': dependencies: - '@unocss/core': 66.5.0 - '@unocss/preset-wind3': 66.5.0 + '@unocss/core': 66.5.1 + '@unocss/preset-wind3': 66.5.1 - '@unocss/reset@66.5.0': {} + '@unocss/reset@66.5.1': {} - '@unocss/rule-utils@66.5.0': + '@unocss/rule-utils@66.5.1': dependencies: - '@unocss/core': 66.5.0 - magic-string: 0.30.18 + '@unocss/core': 66.5.1 + magic-string: 0.30.19 - '@unocss/transformer-attributify-jsx@66.5.0': + '@unocss/transformer-attributify-jsx@66.5.1': dependencies: '@babel/parser': 7.27.7 '@babel/traverse': 7.27.7 - '@unocss/core': 66.5.0 + '@unocss/core': 66.5.1 transitivePeerDependencies: - supports-color - '@unocss/transformer-compile-class@66.5.0': + '@unocss/transformer-compile-class@66.5.1': dependencies: - '@unocss/core': 66.5.0 + '@unocss/core': 66.5.1 - '@unocss/transformer-directives@66.5.0': + '@unocss/transformer-directives@66.5.1': dependencies: - '@unocss/core': 66.5.0 - '@unocss/rule-utils': 66.5.0 + '@unocss/core': 66.5.1 + '@unocss/rule-utils': 66.5.1 css-tree: 3.1.0 - '@unocss/transformer-variant-group@66.5.0': + '@unocss/transformer-variant-group@66.5.1': dependencies: - '@unocss/core': 66.5.0 + '@unocss/core': 66.5.1 - '@unocss/vite@66.5.0(vite@7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1))': + '@unocss/vite@66.5.1(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1))': dependencies: '@jridgewell/remapping': 2.3.5 - '@unocss/config': 66.5.0 - '@unocss/core': 66.5.0 - '@unocss/inspector': 66.5.0 + '@unocss/config': 66.5.1 + '@unocss/core': 66.5.1 + '@unocss/inspector': 66.5.1 chokidar: 3.6.0 - magic-string: 0.30.18 + magic-string: 0.30.19 pathe: 2.0.3 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 unplugin-utils: 0.3.0 - vite: 7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1) + vite: 7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1) - '@vitejs/plugin-vue@6.0.1(vite@7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.21(typescript@5.9.2))': + '@vitejs/plugin-vue@6.0.1(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.21(typescript@5.9.2))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.29 - vite: 7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1) + vite: 7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1) vue: 3.5.21(typescript@5.9.2) - '@vitest/eslint-plugin@1.3.6(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': + '@vitest/eslint-plugin@1.3.12(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.42.0 - '@typescript-eslint/utils': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - eslint: 9.34.0(jiti@2.5.1) + '@typescript-eslint/scope-manager': 8.44.0 + '@typescript-eslint/utils': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + eslint: 9.35.0(jiti@2.5.1) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: @@ -3485,7 +3479,7 @@ snapshots: '@vue/compiler-core@3.5.21': dependencies: - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.4 '@vue/shared': 3.5.21 entities: 4.5.0 estree-walker: 2.0.2 @@ -3498,13 +3492,13 @@ snapshots: '@vue/compiler-sfc@3.5.21': dependencies: - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.4 '@vue/compiler-core': 3.5.21 '@vue/compiler-dom': 3.5.21 '@vue/compiler-ssr': 3.5.21 '@vue/shared': 3.5.21 estree-walker: 2.0.2 - magic-string: 0.30.18 + magic-string: 0.30.19 postcss: 8.5.6 source-map-js: 1.2.1 @@ -3520,7 +3514,7 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/language-core@3.0.6(typescript@5.9.2)': + '@vue/language-core@3.0.7(typescript@5.9.2)': dependencies: '@volar/language-core': 2.4.23 '@vue/compiler-dom': 3.5.21 @@ -3607,7 +3601,7 @@ snapshots: asynckit@0.4.0: {} - axios@1.11.0: + axios@1.12.2: dependencies: follow-redirects: 1.15.11 form-data: 4.0.4 @@ -3617,6 +3611,8 @@ snapshots: balanced-match@1.0.2: {} + baseline-browser-mapping@2.8.6: {} + binary-extensions@2.3.0: {} boolbase@1.0.0: {} @@ -3634,12 +3630,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.25.4: + browserslist@4.26.2: dependencies: - caniuse-lite: 1.0.30001739 - electron-to-chromium: 1.5.213 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.4) + baseline-browser-mapping: 2.8.6 + caniuse-lite: 1.0.30001743 + electron-to-chromium: 1.5.222 + node-releases: 2.0.21 + update-browserslist-db: 1.1.3(browserslist@4.26.2) buffer-crc32@0.2.13: {} @@ -3656,7 +3653,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001739: {} + caniuse-lite@1.0.30001743: {} ccount@2.0.1: {} @@ -3744,7 +3741,7 @@ snapshots: core-js-compat@3.45.1: dependencies: - browserslist: 4.25.4 + browserslist: 4.26.2 cross-spawn@7.0.6: dependencies: @@ -3787,7 +3784,7 @@ snapshots: de-indent@1.0.2: {} - debug@4.4.1: + debug@4.4.3: dependencies: ms: 2.1.3 @@ -3838,7 +3835,7 @@ snapshots: duplexer@0.1.2: {} - electron-to-chromium@1.5.213: {} + electron-to-chromium@1.5.222: {} empathic@2.0.0: {} @@ -3875,34 +3872,34 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 - esbuild@0.25.9: + esbuild@0.25.10: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.9 - '@esbuild/android-arm': 0.25.9 - '@esbuild/android-arm64': 0.25.9 - '@esbuild/android-x64': 0.25.9 - '@esbuild/darwin-arm64': 0.25.9 - '@esbuild/darwin-x64': 0.25.9 - '@esbuild/freebsd-arm64': 0.25.9 - '@esbuild/freebsd-x64': 0.25.9 - '@esbuild/linux-arm': 0.25.9 - '@esbuild/linux-arm64': 0.25.9 - '@esbuild/linux-ia32': 0.25.9 - '@esbuild/linux-loong64': 0.25.9 - '@esbuild/linux-mips64el': 0.25.9 - '@esbuild/linux-ppc64': 0.25.9 - '@esbuild/linux-riscv64': 0.25.9 - '@esbuild/linux-s390x': 0.25.9 - '@esbuild/linux-x64': 0.25.9 - '@esbuild/netbsd-arm64': 0.25.9 - '@esbuild/netbsd-x64': 0.25.9 - '@esbuild/openbsd-arm64': 0.25.9 - '@esbuild/openbsd-x64': 0.25.9 - '@esbuild/openharmony-arm64': 0.25.9 - '@esbuild/sunos-x64': 0.25.9 - '@esbuild/win32-arm64': 0.25.9 - '@esbuild/win32-ia32': 0.25.9 - '@esbuild/win32-x64': 0.25.9 + '@esbuild/aix-ppc64': 0.25.10 + '@esbuild/android-arm': 0.25.10 + '@esbuild/android-arm64': 0.25.10 + '@esbuild/android-x64': 0.25.10 + '@esbuild/darwin-arm64': 0.25.10 + '@esbuild/darwin-x64': 0.25.10 + '@esbuild/freebsd-arm64': 0.25.10 + '@esbuild/freebsd-x64': 0.25.10 + '@esbuild/linux-arm': 0.25.10 + '@esbuild/linux-arm64': 0.25.10 + '@esbuild/linux-ia32': 0.25.10 + '@esbuild/linux-loong64': 0.25.10 + '@esbuild/linux-mips64el': 0.25.10 + '@esbuild/linux-ppc64': 0.25.10 + '@esbuild/linux-riscv64': 0.25.10 + '@esbuild/linux-s390x': 0.25.10 + '@esbuild/linux-x64': 0.25.10 + '@esbuild/netbsd-arm64': 0.25.10 + '@esbuild/netbsd-x64': 0.25.10 + '@esbuild/openbsd-arm64': 0.25.10 + '@esbuild/openbsd-x64': 0.25.10 + '@esbuild/openharmony-arm64': 0.25.10 + '@esbuild/sunos-x64': 0.25.10 + '@esbuild/win32-arm64': 0.25.10 + '@esbuild/win32-ia32': 0.25.10 + '@esbuild/win32-x64': 0.25.10 escalade@3.2.0: {} @@ -3912,91 +3909,91 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-compat-utils@0.5.1(eslint@9.34.0(jiti@2.5.1)): + eslint-compat-utils@0.5.1(eslint@9.35.0(jiti@2.5.1)): dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) semver: 7.7.2 - eslint-compat-utils@0.6.5(eslint@9.34.0(jiti@2.5.1)): + eslint-compat-utils@0.6.5(eslint@9.35.0(jiti@2.5.1)): dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) semver: 7.7.2 - eslint-config-flat-gitignore@2.1.0(eslint@9.34.0(jiti@2.5.1)): + eslint-config-flat-gitignore@2.1.0(eslint@9.35.0(jiti@2.5.1)): dependencies: - '@eslint/compat': 1.3.2(eslint@9.34.0(jiti@2.5.1)) - eslint: 9.34.0(jiti@2.5.1) + '@eslint/compat': 1.3.2(eslint@9.35.0(jiti@2.5.1)) + eslint: 9.35.0(jiti@2.5.1) eslint-flat-config-utils@2.1.1: dependencies: pathe: 2.0.3 - eslint-formatting-reporter@0.0.0(eslint@9.34.0(jiti@2.5.1)): + eslint-formatting-reporter@0.0.0(eslint@9.35.0(jiti@2.5.1)): dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) prettier-linter-helpers: 1.0.0 - eslint-json-compat-utils@0.2.1(eslint@9.34.0(jiti@2.5.1))(jsonc-eslint-parser@2.4.0): + eslint-json-compat-utils@0.2.1(eslint@9.35.0(jiti@2.5.1))(jsonc-eslint-parser@2.4.0): dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) esquery: 1.6.0 jsonc-eslint-parser: 2.4.0 - eslint-merge-processors@2.0.0(eslint@9.34.0(jiti@2.5.1)): + eslint-merge-processors@2.0.0(eslint@9.35.0(jiti@2.5.1)): dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) eslint-parser-plain@0.1.1: {} - eslint-plugin-antfu@3.1.1(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-antfu@3.1.1(eslint@9.35.0(jiti@2.5.1)): dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) - eslint-plugin-command@3.3.1(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-command@3.3.1(eslint@9.35.0(jiti@2.5.1)): dependencies: '@es-joy/jsdoccomment': 0.50.2 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) - eslint-plugin-es-x@7.8.0(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-es-x@7.8.0(eslint@9.35.0(jiti@2.5.1)): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) '@eslint-community/regexpp': 4.12.1 - eslint: 9.34.0(jiti@2.5.1) - eslint-compat-utils: 0.5.1(eslint@9.34.0(jiti@2.5.1)) + eslint: 9.35.0(jiti@2.5.1) + eslint-compat-utils: 0.5.1(eslint@9.35.0(jiti@2.5.1)) - eslint-plugin-es@3.0.1(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-es@3.0.1(eslint@9.35.0(jiti@2.5.1)): dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) eslint-utils: 2.1.0 regexpp: 3.2.0 - eslint-plugin-format@1.0.1(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-format@1.0.1(eslint@9.35.0(jiti@2.5.1)): dependencies: '@dprint/formatter': 0.3.0 '@dprint/markdown': 0.17.8 '@dprint/toml': 0.6.4 - eslint: 9.34.0(jiti@2.5.1) - eslint-formatting-reporter: 0.0.0(eslint@9.34.0(jiti@2.5.1)) + eslint: 9.35.0(jiti@2.5.1) + eslint-formatting-reporter: 0.0.0(eslint@9.35.0(jiti@2.5.1)) eslint-parser-plain: 0.1.1 prettier: 3.6.2 synckit: 0.9.3 - eslint-plugin-import-lite@0.3.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2): + eslint-plugin-import-lite@0.3.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) - '@typescript-eslint/types': 8.42.0 - eslint: 9.34.0(jiti@2.5.1) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) + '@typescript-eslint/types': 8.44.0 + eslint: 9.35.0(jiti@2.5.1) optionalDependencies: typescript: 5.9.2 - eslint-plugin-jsdoc@52.0.4(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-jsdoc@54.7.0(eslint@9.35.0(jiti@2.5.1)): dependencies: - '@es-joy/jsdoccomment': 0.52.0 + '@es-joy/jsdoccomment': 0.56.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.4.1 + debug: 4.4.3 escape-string-regexp: 4.0.0 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) espree: 10.4.0 esquery: 1.6.0 parse-imports-exports: 0.2.4 @@ -4005,12 +4002,12 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-jsonc@2.20.1(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-jsonc@2.20.1(eslint@9.35.0(jiti@2.5.1)): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) - eslint: 9.34.0(jiti@2.5.1) - eslint-compat-utils: 0.6.5(eslint@9.34.0(jiti@2.5.1)) - eslint-json-compat-utils: 0.2.1(eslint@9.34.0(jiti@2.5.1))(jsonc-eslint-parser@2.4.0) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) + eslint: 9.35.0(jiti@2.5.1) + eslint-compat-utils: 0.6.5(eslint@9.35.0(jiti@2.5.1)) + eslint-json-compat-utils: 0.2.1(eslint@9.35.0(jiti@2.5.1))(jsonc-eslint-parser@2.4.0) espree: 10.4.0 graphemer: 1.4.0 jsonc-eslint-parser: 2.4.0 @@ -4019,12 +4016,12 @@ snapshots: transitivePeerDependencies: - '@eslint/json' - eslint-plugin-n@17.21.3(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2): + eslint-plugin-n@17.23.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) enhanced-resolve: 5.18.3 - eslint: 9.34.0(jiti@2.5.1) - eslint-plugin-es-x: 7.8.0(eslint@9.34.0(jiti@2.5.1)) + eslint: 9.35.0(jiti@2.5.1) + eslint-plugin-es-x: 7.8.0(eslint@9.35.0(jiti@2.5.1)) get-tsconfig: 4.10.1 globals: 15.15.0 globrex: 0.1.2 @@ -4036,74 +4033,74 @@ snapshots: eslint-plugin-no-only-tests@3.3.0: {} - eslint-plugin-node@11.1.0(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-node@11.1.0(eslint@9.35.0(jiti@2.5.1)): dependencies: - eslint: 9.34.0(jiti@2.5.1) - eslint-plugin-es: 3.0.1(eslint@9.34.0(jiti@2.5.1)) + eslint: 9.35.0(jiti@2.5.1) + eslint-plugin-es: 3.0.1(eslint@9.35.0(jiti@2.5.1)) eslint-utils: 2.1.0 ignore: 5.3.2 minimatch: 3.1.2 resolve: 1.22.10 semver: 6.3.1 - eslint-plugin-perfectionist@4.15.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2): + eslint-plugin-perfectionist@4.15.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2): dependencies: - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/utils': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) - eslint: 9.34.0(jiti@2.5.1) + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/utils': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + eslint: 9.35.0(jiti@2.5.1) natural-orderby: 5.0.0 transitivePeerDependencies: - supports-color - typescript - eslint-plugin-pnpm@1.1.1(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-pnpm@1.1.1(eslint@9.35.0(jiti@2.5.1)): dependencies: empathic: 2.0.0 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) jsonc-eslint-parser: 2.4.0 pathe: 2.0.3 pnpm-workspace-yaml: 1.1.1 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 yaml-eslint-parser: 1.3.0 - eslint-plugin-regexp@2.10.0(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-regexp@2.10.0(eslint@9.35.0(jiti@2.5.1)): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) '@eslint-community/regexpp': 4.12.1 comment-parser: 1.4.1 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) jsdoc-type-pratt-parser: 4.8.0 refa: 0.12.1 regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-simple-import-sort@12.1.1(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-simple-import-sort@12.1.1(eslint@9.35.0(jiti@2.5.1)): dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) - eslint-plugin-toml@0.12.0(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-toml@0.12.0(eslint@9.35.0(jiti@2.5.1)): dependencies: - debug: 4.4.1 - eslint: 9.34.0(jiti@2.5.1) - eslint-compat-utils: 0.6.5(eslint@9.34.0(jiti@2.5.1)) + debug: 4.4.3 + eslint: 9.35.0(jiti@2.5.1) + eslint-compat-utils: 0.6.5(eslint@9.35.0(jiti@2.5.1)) lodash: 4.17.21 toml-eslint-parser: 0.10.0 transitivePeerDependencies: - supports-color - eslint-plugin-unicorn@60.0.0(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-unicorn@61.0.2(eslint@9.35.0(jiti@2.5.1)): dependencies: '@babel/helper-validator-identifier': 7.27.1 - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) '@eslint/plugin-kit': 0.3.5 change-case: 5.4.4 ci-info: 4.3.0 clean-regexp: 1.0.0 core-js-compat: 3.45.1 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) esquery: 1.6.0 find-up-simple: 1.0.1 - globals: 16.3.0 + globals: 16.4.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 jsesc: 3.1.0 @@ -4111,42 +4108,42 @@ snapshots: regexp-tree: 0.1.27 regjsparser: 0.12.0 semver: 7.7.2 - strip-indent: 4.0.0 + strip-indent: 4.1.0 - eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1)): dependencies: - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/eslint-plugin': 8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) - eslint-plugin-vue@10.4.0(@typescript-eslint/parser@8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(vue-eslint-parser@10.2.0(eslint@9.34.0(jiti@2.5.1))): + eslint-plugin-vue@10.4.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(vue-eslint-parser@10.2.0(eslint@9.35.0(jiti@2.5.1))): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) - eslint: 9.34.0(jiti@2.5.1) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) + eslint: 9.35.0(jiti@2.5.1) natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 semver: 7.7.2 - vue-eslint-parser: 10.2.0(eslint@9.34.0(jiti@2.5.1)) + vue-eslint-parser: 10.2.0(eslint@9.35.0(jiti@2.5.1)) xml-name-validator: 4.0.0 optionalDependencies: - '@typescript-eslint/parser': 8.42.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/parser': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) - eslint-plugin-yml@1.18.0(eslint@9.34.0(jiti@2.5.1)): + eslint-plugin-yml@1.18.0(eslint@9.35.0(jiti@2.5.1)): dependencies: - debug: 4.4.1 + debug: 4.4.3 escape-string-regexp: 4.0.0 - eslint: 9.34.0(jiti@2.5.1) - eslint-compat-utils: 0.6.5(eslint@9.34.0(jiti@2.5.1)) + eslint: 9.35.0(jiti@2.5.1) + eslint-compat-utils: 0.6.5(eslint@9.35.0(jiti@2.5.1)) natural-compare: 1.4.0 yaml-eslint-parser: 1.3.0 transitivePeerDependencies: - supports-color - eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.21)(eslint@9.34.0(jiti@2.5.1)): + eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.21)(eslint@9.35.0(jiti@2.5.1)): dependencies: '@vue/compiler-sfc': 3.5.21 - eslint: 9.34.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) eslint-scope@8.4.0: dependencies: @@ -4163,17 +4160,17 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.34.0(jiti@2.5.1): + eslint@9.35.0(jiti@2.5.1): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 '@eslint/config-helpers': 0.3.1 '@eslint/core': 0.15.2 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.34.0 + '@eslint/js': 9.35.0 '@eslint/plugin-kit': 0.3.5 - '@humanfs/node': 0.16.6 + '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 @@ -4181,7 +4178,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -4239,7 +4236,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.4.1 + debug: 4.4.3 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -4364,7 +4361,7 @@ snapshots: globals@15.15.0: {} - globals@16.3.0: {} + globals@16.4.0: {} globrex@0.1.2: {} @@ -4454,6 +4451,8 @@ snapshots: jsdoc-type-pratt-parser@4.8.0: {} + jsdoc-type-pratt-parser@5.1.1: {} + jsesc@3.0.2: {} jsesc@3.1.0: {} @@ -4503,7 +4502,7 @@ snapshots: longest-streak@3.1.0: {} - magic-string@0.30.18: + magic-string@0.30.19: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -4811,7 +4810,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.4.1 + debug: 4.4.3 decode-named-character-reference: 1.2.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -4841,8 +4840,6 @@ snapshots: dependencies: mime-db: 1.52.0 - min-indent@1.0.1: {} - minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -4890,7 +4887,7 @@ snapshots: node-fetch-native@1.6.7: {} - node-releases@2.0.19: {} + node-releases@2.0.21: {} normalize-path@3.0.0: {} @@ -5059,39 +5056,39 @@ snapshots: reusify@1.1.0: {} - rollup-plugin-dts@6.2.3(rollup@4.50.0)(typescript@5.9.2): + rollup-plugin-dts@6.2.3(rollup@4.51.0)(typescript@5.9.2): dependencies: - magic-string: 0.30.18 - rollup: 4.50.0 + magic-string: 0.30.19 + rollup: 4.51.0 typescript: 5.9.2 optionalDependencies: '@babel/code-frame': 7.27.1 - rollup@4.50.0: + rollup@4.51.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.50.0 - '@rollup/rollup-android-arm64': 4.50.0 - '@rollup/rollup-darwin-arm64': 4.50.0 - '@rollup/rollup-darwin-x64': 4.50.0 - '@rollup/rollup-freebsd-arm64': 4.50.0 - '@rollup/rollup-freebsd-x64': 4.50.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.50.0 - '@rollup/rollup-linux-arm-musleabihf': 4.50.0 - '@rollup/rollup-linux-arm64-gnu': 4.50.0 - '@rollup/rollup-linux-arm64-musl': 4.50.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.50.0 - '@rollup/rollup-linux-ppc64-gnu': 4.50.0 - '@rollup/rollup-linux-riscv64-gnu': 4.50.0 - '@rollup/rollup-linux-riscv64-musl': 4.50.0 - '@rollup/rollup-linux-s390x-gnu': 4.50.0 - '@rollup/rollup-linux-x64-gnu': 4.50.0 - '@rollup/rollup-linux-x64-musl': 4.50.0 - '@rollup/rollup-openharmony-arm64': 4.50.0 - '@rollup/rollup-win32-arm64-msvc': 4.50.0 - '@rollup/rollup-win32-ia32-msvc': 4.50.0 - '@rollup/rollup-win32-x64-msvc': 4.50.0 + '@rollup/rollup-android-arm-eabi': 4.51.0 + '@rollup/rollup-android-arm64': 4.51.0 + '@rollup/rollup-darwin-arm64': 4.51.0 + '@rollup/rollup-darwin-x64': 4.51.0 + '@rollup/rollup-freebsd-arm64': 4.51.0 + '@rollup/rollup-freebsd-x64': 4.51.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.51.0 + '@rollup/rollup-linux-arm-musleabihf': 4.51.0 + '@rollup/rollup-linux-arm64-gnu': 4.51.0 + '@rollup/rollup-linux-arm64-musl': 4.51.0 + '@rollup/rollup-linux-loong64-gnu': 4.51.0 + '@rollup/rollup-linux-ppc64-gnu': 4.51.0 + '@rollup/rollup-linux-riscv64-gnu': 4.51.0 + '@rollup/rollup-linux-riscv64-musl': 4.51.0 + '@rollup/rollup-linux-s390x-gnu': 4.51.0 + '@rollup/rollup-linux-x64-gnu': 4.51.0 + '@rollup/rollup-linux-x64-musl': 4.51.0 + '@rollup/rollup-openharmony-arm64': 4.51.0 + '@rollup/rollup-win32-arm64-msvc': 4.51.0 + '@rollup/rollup-win32-ia32-msvc': 4.51.0 + '@rollup/rollup-win32-x64-msvc': 4.51.0 fsevents: 2.3.3 run-parallel@1.2.0: @@ -5100,7 +5097,7 @@ snapshots: safer-buffer@2.1.2: {} - sass@1.92.0: + sass@1.92.1: dependencies: chokidar: 4.0.3 immutable: 5.1.3 @@ -5126,7 +5123,7 @@ snapshots: shebang-regex@3.0.0: {} - sirv@3.0.1: + sirv@3.0.2: dependencies: '@polka/url': 1.0.0-next.29 mrmime: 2.0.1 @@ -5152,9 +5149,7 @@ snapshots: spdx-license-ids@3.0.22: {} - strip-indent@4.0.0: - dependencies: - min-indent: 1.0.1 + strip-indent@4.1.0: {} strip-json-comments@3.1.1: {} @@ -5207,7 +5202,7 @@ snapshots: tinyexec@1.0.1: {} - tinyglobby@0.2.14: + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 @@ -5248,26 +5243,26 @@ snapshots: jiti: 2.5.1 quansync: 0.2.11 - undici-types@7.10.0: {} + undici-types@7.12.0: {} undici@6.21.3: {} - unimport@5.2.0: + unimport@5.3.0: dependencies: acorn: 8.15.0 escape-string-regexp: 5.0.0 estree-walker: 3.0.3 local-pkg: 1.1.2 - magic-string: 0.30.18 + magic-string: 0.30.19 mlly: 1.8.0 pathe: 2.0.3 picomatch: 4.0.3 pkg-types: 2.3.0 scule: 1.3.0 strip-literal: 3.0.0 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 unplugin: 2.3.10 - unplugin-utils: 0.2.5 + unplugin-utils: 0.3.0 unist-util-is@6.0.0: dependencies: @@ -5288,29 +5283,29 @@ snapshots: unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - unocss@66.5.0(postcss@8.5.6)(vite@7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1)): - dependencies: - '@unocss/astro': 66.5.0(vite@7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1)) - '@unocss/cli': 66.5.0 - '@unocss/core': 66.5.0 - '@unocss/postcss': 66.5.0(postcss@8.5.6) - '@unocss/preset-attributify': 66.5.0 - '@unocss/preset-icons': 66.5.0 - '@unocss/preset-mini': 66.5.0 - '@unocss/preset-tagify': 66.5.0 - '@unocss/preset-typography': 66.5.0 - '@unocss/preset-uno': 66.5.0 - '@unocss/preset-web-fonts': 66.5.0 - '@unocss/preset-wind': 66.5.0 - '@unocss/preset-wind3': 66.5.0 - '@unocss/preset-wind4': 66.5.0 - '@unocss/transformer-attributify-jsx': 66.5.0 - '@unocss/transformer-compile-class': 66.5.0 - '@unocss/transformer-directives': 66.5.0 - '@unocss/transformer-variant-group': 66.5.0 - '@unocss/vite': 66.5.0(vite@7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1)) + unocss@66.5.1(postcss@8.5.6)(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)): + dependencies: + '@unocss/astro': 66.5.1(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)) + '@unocss/cli': 66.5.1 + '@unocss/core': 66.5.1 + '@unocss/postcss': 66.5.1(postcss@8.5.6) + '@unocss/preset-attributify': 66.5.1 + '@unocss/preset-icons': 66.5.1 + '@unocss/preset-mini': 66.5.1 + '@unocss/preset-tagify': 66.5.1 + '@unocss/preset-typography': 66.5.1 + '@unocss/preset-uno': 66.5.1 + '@unocss/preset-web-fonts': 66.5.1 + '@unocss/preset-wind': 66.5.1 + '@unocss/preset-wind3': 66.5.1 + '@unocss/preset-wind4': 66.5.1 + '@unocss/transformer-attributify-jsx': 66.5.1 + '@unocss/transformer-compile-class': 66.5.1 + '@unocss/transformer-directives': 66.5.1 + '@unocss/transformer-variant-group': 66.5.1 + '@unocss/vite': 66.5.1(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)) optionalDependencies: - vite: 7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1) + vite: 7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1) transitivePeerDependencies: - postcss - supports-color @@ -5318,19 +5313,14 @@ snapshots: unplugin-auto-import@20.1.0(@vueuse/core@13.9.0(vue@3.5.21(typescript@5.9.2))): dependencies: local-pkg: 1.1.2 - magic-string: 0.30.18 + magic-string: 0.30.19 picomatch: 4.0.3 - unimport: 5.2.0 + unimport: 5.3.0 unplugin: 2.3.10 unplugin-utils: 0.3.0 optionalDependencies: '@vueuse/core': 13.9.0(vue@3.5.21(typescript@5.9.2)) - unplugin-utils@0.2.5: - dependencies: - pathe: 2.0.3 - picomatch: 4.0.3 - unplugin-utils@0.3.0: dependencies: pathe: 2.0.3 @@ -5343,9 +5333,9 @@ snapshots: picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 - update-browserslist-db@1.1.3(browserslist@4.25.4): + update-browserslist-db@1.1.3(browserslist@4.26.2): dependencies: - browserslist: 4.25.4 + browserslist: 4.26.2 escalade: 3.2.0 picocolors: 1.1.1 @@ -5355,28 +5345,28 @@ snapshots: util-deprecate@1.0.2: {} - vite@7.1.4(@types/node@24.3.0)(jiti@2.5.1)(sass@1.92.0)(terser@5.44.0)(yaml@2.8.1): + vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1): dependencies: - esbuild: 0.25.9 + esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.50.0 - tinyglobby: 0.2.14 + rollup: 4.51.0 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.3.0 + '@types/node': 24.5.2 fsevents: 2.3.3 jiti: 2.5.1 - sass: 1.92.0 + sass: 1.92.1 terser: 5.44.0 yaml: 2.8.1 vscode-uri@3.1.0: {} - vue-eslint-parser@10.2.0(eslint@9.34.0(jiti@2.5.1)): + vue-eslint-parser@10.2.0(eslint@9.35.0(jiti@2.5.1)): dependencies: - debug: 4.4.1 - eslint: 9.34.0(jiti@2.5.1) + debug: 4.4.3 + eslint: 9.35.0(jiti@2.5.1) eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -5392,10 +5382,10 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.21(typescript@5.9.2) - vue-tsc@3.0.6(typescript@5.9.2): + vue-tsc@3.0.7(typescript@5.9.2): dependencies: '@volar/typescript': 2.4.23 - '@vue/language-core': 3.0.6(typescript@5.9.2) + '@vue/language-core': 3.0.7(typescript@5.9.2) typescript: 5.9.2 vue@3.5.21(typescript@5.9.2): diff --git a/jetv-ui/src/assets/jet-icons.json b/jetv-ui/src/assets/jet-icons.json index e84ef58..b841f91 100644 --- a/jetv-ui/src/assets/jet-icons.json +++ b/jetv-ui/src/assets/jet-icons.json @@ -1,6 +1,6 @@ { "prefix": "jet", - "lastModified": 1758096806, + "lastModified": 1758252197, "icons": { "add": { "body": "" @@ -8,6 +8,12 @@ "add-dark": { "body": "" }, + "anytype": { + "body": "" + }, + "anytype-dark": { + "body": "" + }, "checked": { "body": "" }, diff --git a/jetv-ui/src/components/Button/JeButton.vue b/jetv-ui/src/components/Button/JeButton.vue index 8dadb22..fc8cab4 100644 --- a/jetv-ui/src/components/Button/JeButton.vue +++ b/jetv-ui/src/components/Button/JeButton.vue @@ -41,7 +41,7 @@ withDefaults(defineProps(), { // Secondary 按钮类型样式 &--secondary:not(:disabled), &--secondary-alt:not(:disabled) { - @apply outline-offset-0; + @apply outline-offset--1px; // light @apply light:color-$gray-1; diff --git a/jetv-ui/src/components/Button/JeCheckbox.vue b/jetv-ui/src/components/Button/JeCheckbox.vue index ac858d4..e5ab222 100644 --- a/jetv-ui/src/components/Button/JeCheckbox.vue +++ b/jetv-ui/src/components/Button/JeCheckbox.vue @@ -1,18 +1,21 @@ @@ -25,6 +28,7 @@ function handleChange(event: Event) { :checked="modelValue" :disabled="disabled" @change="handleChange" + @keydown.enter.prevent="handleKeydownEnter" > @@ -48,7 +52,7 @@ function handleChange(event: Event) { @apply dark:bg-$gray-2 dark:outline-$gray-6; } -// 激活状态 +// Active states .je-checkbox__input:not(:disabled) { &:not(:checked) { @apply light:hover:outline-$gray-6 light:focus:outline-$blue-4; @@ -63,13 +67,13 @@ function handleChange(event: Event) { @apply light:hover:bg-$blue-3 light:focus:outline-$blue-4; @apply dark:hover:bg-$blue-5 dark:focus:outline-$blue-6; - // 选中状态 + // Checked state &:not(.je-checkbox__input--indeterminate) { @apply light:bg-$blue-4 dark:bg-$blue-6; @apply i-jet:checked; } - // Indeterminate 状态 + // Indeterminate state &.je-checkbox__input--indeterminate { @apply light:bg-$blue-4 dark:bg-$blue-6; @apply i-jet:remove; @@ -77,20 +81,30 @@ function handleChange(event: Event) { } } -// 禁用状态样式 +// Disabled styles +.je-checkbox__input:disabled { + @apply light:bg-$gray-13 light:outline-$gray-9; + @apply dark:bg-$gray-2 dark:outline-$gray-5; +} + .je-checkbox__input:disabled:checked { - @apply outline-none text-20px; + @apply outline-none text-20px opacity-70; // soften in disabled - // 选中状态 + // Checked state &:not(.je-checkbox__input--indeterminate) { + // Filled but muted background and outline + @apply light:bg-$gray-11 light:outline-$gray-9; + @apply dark:bg-$gray-3 dark:outline-$gray-5; + + // Keep a visible but subtle check icon @apply light:i-jet:checked dark:i-jet:checked-disabled-dark; - @apply light:bg-$gray-9 dark:bg-$gray-3; } - // Indeterminate 状态 + // Indeterminate state &.je-checkbox__input--indeterminate { + @apply light:bg-$gray-11 light:outline-$gray-9; + @apply dark:bg-$gray-3 dark:outline-$gray-5; @apply light:i-jet:remove dark:i-jet:remove-disabled-dark; - @apply light:bg-$gray-9 dark:bg-$gray-3; } } diff --git a/jetv-ui/src/components/Button/JeSlimButton.vue b/jetv-ui/src/components/Button/JeSlimButton.vue index 3aa23d4..1262d76 100644 --- a/jetv-ui/src/components/Button/JeSlimButton.vue +++ b/jetv-ui/src/components/Button/JeSlimButton.vue @@ -21,7 +21,7 @@ withDefaults(defineProps(), { diff --git a/jetv-ui/src/components/Input/JeFileInputField.vue b/jetv-ui/src/components/Input/JeFileInputField.vue index c01d082..10af041 100644 --- a/jetv-ui/src/components/Input/JeFileInputField.vue +++ b/jetv-ui/src/components/Input/JeFileInputField.vue @@ -5,22 +5,36 @@ import type { JeFileInputFieldProps } from './types.ts' const props = withDefaults(defineProps(), { validated: false, disabled: false, + mode: 'folder', }) const emit = defineEmits(['update:modelValue', 'update:validated']) -const folderPath = ref(props.modelValue) - -// 监听 folderPath 的变化,将值传递回父组件 -watch(folderPath, (newValue) => { - emit('update:modelValue', newValue) +const filePath = computed({ + get: () => props.modelValue, + set: val => emit('update:modelValue', val), }) -// 打开文件夹选择对话框 -async function openFolder() { - if (!props.disabled) { - const selectedPaths = await window.api.openFolderDialog() - if (selectedPaths.length > 0) { - folderPath.value = selectedPaths[0] +// 打开文件/文件夹选择对话框 +async function openPicker() { + if (props.disabled) { + return + } + + if (props.mode === 'file') { + const selectedPaths = await window.api.openFileDialog({ + title: props.dialogTitle, + fileTypes: props.fileTypes, + }) + if (selectedPaths && selectedPaths.length > 0) { + filePath.value = selectedPaths[0] + } + } + else { + const selectedPaths = await window.api.openFolderDialog({ + title: props.dialogTitle, + }) + if (selectedPaths && selectedPaths.length > 0) { + filePath.value = selectedPaths[0] } } } @@ -30,7 +44,7 @@ async function openFolder() { - + @@ -58,6 +76,10 @@ async function openFolder() { @apply relative flex-items-center; } +.je-file-input-filed__input :deep(.je-input-field__input) { + @apply w-full pr-27px; +} + .je-file-input-filed__icon-wrapper { @apply absolute right-5px top-50% translate-y--50%; @apply size-19px rounded-3px; @@ -88,10 +110,10 @@ async function openFolder() { @apply light:i-jet:folder dark:i-jet:folder-dark; } - - diff --git a/jetv-ui/src/components/Input/JeSearchField.vue b/jetv-ui/src/components/Input/JeSearchField.vue index 928e6cc..488f6f7 100644 --- a/jetv-ui/src/components/Input/JeSearchField.vue +++ b/jetv-ui/src/components/Input/JeSearchField.vue @@ -9,11 +9,9 @@ const props = withDefaults(defineProps(), { }) const emit = defineEmits(['update:modelValue', 'update:validated']) -const searchContent = ref(props.modelValue) - -// 监听 searchContent 的变化,将值传递回父组件 -watch(searchContent, (newValue) => { - emit('update:modelValue', newValue) +const searchContent = computed({ + get: () => props.modelValue, + set: val => emit('update:modelValue', val), }) function clearInput() { @@ -61,6 +59,16 @@ function clearInput() { @apply light:i-jet:search dark:i-jet:search-dark; } +:deep(.je-input-field__input) { + .je-search-filed__input & { + @apply m-0 pl-25px pr-23px; + } + + .je-search-filed__input--in-editor & { + @apply outline-0; + } +} + .je-search-filed__icon-clear { @apply absolute top-0 bottom-0 right-0; @apply mx-3px my-auto; @@ -81,15 +89,3 @@ function clearInput() { } } - - diff --git a/jetv-ui/src/components/Input/types.ts b/jetv-ui/src/components/Input/types.ts index 8c7b0f1..54e680d 100644 --- a/jetv-ui/src/components/Input/types.ts +++ b/jetv-ui/src/components/Input/types.ts @@ -223,6 +223,24 @@ export interface JeFileInputFieldProps { */ modelValue: string | null + /** + * 选择模式:文件夹或文件 + * - 默认为 'folder' + */ + mode?: 'folder' | 'file' + + /** + * 对话框标题 + */ + dialogTitle?: string + + /** + * 在文件模式下可选的文件类型过滤器。 + * 仅当 selectType 为 'file' 时生效,将透传给 openFileDialog 以限制可选扩展名。 + * 例如:[{ name: 'JSON', extensions: ['json'] }] + */ + fileTypes?: { name: string, extensions: string[] }[] + /** * 文件输入字段的验证状态。 * diff --git a/jetv-ui/src/components/Menu/JeMiniMenu.vue b/jetv-ui/src/components/Menu/JeMiniMenu.vue index 82c76f8..1968245 100644 --- a/jetv-ui/src/components/Menu/JeMiniMenu.vue +++ b/jetv-ui/src/components/Menu/JeMiniMenu.vue @@ -23,9 +23,9 @@ const visibleProxy = computed({ /> - - diff --git a/src/components/SettingsGroup.vue b/src/components/SettingsGroup.vue new file mode 100644 index 0000000..1454bc8 --- /dev/null +++ b/src/components/SettingsGroup.vue @@ -0,0 +1,21 @@ + + + diff --git a/src/global.d.ts b/src/global.d.ts index 478acdc..49f58b0 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -1,96 +1,162 @@ import type { ThemeEnum } from '~/constants/appEnums' +import type { DataFileEnum } from '~/stores/helpers/persistence' +import type { ScannerSettings } from '~/stores/settingsStore' import type { LinguistResult } from '~/views/ProjectEditorView' +/** + * 通用/基础类型 + */ +type HexColor = `#${string}` +type Unlisten = () => void +interface ErrorResult { error: string } + +/** + * 对话框 + */ +interface DialogOpenOptions { + title?: string +} +interface FileTypeFilter { + name: string + extensions: string[] +} +interface FileDialogOptions extends DialogOpenOptions { + fileTypes?: FileTypeFilter[] +} + +/** + * 路径与文件 + */ +interface PathExistenceResult { + exists: boolean + error?: string +} + +/** + * 项目分析 + */ +type ProjectAnalyzeStage = 'start' | 'checking' | 'analyzing' | 'done' +interface ProjectAnalyzeProgress { + folderPath: string + stage: ProjectAnalyzeStage +} +interface LicenseReadResult { + success: boolean + filename?: string + snippet?: string + lines?: number + message?: string +} + +/** + * 数据存取 + */ +interface BasicResult { + success: boolean + error?: string +} +interface DataResult { + success: boolean + data?: string + error?: string +} + +/** + * 更新检查 + */ +interface UpdateCheckResult { + hasUpdate: boolean + currentVersion: string + latestVersion?: string + url?: string + name?: string + notes?: string + publishedAt?: string + error?: string +} + +/** + * 扫描(批量 & 流式) + */ +interface LangGroupItem { + text: string + color: HexColor + percentage: number +} +interface ScanItem { + path: string + name: string + mainLang?: string + mainLangColor?: HexColor + langGroup?: LangGroupItem[] + ide?: string | null // CodeEditorEnum,例如 "visual-studio-code" + error?: string +} +export interface ScanStartPayload extends Omit { + existingPaths: string[] +} +interface ScanSession { + sessionId: number +} +interface ScannerItemEvent { + sessionId: number + item: ScanItem +} +interface ScannerDoneEvent { + sessionId: number +} +interface ScannerErrorEvent { + sessionId: number + error: string +} + declare global { interface Window { api: { - // dialog - openFolderDialog: () => Promise - openFileDialog: (fileTypes?: { name: string, extensions: string[] }[]) => Promise - - // folder - getFolderList: (folderPath: string) => Promise<{ folders: string[], error?: string }> + // ========= dialog ========= + openFolderDialog: (options?: DialogOpenOptions) => Promise + openFileDialog: (options?: FileDialogOptions) => Promise - // path + // ========= path ========= formatPath: (filePath: string) => Promise - checkPathExistence: (path: string) => Promise<{ exists: boolean, error?: string }> - - // project - analyzeProject: (folderPath: string) => Promise - onProjectAnalyzeProgress: (cb: (data: { folderPath: string, stage: 'start' | 'checking' | 'analyzing' | 'done' }) => void) => () => void - readProjectLicense: (folderPath: string, maxLines?: number) => Promise<{ - success: boolean - filename?: string - snippet?: string - lines?: number - message?: string - }> + checkPathExistence: (path: string) => Promise + + // ========= project ========= + analyzeProject: (folderPath: string) => Promise + onProjectAnalyzeProgress: (cb: (data: ProjectAnalyzeProgress) => void) => Unlisten + readProjectLicense: (folderPath: string, maxLines?: number) => Promise openProject: (idePath: string, projectPath: string) => Promise deleteProject: (projectPath: string) => Promise importProject: () => Promise exportProject: () => Promise - // settings - openSettingsJSON: () => Promise - - // data - saveData: (fileType: string, data: string) => Promise<{ success: boolean, error?: string }> - loadData: (fileType: string) => Promise<{ success: boolean, data?: string, error?: string }> - deleteData: (fileType: string) => Promise<{ success: boolean, error?: string }> + // ========= data ========= + saveData: (fileType: DataFileEnum, data: string) => Promise + loadData: (fileType: DataFileEnum) => Promise + openData: (fileType: DataFileEnum) => Promise + deleteData: (fileType: DataFileEnum) => Promise - // system + // ========= system ========= openExternal: (url: string) => void openInExplorer: (path: string) => void openInTerminal: (path: string) => void - // update - checkUpdate: () => Promise<{ - hasUpdate: boolean - currentVersion: string - latestVersion?: string - url?: string - name?: string - notes?: string - publishedAt?: string - error?: string - }> - - // scanner (batch) - scanProjects: (payload: { roots: string[], existingPaths: string[] }) => Promise< - Array<{ - path: string - name: string - mainLang?: string - mainLangColor?: `#${string}` - langGroup?: Array<{ text: string, color: `#${string}`, percentage: number }> - error?: string - }> - > - - // scanner (stream) - startProjectScan: (payload: { - roots: string[] - existingPaths: string[] - }) => Promise<{ sessionId: number }> + // ========= update ========= + checkUpdate: () => Promise + + // ========= scanner ========= + startProjectScan: (payload: ScanStartPayload) => Promise stopProjectScan: (sessionId: number) => Promise<{ stopped: boolean }> - onScannerItem: ( - cb: (data: { - sessionId: number - item: { - path: string - name: string - mainLang?: string - mainLangColor?: `#${string}` - langGroup?: Array<{ text: string, color: `#${string}`, percentage: number }> - error?: string - } - }) => void - ) => () => void - onScannerDone: (cb: (data: { sessionId: number }) => void) => () => void - onScannerError: (cb: (data: { sessionId: number, error: string }) => void) => () => void - - // theme + onScannerItem: (cb: (data: ScannerItemEvent) => void) => Unlisten + onScannerDone: (cb: (data: ScannerDoneEvent) => void) => Unlisten + onScannerError: (cb: (data: ScannerErrorEvent) => void) => Unlisten + detectJetBrainsConfigRootPath: () => Promise + detectVscodeStateDbPath: () => Promise + + // ========= theme ========= setWindowTheme: (currentTheme: ThemeEnum) => void } } } + +export {} diff --git a/src/locales/en.yml b/src/locales/en.yml index 7a9d590..2d0cc01 100644 --- a/src/locales/en.yml +++ b/src/locales/en.yml @@ -1,3 +1,10 @@ +common: + detect: Auto Detect + not_supported: Not supported yet + platform: + windows: Windows + macos: macOS + linux: Linux license: info: commercial_use: Commercial use @@ -15,7 +22,6 @@ license: state_changes: State changes liability: Liability trademark_use: Trademark use - warranty: Warranty mit: description_url: https://choosealicense.com/licenses/mit/ apache_2_0: @@ -156,6 +162,12 @@ settings: auto_scan: title: Auto Scanner Project desc: Automatically scans project root paths at startup. + method: Import Methods + methods_desc: Projects will be scanned and imported from the following methods at startup. + fs_tab: Import from file system + enable_fs: Enable importing from file system + ide_tab: Import from IDEs + enable_ide: Enable importing from IDEs add_folder: Add Project Root default_open_mode: Default Opening Method auto_select_program: Automatically select program based on language @@ -166,6 +178,30 @@ settings: clear_history_warning: 'Warning: After deletion, the program will re-scan all project folders on next startup, which may cause a short freeze. Please proceed with caution.' confirm: Yes cancel: No + strategy: Import Strategy + jetbrains: + title: 'JetBrains IDEs:' + config_root: 'JetBrains IDE config root path:' + select_folder_dialog: Select JetBrains IDE config root directory + hint_title: 'Please choose the JetBrains IDE config root directory, usually at:' + path_samples: + windows: 'C:\\Users\\<User>\\AppData\\Roaming\\JetBrains' + macos: ~/Library/Application Support/JetBrains + linux: ~/.config/JetBrains or ~/.JetBrains + includes: Includes IntelliJ IDEA, PyCharm, WebStorm, etc. + scan_versions: All IDE versions under this path will be scanned. + vscode: + title: 'Visual Studio Code:' + recent_db_label: 'VS Code recent projects file:' + select_file_dialog: Select VS Code recent projects file + file_type_name: VS Code Database + hint_title: "Please choose VS Code's state.vscdb file, usually at:" + path_samples: + windows: 'C:\\Users\\<User>\\AppData\\Roaming\\Code\\User\\globalStorage\\state.vscdb' + macos: ~/Library/Application Support/Code/User/globalStorage/state.vscdb + linux: ~/.config/Code/User/globalStorage/state.vscdb + vs: + title: 'Visual Studio:' about: title: About version: diff --git a/src/locales/zh-CN.yml b/src/locales/zh-CN.yml index d082963..84b1092 100644 --- a/src/locales/zh-CN.yml +++ b/src/locales/zh-CN.yml @@ -1,3 +1,10 @@ +common: + detect: 自动检测 + not_supported: 暂不支持 + platform: + windows: Windows + macos: macOS + linux: Linux license: info: commercial_use: 商业用途 @@ -7,6 +14,7 @@ license: private_use: 私用 disclose_source: 公开源码 license_and_copyright_notice: 放置许可协议与版权信息 + license_and_copyright_notice_for_source: 放置许可协议与版权信息(源码) network_use_is_distribution: 使用网络分发 same_license: 使用相同协议 same_license_library: 使用相同协议(library) @@ -148,6 +156,12 @@ settings: auto_scan: title: 自动扫描项目 desc: 启动时自动扫描项目根路径下的项目。 + method: 导入方式 + methods_desc: 启动后将从以下方式中自动扫描并导入项目。 + fs_tab: 从文件系统目录中导入 + enable_fs: 启用从文件系统目录中导入 + ide_tab: 从 IDE 中导入 + enable_ide: 启用从 IDE 中导入 add_folder: 添加项目根 default_open_mode: 默认打开方式 auto_select_program: 根据语言自动选择程序 @@ -158,6 +172,30 @@ settings: clear_history_warning: 警告:删除后,程序将在下次启动时重新检查所有项目文件夹,可能会导致程序短暂卡顿,请谨慎操作。 confirm: 是 cancel: 否 + strategy: 导入策略 + jetbrains: + title: JetBrains IDE: + config_root: JetBrains IDE 配置根路径: + select_folder_dialog: 选择 JetBrains IDE 配置根目录 + hint_title: 请选择 JetBrains IDE 配置根目录,通常在: + path_samples: + windows: 'C:\\Users\\<用户名>\\AppData\\Roaming\\JetBrains' + macos: ~/Library/Application Support/JetBrains + linux: ~/.config/JetBrains 或 ~/.JetBrains + includes: 包含 IntelliJ IDEA、PyCharm、WebStorm 等 IDE 配置。 + scan_versions: 该路径下的各个版本 IDE 配置目录均会被扫描。 + vscode: + title: Visual Studio Code: + recent_db_label: VS Code recent projects 文件: + select_file_dialog: 选择 VS Code recent projects 文件 + file_type_name: VS Code 数据库 + hint_title: 请选择 VS Code 的 state.vscdb 文件,通常在: + path_samples: + windows: 'C:\\Users\\<用户名>\\AppData\\Roaming\\Code\\User\\globalStorage\\state.vscdb' + macos: ~/Library/Application Support/Code/User/globalStorage/state.vscdb + linux: ~/.config/Code/User/globalStorage/state.vscdb + vs: + title: Visual Studio: about: title: 关于 version: diff --git a/src/services/projectScannerService.ts b/src/services/projectScannerService.ts index 3aef1ec..adab302 100644 --- a/src/services/projectScannerService.ts +++ b/src/services/projectScannerService.ts @@ -1,5 +1,3 @@ -import { unref } from 'vue' - import { clearState, setState } from '~/components/StateBar' import type { CodeEditorEnum } from '~/constants/codeEditor' import type { LicenseEnum } from '~/constants/license' @@ -39,18 +37,13 @@ export async function addNewProjectsInWorker() { projectsStore.allProjects.forEach(p => scannerStore.addScannedPath(p.path)) - const roots = Array.isArray(unref(settingsStore.projectScannerRoots)) - ? [...unref(settingsStore.projectScannerRoots) as string[]] - : [] - const existingPaths = Array.from(unref(scannerStore.allHistoryScannedPaths)) - // 初始状态:扫描中 setState('projectScanner', t('status.project_scanner.scanning'), true) - // 启动扫描(异步) + // 启动扫描 const { sessionId } = await window.api.startProjectScan({ - roots, - existingPaths, + ...toRaw(settingsStore.scanner), + existingPaths: Array.from(scannerStore.allHistoryScannedPaths), }) // 先声明,再在 finalize 中使用,避免 no-use-before-define @@ -97,11 +90,13 @@ export async function addNewProjectsInWorker() { } } - const defaultOpen: CodeEditorEnum = settingsStore.projectScannerOpenMode === 'specified' - ? settingsStore.projectScannerEditor - : editorLangGroupsStore.getEditorByLanguage(mainLang, settingsStore.projectScannerEditor) as CodeEditorEnum + const defaultOpen: CodeEditorEnum = item.ide + ? item.ide as CodeEditorEnum + : settingsStore.scanner.openMode === 'specified' + ? settingsStore.scanner.editor + : editorLangGroupsStore.getEditorByLanguage(mainLang, settingsStore.scanner.editor) as CodeEditorEnum - const isTemporary: boolean = toRegExp(settingsStore.projectScannerNamePattern)?.test(name) || false + const isTemporary: boolean = toRegExp(settingsStore.scanner.namePattern)?.test(name) || false const newProject: LocalProject = { appendTime: Date.now(), diff --git a/src/stores/helpers/persistence.ts b/src/stores/helpers/persistence.ts index 99865fe..690a082 100644 --- a/src/stores/helpers/persistence.ts +++ b/src/stores/helpers/persistence.ts @@ -1,5 +1,10 @@ +/** + * 数据文件类型 + */ +export type DataFileEnum = 'editorLangGroups' | 'projects' | 'projectScanner' | 'settings' + export interface PersistenceOptions { - key: 'editorLangGroups' | 'projects' | 'projectScanner' | 'settings' + key: DataFileEnum serialize?: (data: T) => string deserialize?: (raw: string) => T } diff --git a/src/stores/projectScannerStore.ts b/src/stores/projectScannerStore.ts index dcb97a0..4ef111a 100644 --- a/src/stores/projectScannerStore.ts +++ b/src/stores/projectScannerStore.ts @@ -27,7 +27,7 @@ export const useProjectScannerStore = defineStore('projectScanner', () => { async function saveProjectScannerData() { await scannerPersistence.save({ - historyScannedPaths: Array.from(historyScannedPaths.value), + historyScannedPaths: Array.from(historyScannedPaths.value).sort(), }) } diff --git a/src/stores/settingsStore.ts b/src/stores/settingsStore.ts index 32c7976..ab08b50 100644 --- a/src/stores/settingsStore.ts +++ b/src/stores/settingsStore.ts @@ -8,17 +8,62 @@ const settingsPersistence = createPersistence({ key: 'settings', }) +// Scanner settings shape +export interface ScannerSettings { + // file system roots scanning + rootsEnabled: boolean + roots: string[] + + // IDE scanning toggles + ideEnabled: boolean + jetbrains: { + enabled: boolean + configRootPath: string + } + vscode: { + enabled: boolean + stateDbPath: string + } + visualStudio: { + enabled: boolean + } + + // import strategies + openMode: 'auto' | 'specified' + editor: CodeEditorEnum + namePattern: string +} + export const useSettingsStore = defineStore('settings', () => { - // --- 配置项 --- + // --- 基础配置项 --- const theme = ref(ThemeEnum.Light) const language = ref(LanguageEnum.English) const codeEditorsPath = reactive>( Object.fromEntries(Object.keys(codeEditors).map(key => [key, ''])) as Record, ) - const projectScannerRoots = ref([]) - const projectScannerOpenMode = ref<'auto' | 'specified'>('auto') - const projectScannerEditor = ref(CodeEditorEnum.VisualStudioCode) - const projectScannerNamePattern = ref('(demo|test)') + + // --- 扫描器配置 --- + const scanner = reactive({ + rootsEnabled: false, + roots: [], + + ideEnabled: false, + jetbrains: { + enabled: false, + configRootPath: '', + }, + vscode: { + enabled: false, + stateDbPath: '', + }, + visualStudio: { + enabled: false, + }, + + openMode: 'auto', + editor: CodeEditorEnum.VisualStudioCode, + namePattern: '(demo|test)', + }) // --- 加载配置 --- async function loadSettings(): Promise { @@ -27,20 +72,44 @@ export const useSettingsStore = defineStore('settings', () => { if (loadedData) { theme.value = loadedData.theme ?? theme.value language.value = loadedData.language ?? language.value - projectScannerRoots.value = Array.isArray(loadedData.projectScannerRoots) - ? loadedData.projectScannerRoots - : [] - projectScannerOpenMode.value - = loadedData.projectScannerOpenMode ?? projectScannerOpenMode.value - projectScannerEditor.value = loadedData.projectScannerEditor ?? projectScannerEditor.value - projectScannerNamePattern.value - = loadedData.projectScannerNamePattern ?? projectScannerNamePattern.value + // editors path if (loadedData.codeEditorsPath) { for (const editor of Object.keys(codeEditorsPath) as CodeEditorEnum[]) { codeEditorsPath[editor] = loadedData.codeEditorsPath[editor] ?? '' } } + + // scanner + if (loadedData.scanner) { + const s = loadedData.scanner as Partial + // primitives + if (typeof s.rootsEnabled === 'boolean') + scanner.rootsEnabled = s.rootsEnabled + if (Array.isArray(s.roots)) + scanner.roots.splice(0, scanner.roots.length, ...s.roots) + if (typeof s.ideEnabled === 'boolean') + scanner.ideEnabled = s.ideEnabled + if (s.openMode === 'auto' || s.openMode === 'specified') + scanner.openMode = s.openMode + if (s.editor) + scanner.editor = s.editor + if (typeof s.namePattern === 'string') + scanner.namePattern = s.namePattern + + // nested + if (s.jetbrains) { + scanner.jetbrains.enabled = s.jetbrains.enabled + scanner.jetbrains.configRootPath = s.jetbrains.configRootPath + } + if (s.vscode) { + scanner.vscode.enabled = s.vscode.enabled + scanner.vscode.stateDbPath = s.vscode.stateDbPath + } + if (s.visualStudio) { + scanner.visualStudio.enabled = s.visualStudio.enabled + } + } } } catch (error) { @@ -55,10 +124,7 @@ export const useSettingsStore = defineStore('settings', () => { theme: theme.value, language: language.value, codeEditorsPath, - projectScannerRoots: projectScannerRoots.value, - projectScannerOpenMode: projectScannerOpenMode.value, - projectScannerEditor: projectScannerEditor.value, - projectScannerNamePattern: projectScannerNamePattern.value, + scanner, }) } catch (error) { @@ -70,10 +136,7 @@ export const useSettingsStore = defineStore('settings', () => { theme, language, codeEditorsPath, - projectScannerRoots, - projectScannerOpenMode, - projectScannerEditor, - projectScannerNamePattern, + scanner, loadSettings, saveSettings, } diff --git a/src/views/HomeView/ProjectOverview/ProjectOverviewHeader.vue b/src/views/HomeView/ProjectOverview/ProjectOverviewHeader.vue index 145dc8d..a60787e 100644 --- a/src/views/HomeView/ProjectOverview/ProjectOverviewHeader.vue +++ b/src/views/HomeView/ProjectOverview/ProjectOverviewHeader.vue @@ -42,8 +42,8 @@ watch(searchInputValue, (newSearchValue) => { - diff --git a/src/views/SettingsView/SettingsView.vue b/src/views/SettingsView/SettingsView.vue index 83cb984..e16b8e1 100644 --- a/src/views/SettingsView/SettingsView.vue +++ b/src/views/SettingsView/SettingsView.vue @@ -39,7 +39,7 @@ const searchValue = ref('') const activatedView = inject('activatedView') as Ref function openSettingsJSON() { - window.api.openSettingsJSON() + window.api.openData('settings') } function saveAllSettings() { @@ -76,11 +76,13 @@ onUnmounted(() => { >
diff --git a/src/views/SettingsView/pages/AutoProjectScanner.vue b/src/views/SettingsView/pages/AutoProjectScanner.vue index 7b3a0f5..6721f44 100644 --- a/src/views/SettingsView/pages/AutoProjectScanner.vue +++ b/src/views/SettingsView/pages/AutoProjectScanner.vue @@ -1,114 +1,347 @@ + + diff --git a/unocss.config.ts b/unocss.config.ts index 52b34f6..4c652de 100644 --- a/unocss.config.ts +++ b/unocss.config.ts @@ -38,6 +38,8 @@ export default defineConfig({ // Color 'text-primary': 'light:color-$gray-1 dark:color-$gray-12', 'text-secondary': 'color-$gray-7', + // Layout + 'settings-section': 'pl-30px', }, safelist: editorIconClasses, transformers: [