diff --git a/.prettierrc b/.prettierrc index f596965..a8fcce4 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,11 +1,22 @@ { - "semi": true, - "trailingComma": "es5", - "singleQuote": true, - "printWidth": 100, + "printWidth": 120, "tabWidth": 4, "useTabs": false, - "bracketSpacing": true, - "arrowParens": "always", - "endOfLine": "lf" + "semi": true, + "singleQuote": true, + "trailingComma": "all", + "overrides": [ + { + "files": "*.yaml", + "options": { + "tabWidth": 4 + } + }, + { + "files": "*.yml", + "options": { + "tabWidth": 4 + } + } + ] } diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz index 393ff3e..a1f8c25 100644 Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ diff --git a/eslint.config.js b/eslint.config.js index 6f07992..490486a 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -180,7 +180,53 @@ module.exports = [ }, }, { + // Browser/Renderer JavaScript files (Electron renderer process) + files: ['packages/mac/src/renderer/**/*.js'], + languageOptions: { + ecmaVersion: 2020, + sourceType: 'script', // Renderer files use script mode + globals: { + // Browser globals + window: 'readonly', + document: 'readonly', + console: 'readonly', + setTimeout: 'readonly', + clearTimeout: 'readonly', + setInterval: 'readonly', + clearInterval: 'readonly', + alert: 'readonly', + confirm: 'readonly', + prompt: 'readonly', + // DOM globals + Element: 'readonly', + HTMLElement: 'readonly', + Event: 'readonly', + MouseEvent: 'readonly', + KeyboardEvent: 'readonly', + // Additional browser APIs + fetch: 'readonly', + localStorage: 'readonly', + sessionStorage: 'readonly', + }, + }, + plugins: { + prettier, + }, + rules: { + 'prettier/prettier': [ + 'error', + { + tabWidth: 4, + }, + ], + // Relax some rules for renderer files + 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + }, + }, + { + // Node.js JavaScript files files: ['**/*.js', '**/*.mjs', '**/*.cjs'], + ignores: ['packages/mac/src/renderer/**/*.js'], // Exclude renderer files languageOptions: { ecmaVersion: 2020, sourceType: 'module', diff --git a/jest.config.js b/jest.config.js index cc57447..6b0bc56 100644 --- a/jest.config.js +++ b/jest.config.js @@ -45,11 +45,7 @@ module.exports = { ], // Global settings - collectCoverageFrom: [ - 'packages/*/src/**/*.ts', - '!packages/*/src/**/*.d.ts', - '!packages/*/src/**/index.ts', - ], + collectCoverageFrom: ['packages/*/src/**/*.ts', '!packages/*/src/**/*.d.ts', '!packages/*/src/**/index.ts'], coverageDirectory: 'coverage', coverageReporters: ['text', 'lcov', 'html'], diff --git a/packages/cli/__tests__/commands/convert-command.test.ts b/packages/cli/__tests__/commands/convert-command.test.ts index 0279062..c7fb1b4 100644 --- a/packages/cli/__tests__/commands/convert-command.test.ts +++ b/packages/cli/__tests__/commands/convert-command.test.ts @@ -37,12 +37,10 @@ describe('ConvertCommandCreator', () => { // Setup mocks const { SubtitleProcessor, ConfigManager } = require('@subzilla/core'); - const mockProcessFile = jest - .fn<() => Promise<{ outputPath: string; backupPath: string }>>() - .mockResolvedValue({ - outputPath: '/mock/output.srt', - backupPath: '/mock/backup.srt', - }); + const mockProcessFile = jest.fn<() => Promise<{ outputPath: string; backupPath: string }>>().mockResolvedValue({ + outputPath: '/mock/output.srt', + backupPath: '/mock/backup.srt', + }); (SubtitleProcessor as any).mockImplementation(() => ({ processFile: mockProcessFile, @@ -152,7 +150,7 @@ describe('ConvertCommandCreator', () => { html: true, colors: true, }), - }) + }), ); }); @@ -169,7 +167,7 @@ describe('ConvertCommandCreator', () => { expect.objectContaining({ retryCount: 3, retryDelay: 2000, - }) + }), ); }); @@ -190,7 +188,7 @@ describe('ConvertCommandCreator', () => { overwriteInput: true, overwriteExisting: true, overwriteBackup: false, - }) + }), ); }); @@ -213,7 +211,7 @@ describe('ConvertCommandCreator', () => { expect.objectContaining({ backupOriginal: true, bom: false, - }) + }), ); }); @@ -242,7 +240,7 @@ describe('ConvertCommandCreator', () => { '🧬 Output options:', expect.objectContaining({ lineEndings: 'lf', - }) + }), ); }); }); diff --git a/packages/cli/src/commands/batch-command.ts b/packages/cli/src/commands/batch-command.ts index 115f25d..3668708 100644 --- a/packages/cli/src/commands/batch-command.ts +++ b/packages/cli/src/commands/batch-command.ts @@ -24,13 +24,11 @@ export class BatchCommandCreator extends BaseCommandCreator const fileBuffer = await fs.readFile(inputFile); // Detect encoding - const detectedEncoding = - await EncodingDetectionService.detectEncoding(inputFile); + const detectedEncoding = await EncodingDetectionService.detectEncoding(inputFile); // Check for BOM const hasBOM = fileBuffer.slice(0, 3).equals(Buffer.from([0xef, 0xbb, 0xbf])); @@ -38,9 +37,7 @@ export class InfoCommandCreator extends BaseCommandCreator // Count lines and entries const content = fileBuffer.toString(detectedEncoding as NodeJS.BufferEncoding); const lines = content.split(/\r?\n/); - const entries = content - .split(/\r?\n\r?\n/) - .filter((entry) => entry.trim()).length; + const entries = content.split(/\r?\n\r?\n/).filter((entry) => entry.trim()).length; // Detect line endings const hasCarriageReturn = content.includes('\r\n'); @@ -63,10 +60,7 @@ export class InfoCommandCreator extends BaseCommandCreator console.log(` • Total Lines: ${chalk.yellow(lines.length)}`); console.log(` • Subtitle Entries: ${chalk.yellow(entries)}`); } catch (error) { - console.error( - chalk.red('❌ Error analyzing subtitle file:'), - (error as Error).message - ); + console.error(chalk.red('❌ Error analyzing subtitle file:'), (error as Error).message); process.exit(1); } }, diff --git a/packages/cli/src/utils/strip-options.ts b/packages/cli/src/utils/strip-options.ts index e3d36dc..44eff91 100644 --- a/packages/cli/src/utils/strip-options.ts +++ b/packages/cli/src/utils/strip-options.ts @@ -1,9 +1,6 @@ import { IStripOptions, IStripCommandOptions, IConfig } from '@subzilla/types'; -export function createStripOptions( - options: IStripCommandOptions, - config: IConfig -): IStripOptions | undefined { +export function createStripOptions(options: IStripCommandOptions, config: IConfig): IStripOptions | undefined { const stripOptions: IStripOptions = options.stripAll ? { html: true, diff --git a/packages/core/__tests__/EncodingConversionService.test.ts b/packages/core/__tests__/EncodingConversionService.test.ts index a3282fd..37757ad 100644 --- a/packages/core/__tests__/EncodingConversionService.test.ts +++ b/packages/core/__tests__/EncodingConversionService.test.ts @@ -52,8 +52,8 @@ describe('EncodingConversionService', () => { const content = 'Smart quotes: "Hello"'; // Create buffer with Windows-1252 specific characters const buffer = Buffer.from([ - 0x53, 0x6d, 0x61, 0x72, 0x74, 0x20, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x3a, 0x20, - 0x93, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x94, + 0x53, 0x6d, 0x61, 0x72, 0x74, 0x20, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x3a, 0x20, 0x93, 0x48, 0x65, + 0x6c, 0x6c, 0x6f, 0x94, ]); const result = EncodingConversionService.convertToUtf8(buffer, 'windows-1252'); diff --git a/packages/core/__tests__/EncodingDetectionService.test.ts b/packages/core/__tests__/EncodingDetectionService.test.ts index f50a3ce..16c028d 100644 --- a/packages/core/__tests__/EncodingDetectionService.test.ts +++ b/packages/core/__tests__/EncodingDetectionService.test.ts @@ -74,9 +74,7 @@ describe('EncodingDetectionService', () => { it('should reject when file does not exist', async () => { const nonExistentPath = path.join(tempDir, 'nonexistent.srt'); - await expect( - EncodingDetectionService.detectEncoding(nonExistentPath) - ).rejects.toThrow(); + await expect(EncodingDetectionService.detectEncoding(nonExistentPath)).rejects.toThrow(); }); it('should handle Windows-1252 encoded content', async () => { diff --git a/packages/core/src/BatchProcessor.ts b/packages/core/src/BatchProcessor.ts index 55da7ba..1849ea4 100644 --- a/packages/core/src/BatchProcessor.ts +++ b/packages/core/src/BatchProcessor.ts @@ -25,7 +25,7 @@ export default class BatchProcessor { hideCursor: true, clearOnComplete: false, }, - Presets.shades_classic + Presets.shades_classic, ); this.directoryBars = new Map(); @@ -62,9 +62,7 @@ export default class BatchProcessor { } this.stats.total = files.length; - console.log( - `🔍 Found ${files.length} files in ${this.countDirectories(files)} directories...` - ); + console.log(`🔍 Found ${files.length} files in ${this.countDirectories(files)} directories...`); // Create output directory if specified if (options.common.outputDir) { @@ -90,8 +88,7 @@ export default class BatchProcessor { // Finalize statistics this.stats.timeTaken = (Date.now() - this.startTime) / 1000; - this.stats.averageTimePerFile = - this.stats.timeTaken / (this.stats.successful + this.stats.failed); + this.stats.averageTimePerFile = this.stats.timeTaken / (this.stats.successful + this.stats.failed); // Stop progress bars this.multiBar.stop(); @@ -157,39 +154,33 @@ export default class BatchProcessor { return acc; }, - {} as Record + {} as Record, ); } private async processDirectoriesParallel( filesByDir: Record, - options: IBatchOptions + options: IBatchOptions, ): Promise { const directories = Object.entries(filesByDir); const chunks = this.chunkArray(directories, options.batch.chunkSize || 3); // Use configured chunk size for (const chunk of chunks) { if (this.shouldStop) break; - await Promise.all( - chunk.map(([dir, files]) => this.processDirectory(dir, files, options)) - ); + await Promise.all(chunk.map(([dir, files]) => this.processDirectory(dir, files, options))); } } private async processDirectoriesSequential( filesByDir: Record, - options: IBatchOptions + options: IBatchOptions, ): Promise { for (const [dir, files] of Object.entries(filesByDir)) { await this.processDirectory(dir, files, options); } } - private async processDirectory( - dir: string, - files: string[], - options: IBatchOptions - ): Promise { + private async processDirectory(dir: string, files: string[], options: IBatchOptions): Promise { if (this.shouldStop) return; // Create directory progress bar @@ -240,11 +231,7 @@ export default class BatchProcessor { if (this.shouldStop) return; try { - if ( - options.batch.skipExisting && - outputPath && - (await this.fileExists(outputPath)) - ) { + if (options.batch.skipExisting && outputPath && (await this.fileExists(outputPath))) { dirStats.skipped++; this.stats.skipped++; diff --git a/packages/core/src/ConfigManager.ts b/packages/core/src/ConfigManager.ts index d50c5ac..15117c6 100644 --- a/packages/core/src/ConfigManager.ts +++ b/packages/core/src/ConfigManager.ts @@ -65,16 +65,10 @@ export default class ConfigManager { try { // Load config from different sources in order of precedence const envConfig = this.loadFromEnv(); - const fileConfig = configPath - ? await this.loadConfigFile(configPath) - : await this.findAndLoadConfig(); + const fileConfig = configPath ? await this.loadConfigFile(configPath) : await this.findAndLoadConfig(); // Merge configs in order of precedence: defaults < file < env - const mergedConfig = this.mergeConfigs( - this.DEFAULT_CONFIG, - fileConfig || {}, - envConfig - ); + const mergedConfig = this.mergeConfigs(this.DEFAULT_CONFIG, fileConfig || {}, envConfig); // Validate the merged config const validatedConfig = await this.validateConfig(mergedConfig); @@ -173,11 +167,7 @@ export default class ConfigManager { /** * 🎯 Set nested value in configuration object */ - private static setNestedValue( - obj: Record, - path: string[], - value: unknown - ): void { + private static setNestedValue(obj: Record, path: string[], value: unknown): void { let current = obj; for (let i = 0; i < path.length - 1; i++) { @@ -214,16 +204,12 @@ export default class ConfigManager { if (Object.prototype.hasOwnProperty.call(source, key)) { const sourceValue = source[key]; - if ( - typeof sourceValue === 'object' && - sourceValue !== null && - !Array.isArray(sourceValue) - ) { + if (typeof sourceValue === 'object' && sourceValue !== null && !Array.isArray(sourceValue)) { const targetValue = result[key] as Record; result[key] = this.deepMerge( (targetValue || {}) as Record, - sourceValue as Record + sourceValue as Record, ) as T[Extract]; } else { result[key] = sourceValue as T[Extract]; diff --git a/packages/core/src/FormattingStripper.ts b/packages/core/src/FormattingStripper.ts index 43c3d9e..cbc0623 100644 --- a/packages/core/src/FormattingStripper.ts +++ b/packages/core/src/FormattingStripper.ts @@ -13,20 +13,7 @@ export default class FormattingStripper { private emojiRegex = /[\u{1F300}-\u{1F9FF}]|[\u{2700}-\u{27BF}]|[\u{1F600}-\u{1F64F}]/gu; private bracketsRegex = /[[\](){}⟨⟩<>]/g; private bidiControlRegex = /[\u200E\u200F\u202A-\u202E\u2066-\u2069]/g; - private richTextTags = [ - 'b', - 'i', - 'u', - 's', - 'font', - 'size', - 'color', - 'ruby', - 'rt', - 'rp', - 'style', - 'class', - ]; + private richTextTags = ['b', 'i', 'u', 's', 'font', 'size', 'color', 'ruby', 'rt', 'rp', 'style', 'class']; public stripFormatting(content: string, options: IStripOptions): string { let result = content; diff --git a/packages/core/src/SubtitleProcessor.ts b/packages/core/src/SubtitleProcessor.ts index 79964d2..2d73f4b 100644 --- a/packages/core/src/SubtitleProcessor.ts +++ b/packages/core/src/SubtitleProcessor.ts @@ -26,7 +26,7 @@ export default class SubtitleProcessor { public async processFile( inputFilePath: string, outputFilePath?: string, - options: IConvertOptions = {} + options: IConvertOptions = {}, ): Promise<{ outputPath: string; backupPath?: string }> { let backupPath: string | undefined; @@ -35,9 +35,7 @@ export default class SubtitleProcessor { await fs.access(inputFilePath); // Determine output strategy - const outputStrategy = options.overwriteInput - ? new OverwriteOutputStrategy() - : new SuffixOutputStrategy(); + const outputStrategy = options.overwriteInput ? new OverwriteOutputStrategy() : new SuffixOutputStrategy(); // Determine final output path const finalOutputPath = outputFilePath || outputStrategy.getOutputPath(inputFilePath); @@ -89,7 +87,7 @@ export default class SubtitleProcessor { throw new Error( `Processing failed and backup restoration failed. Original error: ${ (error as Error).message - }. Restore error: ${(restoreError as Error).message}` + }. Restore error: ${(restoreError as Error).message}`, ); } } @@ -143,9 +141,7 @@ export default class SubtitleProcessor { await fs.access(outputPath); if (!options.overwriteExisting) { - throw new Error( - `Output file ${outputPath} already exists and overwrite existing is disabled` - ); + throw new Error(`Output file ${outputPath} already exists and overwrite existing is disabled`); } } catch (error) { if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { diff --git a/packages/mac/README.md b/packages/mac/README.md new file mode 100644 index 0000000..196450a --- /dev/null +++ b/packages/mac/README.md @@ -0,0 +1,81 @@ +# Subzilla Mac Desktop Application + +A minimalist Mac desktop application for subtitle conversion, built with Electron and integrated with the Subzilla monorepo. + +## Features + +- 🦎 **Simple Interface**: Drag-and-drop subtitle files for instant conversion +- ⚡ **Fast Processing**: Leverages `@subzilla/core` for efficient batch processing +- 🎛️ **Full Control**: Complete preferences window with all configuration options +- 🍎 **Native macOS**: Feels like a native Mac application +- 🔄 **Auto-Updates**: Seamless updates through GitHub releases +- 💾 **Smart Backups**: Optional backup creation with conflict handling + +## Supported Formats + +- **Input**: `.srt`, `.sub`, `.ass`, `.ssa`, `.txt` +- **Output**: UTF-8 encoded files in same or different formats +- **Encoding Detection**: Automatic detection of input encoding +- **Arabic Support**: Optimized for Arabic subtitle processing + +## Development + +```bash +# Install dependencies +yarn install + +# Build TypeScript +yarn build + +# Run in development +yarn dev + +# Create distribution +yarn dist +``` + +## Architecture + +### Main Process (`src/main/`) + +- `index.ts` - Application entry point and window management +- `ipc.ts` - IPC handlers for renderer communication +- `menu.ts` - Native macOS menu bar +- `preferences.ts` - Configuration management with electron-store +- `updater.ts` - Auto-update functionality + +### Renderer Process (`src/renderer/`) + +- `index.html` - Main window interface +- `preferences.html` - Preferences window +- `js/app.js` - Main application logic and drag-drop +- `js/preferences.js` - Preferences management +- `styles/` - CSS styling for both windows + +### Preload (`src/preload/`) + +- `index.ts` - Secure context bridge for IPC communication + +## Integration + +The Mac app directly uses: + +- `@subzilla/core` - All processing logic +- `@subzilla/types` - TypeScript interfaces and types + +No subprocess calls or CLI wrapping - direct integration for maximum performance. + +## Distribution + +Built with `electron-builder` for: + +- **DMG**: Drag-and-drop installer +- **ZIP**: Portable application bundle +- **Auto-updates**: GitHub releases integration + +## Security + +- Context isolation enabled +- Node integration disabled +- Secure IPC communication +- Code signing and notarization ready diff --git a/packages/mac/assets/icon.icns b/packages/mac/assets/icon.icns new file mode 100644 index 0000000..d6e1498 Binary files /dev/null and b/packages/mac/assets/icon.icns differ diff --git a/packages/mac/build/entitlements.mac.plist b/packages/mac/build/entitlements.mac.plist new file mode 100644 index 0000000..50a72e4 --- /dev/null +++ b/packages/mac/build/entitlements.mac.plist @@ -0,0 +1,18 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.debugger + + com.apple.security.cs.disable-library-validation + + com.apple.security.files.user-selected.read-write + + com.apple.security.files.downloads.read-write + + + \ No newline at end of file diff --git a/packages/mac/demo-setup.md b/packages/mac/demo-setup.md new file mode 100644 index 0000000..61261f2 --- /dev/null +++ b/packages/mac/demo-setup.md @@ -0,0 +1,23 @@ +# Subzilla Mac App Demo Setup + +## To Run the Demo + +1. **Build Dependencies**: + +```bash +# Build types package +cd ../types && yarn build + +# Build core package +cd ../core && yarn build + +# Build mac package +cd ../mac && yarn build +``` + +3. **Run the App**: + +```bash +cd packages/mac +npx electron . +``` diff --git a/packages/mac/electron-builder.yml b/packages/mac/electron-builder.yml new file mode 100644 index 0000000..12a7745 --- /dev/null +++ b/packages/mac/electron-builder.yml @@ -0,0 +1,36 @@ +appId: net.onyxdev.subzilla +productName: Subzilla +directories: + output: dist-electron +files: + - dist/**/* + - assets/**/* +mac: + category: public.app-category.utilities + icon: assets/icon.icns + entitlements: build/entitlements.mac.plist + entitlementsInherit: build/entitlements.mac.plist + gatekeeperAssess: false + hardenedRuntime: true + target: + - target: dmg + arch: [x64, arm64] + - target: zip + arch: [x64, arm64] +dmg: + # background: assets/dmg-background.png + icon: assets/icon.icns + iconSize: 100 + window: + width: 540 + height: 380 + contents: + - x: 140 + y: 190 + type: file + - x: 400 + y: 190 + type: link + path: /Applications +publish: + provider: github diff --git a/packages/mac/package.json b/packages/mac/package.json new file mode 100644 index 0000000..878077d --- /dev/null +++ b/packages/mac/package.json @@ -0,0 +1,93 @@ +{ + "name": "@subzilla/mac", + "version": "1.0.0", + "description": "Mac desktop application for Subzilla subtitle converter", + "main": "dist/main/index.js", + "scripts": { + "build": "tsc && npm run copy-renderer && electron-builder", + "dev": "tsc && npm run copy-renderer && electron .", + "start": "electron dist/main/index.js", + "copy-renderer": "mkdir -p dist/renderer && cp -r src/renderer/* dist/renderer/", + "dist": "electron-builder", + "type-check": "tsc --noEmit", + "lint": "eslint . --ext .ts", + "lint:fix": "eslint . --ext .ts --fix", + "format": "prettier --write \"src/**/*.ts\"", + "format:check": "prettier --check \"src/**/*.ts\"", + "test": "jest --selectProjects mac" + }, + "keywords": [ + "subtitle", + "converter", + "mac", + "desktop", + "electron" + ], + "author": { + "name": "Obada Qawwas", + "email": "info@onyxdev.net", + "url": "https://onyxdev.net" + }, + "license": "ISC", + "_moduleAliases": { + "@subzilla/core": "../core/dist", + "@subzilla/types": "../types/dist" + }, + "dependencies": { + "@subzilla/core": "workspace:*", + "@subzilla/types": "workspace:*", + "electron-store": "^8.1.0", + "electron-updater": "^6.1.0", + "module-alias": "^2.2.3" + }, + "devDependencies": { + "@types/node": "^24.3.0", + "electron": "^31.0.0", + "electron-builder": "^24.0.0", + "typescript": "^5.9.2" + }, + "build": { + "appId": "net.onyxdev.subzilla", + "productName": "Subzilla", + "directories": { + "output": "dist-electron" + }, + "files": [ + "dist/**/*", + "assets/**/*" + ], + "mac": { + "category": "public.app-category.utilities", + "icon": "assets/icon.icns", + "entitlements": "build/entitlements.mac.plist", + "entitlementsInherit": "build/entitlements.mac.plist", + "gatekeeperAssess": false, + "hardenedRuntime": true + }, + "dmg": { + "background": "assets/dmg-background.png", + "icon": "assets/icon.icns", + "iconSize": 100, + "window": { + "width": 540, + "height": 380 + }, + "contents": [ + { + "x": 140, + "y": 190, + "type": "file" + }, + { + "x": 400, + "y": 190, + "type": "link", + "path": "/Applications" + } + ] + }, + "publish": { + "provider": "github" + } + } +} diff --git a/packages/mac/src/main/index.ts b/packages/mac/src/main/index.ts new file mode 100644 index 0000000..2e332ac --- /dev/null +++ b/packages/mac/src/main/index.ts @@ -0,0 +1,205 @@ +import 'module-alias/register'; + +import path from 'path'; + +import { app, BrowserWindow, shell, Menu } from 'electron'; + +import { setupIPC } from './ipc'; +import { createMenu } from './menu'; +import { AutoUpdater } from './updater'; + +const isDev = process.env.NODE_ENV === 'development'; +const isProduction = process.env.NODE_ENV === 'production'; + +class SubzillaApp { + private mainWindow: BrowserWindow | null = null; + private preferencesWindow: BrowserWindow | null = null; + private autoUpdater: AutoUpdater | null = null; + + constructor() { + console.log('🦎 Initializing Subzilla Mac App...'); + this.setupApp(); + } + + private setupApp(): void { + // Handle app ready + app.whenReady().then(() => { + console.log('🚀 App ready, creating main window...'); + this.createMainWindow(); + this.setupMenu(); + this.setupIPC(); + this.setupAutoUpdater(); + + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + this.createMainWindow(); + } + }); + }); + + // Quit when all windows are closed (except on macOS) + app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit(); + } + }); + + // Handle file opening from Finder/Dock + app.on('open-file', (event, filePath) => { + event.preventDefault(); + console.log(`📂 File opened from system: ${filePath}`); + + if (this.mainWindow) { + this.mainWindow.webContents.send('file-opened', filePath); + this.mainWindow.show(); + this.mainWindow.focus(); + } + }); + + // Security: prevent new window creation + app.on('web-contents-created', (_, contents) => { + contents.setWindowOpenHandler(({ url }) => { + shell.openExternal(url); + + return { action: 'deny' }; + }); + }); + } + + private createMainWindow(): void { + console.log('🖼️ Creating main window...'); + + this.mainWindow = new BrowserWindow({ + width: 500, + height: 400, + minWidth: 400, + minHeight: 300, + titleBarStyle: 'hiddenInset', + show: false, + webPreferences: { + nodeIntegration: false, + contextIsolation: true, + preload: path.join(__dirname, '../preload/index.js'), + webSecurity: true, + allowRunningInsecureContent: false, + }, + icon: path.join(__dirname, '../../assets/icon.icns'), + }); + + // Load the main window content + const indexPath = path.join(__dirname, '../renderer/index.html'); + + this.mainWindow.loadFile(indexPath); + + // Show window when ready + this.mainWindow.once('ready-to-show', () => { + console.log('✅ Main window ready, showing...'); + this.mainWindow?.show(); + + if (isDev) { + this.mainWindow?.webContents.openDevTools(); + } + }); + + // Handle window closed + this.mainWindow.on('closed', () => { + this.mainWindow = null; + }); + + // Handle external links + this.mainWindow.webContents.setWindowOpenHandler(({ url }) => { + shell.openExternal(url); + + return { action: 'deny' }; + }); + } + + public createPreferencesWindow(): void { + if (this.preferencesWindow) { + this.preferencesWindow.focus(); + + return; + } + + console.log('⚙️ Creating preferences window...'); + + this.preferencesWindow = new BrowserWindow({ + width: 600, + height: 500, + minWidth: 500, + minHeight: 400, + resizable: true, + minimizable: false, + maximizable: false, + fullscreenable: false, + titleBarStyle: 'hiddenInset', + show: false, + parent: this.mainWindow || undefined, + modal: false, + webPreferences: { + nodeIntegration: false, + contextIsolation: true, + preload: path.join(__dirname, '../preload/index.js'), + webSecurity: true, + allowRunningInsecureContent: false, + }, + }); + + // Load preferences content + const preferencesPath = path.join(__dirname, '../renderer/preferences.html'); + + this.preferencesWindow.loadFile(preferencesPath); + + // Show when ready + this.preferencesWindow.once('ready-to-show', () => { + this.preferencesWindow?.show(); + }); + + // Clean up reference when closed + this.preferencesWindow.on('closed', () => { + this.preferencesWindow = null; + }); + } + + private setupMenu(): void { + const menu = createMenu(this); + + Menu.setApplicationMenu(menu); + } + + private setupIPC(): void { + setupIPC(this); + } + + private setupAutoUpdater(): void { + if (isProduction && this.mainWindow) { + this.autoUpdater = new AutoUpdater(this.mainWindow); + } + } + + public getMainWindow(): BrowserWindow | null { + return this.mainWindow; + } + + public getPreferencesWindow(): BrowserWindow | null { + return this.preferencesWindow; + } + + public openFiles(): void { + if (this.mainWindow) { + this.mainWindow.webContents.send('open-files-dialog'); + } + } + + public clearFileList(): void { + if (this.mainWindow) { + this.mainWindow.webContents.send('clear-file-list'); + } + } +} + +// Create app instance +const subzillaApp = new SubzillaApp(); + +// Export for use in other modules +export default subzillaApp; diff --git a/packages/mac/src/main/ipc.ts b/packages/mac/src/main/ipc.ts new file mode 100644 index 0000000..c9313b4 --- /dev/null +++ b/packages/mac/src/main/ipc.ts @@ -0,0 +1,241 @@ +import path from 'path'; + +import { ipcMain, dialog, BrowserWindow, shell, app } from 'electron'; + +import { SubtitleProcessor, BatchProcessor, ConfigManager } from '@subzilla/core'; +import { IConfig, IConvertOptions, IBatchStats } from '@subzilla/types'; + +import { ConfigMapper } from './preferences'; + +export interface FileProcessingItem { + id: string; + filePath: string; + fileName: string; + status: 'pending' | 'processing' | 'completed' | 'error'; + originalEncoding?: string; + resultEncoding?: string; + error?: string; +} + +export interface ProcessingProgress { + current: number; + total: number; + currentFile?: string; + stats: IBatchStats; +} + +export function setupIPC(appInstance: any): void { + console.log('🔗 Setting up IPC handlers...'); + + const processor = new SubtitleProcessor(); + const batchProcessor = new BatchProcessor(); + const configMapper = new ConfigMapper(); + + // File dialog handlers + ipcMain.handle('show-open-dialog', async () => { + const result = await dialog.showOpenDialog({ + title: 'Select Subtitle Files', + filters: [ + { name: 'Subtitle Files', extensions: ['srt', 'sub', 'ass', 'ssa', 'txt'] }, + { name: 'All Files', extensions: ['*'] }, + ], + properties: ['openFile', 'multiSelections'], + }); + + return result; + }); + + // File validation + ipcMain.handle('validate-files', async (_, filePaths: string[]) => { + const validFiles: string[] = []; + const invalidFiles: string[] = []; + + for (const filePath of filePaths) { + const ext = path.extname(filePath).toLowerCase(); + const fileName = path.basename(filePath); + + // Check if it's a supported file type + if (['.srt', '.sub', '.ass', '.ssa', '.txt'].includes(ext)) { + // Skip files that are already processed (contain .subzilla. in the name) + if (fileName.includes('.subzilla.')) { + console.log(`⏭️ Skipping already processed file: ${fileName}`); + invalidFiles.push(filePath); + } else { + validFiles.push(filePath); + } + } else { + invalidFiles.push(filePath); + } + } + + return { validFiles, invalidFiles }; + }); + + // Single file processing + ipcMain.handle('process-file', async (_, filePath: string, options?: IConvertOptions) => { + try { + const fileName = path.basename(filePath); + + // Skip files that are already processed + if (fileName.includes('.subzilla.')) { + console.log(`⏭️ Skipping already processed file: ${fileName}`); + return { + success: false, + error: 'File has already been processed by Subzilla', + }; + } + + console.log(`🔄 Processing file: ${filePath}`); + + const config = await configMapper.getConfig(); + const processOptions: IConvertOptions = { + ...config.output, + ...(config.strip && { strip: config.strip }), + ...options, + }; + + const result = await processor.processFile(filePath, undefined, processOptions); + + console.log(`✅ File processed successfully: ${result.outputPath}`); + + return { + success: true, + outputPath: result.outputPath, + backupPath: result.backupPath, + }; + } catch (error) { + console.error(`❌ Error processing file ${filePath}:`, error); + + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error', + }; + } + }); + + // Batch file processing + ipcMain.handle('process-files-batch', async (event, filePaths: string[], options?: IConvertOptions) => { + try { + console.log(`🔄 Starting batch processing of ${filePaths.length} files...`); + + const config = await configMapper.getConfig(); + const batchOptions = { + common: { + ...config.output, + ...(config.strip && { strip: config.strip }), + ...options, + }, + batch: { + recursive: false, + parallel: config.batch?.parallel ?? true, + skipExisting: config.batch?.skipExisting ?? false, + chunkSize: config.batch?.chunkSize ?? 5, + preserveStructure: false, + }, + }; + + // Set up progress reporting + const sendProgress = (progress: ProcessingProgress) => { + event.sender.send('processing-progress', progress); + }; + + // Process files + const stats = await batchProcessor.processBatch(filePaths.join(','), batchOptions); + + console.log(`✅ Batch processing completed. Success: ${stats.successful}, Failed: ${stats.failed}`); + + return { + success: true, + stats, + }; + } catch (error) { + console.error('❌ Error in batch processing:', error); + + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error', + }; + } + }); + + // Configuration handlers + ipcMain.handle('get-config', async () => { + try { + return await configMapper.getConfig(); + } catch (error) { + console.error('❌ Error getting config:', error); + + return configMapper.getDefaultConfigData(); + } + }); + + ipcMain.handle('save-config', async (_, config: IConfig) => { + try { + await configMapper.saveConfig(config); + console.log('💾 Configuration saved successfully'); + + return { success: true }; + } catch (error) { + console.error('❌ Error saving config:', error); + + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error', + }; + } + }); + + ipcMain.handle('reset-config', async () => { + try { + await configMapper.resetConfig(); + console.log('🔄 Configuration reset to defaults'); + + return { success: true }; + } catch (error) { + console.error('❌ Error resetting config:', error); + + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error', + }; + } + }); + + // Window management + ipcMain.handle('show-preferences', () => { + appInstance.createPreferencesWindow(); + }); + + ipcMain.handle('close-preferences', () => { + const prefsWindow = appInstance.getPreferencesWindow(); + + if (prefsWindow) { + prefsWindow.close(); + } + }); + + // File system operations + ipcMain.handle('show-in-finder', async (_, filePath: string) => { + shell.showItemInFolder(filePath); + }); + + ipcMain.handle('open-file-external', async (_, filePath: string) => { + shell.openPath(filePath); + }); + + // App info + ipcMain.handle('get-app-version', () => { + return app.getVersion(); + }); + + ipcMain.handle('get-app-name', () => { + return app.getName(); + }); + + // Config path for preferences + ipcMain.handle('get-config-path', () => { + return configMapper.getConfigPath(); + }); + + console.log('✅ IPC handlers setup complete'); +} diff --git a/packages/mac/src/main/menu.ts b/packages/mac/src/main/menu.ts new file mode 100644 index 0000000..ce543b1 --- /dev/null +++ b/packages/mac/src/main/menu.ts @@ -0,0 +1,131 @@ +import { Menu, MenuItemConstructorOptions, app, shell } from 'electron'; + +export function createMenu(appInstance: any): Menu { + console.log('📋 Creating native menu bar...'); + + const template: MenuItemConstructorOptions[] = [ + { + label: 'Subzilla', + submenu: [ + { + label: 'About Subzilla', + click: () => { + const version = app.getVersion(); + + shell.openExternal(`https://github.com/onyxdevs/subzilla`); + }, + }, + { type: 'separator' }, + { + label: 'Preferences...', + accelerator: 'Cmd+,', + click: () => { + appInstance.createPreferencesWindow(); + }, + }, + { type: 'separator' }, + { label: 'Services', submenu: [] }, + { type: 'separator' }, + { label: 'Hide Subzilla', role: 'hide' }, + { label: 'Hide Others', role: 'hideOthers' }, + { label: 'Show All', role: 'unhide' }, + { type: 'separator' }, + { label: 'Quit Subzilla', role: 'quit' }, + ], + }, + { + label: 'File', + submenu: [ + { + label: 'Open Files...', + accelerator: 'Cmd+O', + click: () => { + appInstance.openFiles(); + }, + }, + { + label: 'Open Recent', + submenu: [{ label: 'Clear Menu', click: () => app.clearRecentDocuments() }], + }, + { type: 'separator' }, + { + label: 'Clear List', + accelerator: 'Cmd+Delete', + click: () => { + appInstance.clearFileList(); + }, + }, + { type: 'separator' }, + { label: 'Close Window', role: 'close' }, + ], + }, + { + label: 'Edit', + submenu: [ + { label: 'Undo', role: 'undo' }, + { label: 'Redo', role: 'redo' }, + { type: 'separator' }, + { label: 'Cut', role: 'cut' }, + { label: 'Copy', role: 'copy' }, + { label: 'Paste', role: 'paste' }, + { label: 'Select All', role: 'selectAll' }, + ], + }, + { + label: 'View', + submenu: [ + { label: 'Reload', role: 'reload' }, + { label: 'Force Reload', role: 'forceReload' }, + { label: 'Toggle Developer Tools', role: 'toggleDevTools' }, + { type: 'separator' }, + { label: 'Actual Size', role: 'resetZoom' }, + { label: 'Zoom In', role: 'zoomIn' }, + { label: 'Zoom Out', role: 'zoomOut' }, + { type: 'separator' }, + { label: 'Toggle Fullscreen', role: 'togglefullscreen' }, + ], + }, + { + label: 'Window', + submenu: [ + { label: 'Minimize', role: 'minimize' }, + { label: 'Close', role: 'close' }, + { type: 'separator' }, + { label: 'Bring All to Front', role: 'front' }, + ], + }, + { + label: 'Help', + submenu: [ + { + label: 'Subzilla Help', + click: () => { + shell.openExternal('https://github.com/onyxdevs/subzilla/wiki'); + }, + }, + { + label: 'Report Issue', + click: () => { + shell.openExternal('https://github.com/onyxdevs/subzilla/issues'); + }, + }, + { type: 'separator' }, + { + label: 'Keyboard Shortcuts', + click: () => { + // Show keyboard shortcuts overlay + const mainWindow = appInstance.getMainWindow(); + if (mainWindow) { + mainWindow.webContents.send('show-shortcuts'); + } + }, + }, + ], + }, + ]; + + const menu = Menu.buildFromTemplate(template); + console.log('✅ Menu bar created successfully'); + + return menu; +} diff --git a/packages/mac/src/main/preferences.ts b/packages/mac/src/main/preferences.ts new file mode 100644 index 0000000..bff9439 --- /dev/null +++ b/packages/mac/src/main/preferences.ts @@ -0,0 +1,305 @@ +import Store from 'electron-store'; + +import { IConfig, IStripOptions } from '@subzilla/types'; + +export interface MacAppPreferences { + // Application-specific preferences + notifications: boolean; + sounds: boolean; + autoUpdate: boolean; + startMinimized: boolean; + showInDock: boolean; + + // Window preferences + rememberWindowSize: boolean; + lastWindowBounds?: { + width: number; + height: number; + x?: number; + y?: number; + }; +} + +export class ConfigMapper { + private store: Store; + + constructor() { + console.log('⚙️ Initializing configuration store...'); + + this.store = new Store({ + name: 'preferences', + defaults: this.getDefaultConfig(), + schema: { + input: { + type: 'object', + properties: { + encoding: { type: 'string' }, + format: { type: 'string' }, + }, + }, + output: { + type: 'object', + properties: { + directory: { type: 'string' }, + createBackup: { type: 'boolean' }, + overwriteBackup: { type: 'boolean' }, + format: { type: 'string' }, + encoding: { type: 'string' }, + bom: { type: 'boolean' }, + lineEndings: { type: 'string' }, + overwriteInput: { type: 'boolean' }, + overwriteExisting: { type: 'boolean' }, + }, + }, + strip: { + type: 'object', + properties: { + html: { type: 'boolean' }, + colors: { type: 'boolean' }, + styles: { type: 'boolean' }, + urls: { type: 'boolean' }, + timestamps: { type: 'boolean' }, + numbers: { type: 'boolean' }, + punctuation: { type: 'boolean' }, + emojis: { type: 'boolean' }, + brackets: { type: 'boolean' }, + bidiControl: { type: 'boolean' }, + }, + }, + batch: { + type: 'object', + properties: { + recursive: { type: 'boolean' }, + parallel: { type: 'boolean' }, + skipExisting: { type: 'boolean' }, + maxDepth: { type: 'number' }, + preserveStructure: { type: 'boolean' }, + chunkSize: { type: 'number' }, + retryCount: { type: 'number' }, + retryDelay: { type: 'number' }, + failFast: { type: 'boolean' }, + }, + }, + app: { + type: 'object', + properties: { + notifications: { type: 'boolean' }, + sounds: { type: 'boolean' }, + autoUpdate: { type: 'boolean' }, + startMinimized: { type: 'boolean' }, + showInDock: { type: 'boolean' }, + rememberWindowSize: { type: 'boolean' }, + }, + }, + }, + }); + + console.log('✅ Configuration store initialized'); + } + + private getDefaultConfig(): IConfig & { app: MacAppPreferences } { + return { + input: { + encoding: 'auto', + format: 'auto', + }, + output: { + encoding: 'utf8', + createBackup: false, + overwriteBackup: false, + bom: true, + lineEndings: 'auto', + overwriteInput: false, + overwriteExisting: true, + }, + strip: { + html: false, + colors: false, + styles: false, + urls: false, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: true, // Default to true for better Arabic support + }, + batch: { + recursive: false, + parallel: true, + skipExisting: false, + preserveStructure: false, + chunkSize: 5, + retryCount: 0, + retryDelay: 1000, + failFast: false, + }, + app: { + notifications: true, + sounds: true, + autoUpdate: true, + startMinimized: false, + showInDock: true, + rememberWindowSize: true, + }, + }; + } + + public getDefaultConfigData(): IConfig & { app: MacAppPreferences } { + return { + input: { + encoding: 'auto', + format: 'auto', + }, + output: { + encoding: 'utf8', + createBackup: false, + overwriteBackup: false, + bom: true, + lineEndings: 'auto', + overwriteInput: false, + overwriteExisting: true, + }, + strip: { + html: false, + colors: false, + styles: false, + urls: false, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: true, + }, + batch: { + recursive: false, + parallel: true, + skipExisting: false, + preserveStructure: false, + chunkSize: 5, + retryCount: 0, + retryDelay: 1000, + failFast: false, + }, + app: { + notifications: true, + sounds: true, + autoUpdate: true, + startMinimized: false, + showInDock: true, + rememberWindowSize: true, + }, + }; + } + + public async getConfig(): Promise { + const fullConfig = this.store.store; + + // Return only the IConfig part (without app preferences) + const { app, ...config } = fullConfig; + + return config; + } + + public async getAppPreferences(): Promise { + return this.store.get('app', this.getDefaultConfig().app); + } + + public async saveConfig(config: IConfig): Promise { + console.log('💾 Saving configuration...'); + + // Preserve app preferences while updating core config + const currentApp = await this.getAppPreferences(); + + this.store.set({ ...config, app: currentApp }); + + console.log('✅ Configuration saved'); + } + + public async saveAppPreferences(preferences: MacAppPreferences): Promise { + console.log('💾 Saving app preferences...'); + this.store.set('app', preferences); + console.log('✅ App preferences saved'); + } + + public async resetConfig(): Promise { + console.log('🔄 Resetting configuration to defaults...'); + this.store.clear(); + console.log('✅ Configuration reset'); + } + + public getConfigPath(): string { + return this.store.path; + } + + public getStore(): any { + return this.store; + } + + // Preset management for quick formatting options + public getFormattingPresets(): Record { + return { + None: { + html: false, + colors: false, + styles: false, + urls: false, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: false, + }, + 'Basic Clean': { + html: true, + colors: true, + styles: true, + urls: false, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: true, + }, + 'Deep Clean': { + html: true, + colors: true, + styles: true, + urls: true, + timestamps: false, + numbers: false, + punctuation: true, + emojis: false, + brackets: true, + bidiControl: true, + }, + 'Arabic Optimized': { + html: true, + colors: true, + styles: true, + urls: true, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: true, + }, + 'Maximum Clean': { + html: true, + colors: true, + styles: true, + urls: true, + timestamps: true, + numbers: true, + punctuation: true, + emojis: true, + brackets: true, + bidiControl: true, + }, + }; + } +} diff --git a/packages/mac/src/main/updater.ts b/packages/mac/src/main/updater.ts new file mode 100644 index 0000000..2979a54 --- /dev/null +++ b/packages/mac/src/main/updater.ts @@ -0,0 +1,125 @@ +import { autoUpdater } from 'electron-updater'; +import { dialog, BrowserWindow, Notification } from 'electron'; + +export class AutoUpdater { + private mainWindow: BrowserWindow; + + constructor(mainWindow: BrowserWindow) { + console.log('🔄 Initializing auto-updater...'); + this.mainWindow = mainWindow; + this.setupUpdater(); + } + + private setupUpdater(): void { + // Configure updater + autoUpdater.autoDownload = false; + autoUpdater.autoInstallOnAppQuit = true; + + // Check for updates on startup (after 3 seconds) + setTimeout(() => { + autoUpdater.checkForUpdatesAndNotify(); + }, 3000); + + // Update available + autoUpdater.on('update-available', (info) => { + console.log('📦 Update available:', info.version); + + const response = dialog.showMessageBoxSync(this.mainWindow, { + type: 'info', + title: 'Update Available', + message: `A new version of Subzilla is available (v${info.version})`, + detail: 'Would you like to download it now? The update will be installed when you restart the app.', + buttons: ['Download', 'Later'], + defaultId: 0, + cancelId: 1, + }); + + if (response === 0) { + autoUpdater.downloadUpdate(); + + // Show notification + new Notification({ + title: 'Subzilla Update', + body: 'Downloading update in the background...', + silent: false, + }).show(); + } + }); + + // Update not available + autoUpdater.on('update-not-available', () => { + console.log('✅ App is up to date'); + }); + + // Download progress + autoUpdater.on('download-progress', (progressObj) => { + const percent = Math.round(progressObj.percent); + console.log(`📥 Download progress: ${percent}%`); + + // Update dock badge with download progress + if (process.platform === 'darwin') { + const { app } = require('electron'); + app.dock.setBadge(`${percent}%`); + } + + // Send progress to renderer + this.mainWindow.webContents.send('update-download-progress', { + percent, + transferred: progressObj.transferred, + total: progressObj.total, + }); + }); + + // Update downloaded + autoUpdater.on('update-downloaded', (info) => { + console.log('✅ Update downloaded:', info.version); + + // Clear dock badge + if (process.platform === 'darwin') { + const { app } = require('electron'); + app.dock.setBadge(''); + } + + const response = dialog.showMessageBoxSync(this.mainWindow, { + type: 'info', + title: 'Update Ready', + message: `Update v${info.version} has been downloaded`, + detail: 'The update will be installed when you restart Subzilla. Would you like to restart now?', + buttons: ['Restart Now', 'Later'], + defaultId: 0, + cancelId: 1, + }); + + if (response === 0) { + autoUpdater.quitAndInstall(); + } + }); + + // Update error + autoUpdater.on('error', (error) => { + console.error('❌ Auto-updater error:', error); + + // Don't show error dialog for network issues + if (!error.message.includes('net::')) { + dialog.showErrorBox('Update Error', `There was a problem updating Subzilla: ${error.message}`); + } + }); + + console.log('✅ Auto-updater setup complete'); + } + + public checkForUpdates(): void { + console.log('🔍 Manually checking for updates...'); + autoUpdater.checkForUpdatesAndNotify(); + } + + public downloadUpdate(): void { + console.log('📥 Manually downloading update...'); + autoUpdater.downloadUpdate(); + } + + public quitAndInstall(): void { + console.log('🔄 Quitting and installing update...'); + autoUpdater.quitAndInstall(); + } +} diff --git a/packages/mac/src/preload/index.ts b/packages/mac/src/preload/index.ts new file mode 100644 index 0000000..a152580 --- /dev/null +++ b/packages/mac/src/preload/index.ts @@ -0,0 +1,104 @@ +import { contextBridge, ipcRenderer } from 'electron'; +import { IConfig, IConvertOptions, IBatchStats } from '@subzilla/types'; + +export interface SubzillaAPI { + // File operations + showOpenDialog: () => Promise; + validateFiles: (filePaths: string[]) => Promise<{ validFiles: string[]; invalidFiles: string[] }>; + processFile: ( + filePath: string, + options?: IConvertOptions, + ) => Promise<{ success: boolean; outputPath?: string; backupPath?: string; error?: string }>; + processFilesBatch: ( + filePaths: string[], + options?: IConvertOptions, + ) => Promise<{ success: boolean; stats?: IBatchStats; error?: string }>; + + // Configuration + getConfig: () => Promise; + saveConfig: (config: IConfig) => Promise<{ success: boolean; error?: string }>; + resetConfig: () => Promise<{ success: boolean; error?: string }>; + + // Window management + showPreferences: () => Promise; + closePreferences: () => Promise; + + // System integration + showInFinder: (filePath: string) => Promise; + openFileExternal: (filePath: string) => Promise; + + // App info + getAppVersion: () => Promise; + getAppName: () => Promise; + getConfigPath: () => Promise; + + // Event listeners + onFileOpened: (callback: (filePath: string) => void) => void; + onProcessingProgress: (callback: (progress: any) => void) => void; + onUpdateDownloadProgress: (callback: (progress: any) => void) => void; + onOpenFilesDialog: (callback: () => void) => void; + onClearFileList: (callback: () => void) => void; + onShowShortcuts: (callback: () => void) => void; + + // Event cleanup + removeAllListeners: (channel: string) => void; +} + +// Expose protected methods that allow the renderer process to use +// the ipcRenderer without exposing the entire object +const api: SubzillaAPI = { + // File operations + showOpenDialog: () => ipcRenderer.invoke('show-open-dialog'), + validateFiles: (filePaths: string[]) => ipcRenderer.invoke('validate-files', filePaths), + processFile: (filePath: string, options?: IConvertOptions) => ipcRenderer.invoke('process-file', filePath, options), + processFilesBatch: (filePaths: string[], options?: IConvertOptions) => + ipcRenderer.invoke('process-files-batch', filePaths, options), + + // Configuration + getConfig: () => ipcRenderer.invoke('get-config'), + saveConfig: (config: IConfig) => ipcRenderer.invoke('save-config', config), + resetConfig: () => ipcRenderer.invoke('reset-config'), + + // Window management + showPreferences: () => ipcRenderer.invoke('show-preferences'), + closePreferences: () => ipcRenderer.invoke('close-preferences'), + + // System integration + showInFinder: (filePath: string) => ipcRenderer.invoke('show-in-finder', filePath), + openFileExternal: (filePath: string) => ipcRenderer.invoke('open-file-external', filePath), + + // App info + getAppVersion: () => ipcRenderer.invoke('get-app-version'), + getAppName: () => ipcRenderer.invoke('get-app-name'), + getConfigPath: () => ipcRenderer.invoke('get-config-path'), + + // Event listeners + onFileOpened: (callback: (filePath: string) => void) => { + ipcRenderer.on('file-opened', (_, filePath) => callback(filePath)); + }, + onProcessingProgress: (callback: (progress: any) => void) => { + ipcRenderer.on('processing-progress', (_, progress) => callback(progress)); + }, + onUpdateDownloadProgress: (callback: (progress: any) => void) => { + ipcRenderer.on('update-download-progress', (_, progress) => callback(progress)); + }, + onOpenFilesDialog: (callback: () => void) => { + ipcRenderer.on('open-files-dialog', () => callback()); + }, + onClearFileList: (callback: () => void) => { + ipcRenderer.on('clear-file-list', () => callback()); + }, + onShowShortcuts: (callback: () => void) => { + ipcRenderer.on('show-shortcuts', () => callback()); + }, + + // Event cleanup + removeAllListeners: (channel: string) => { + ipcRenderer.removeAllListeners(channel); + }, +}; + +// Expose the API to the renderer process +contextBridge.exposeInMainWorld('subzilla', api); + +console.log('🔒 Context bridge established successfully'); diff --git a/packages/mac/src/renderer/index.html b/packages/mac/src/renderer/index.html new file mode 100644 index 0000000..11637b1 --- /dev/null +++ b/packages/mac/src/renderer/index.html @@ -0,0 +1,104 @@ + + + + + + + Subzilla + + + +
+ +
+
+ +

Drop subtitle files here

+

or

+
+ Supports: .srt .sub .ass .ssa .txt +
+
+
+ + + + + + + + + + + + +
+ + + + + + + \ No newline at end of file diff --git a/packages/mac/src/renderer/js/app.js b/packages/mac/src/renderer/js/app.js new file mode 100644 index 0000000..a70e0b2 --- /dev/null +++ b/packages/mac/src/renderer/js/app.js @@ -0,0 +1,567 @@ +// Main application logic for Subzilla Mac +class SubzillaApp { + constructor() { + console.log('🦎 Initializing Subzilla renderer...'); + + this.files = new Map(); // Map + this.isProcessing = false; + this.currentState = 'empty'; // 'empty', 'processing', 'completed' + + this.initializeElements(); + this.setupEventListeners(); + this.setupIPC(); + this.loadInitialState(); + } + + initializeElements() { + // State containers + this.emptyState = document.getElementById('empty-state'); + this.processingState = document.getElementById('processing-state'); + + // Interactive elements + this.browseButton = document.getElementById('browse-button'); + this.fileInput = document.getElementById('file-input'); + this.clearButton = document.getElementById('clear-button'); + this.addMoreButton = document.getElementById('add-more-button'); + this.preferencesButton = document.getElementById('preferences-button'); + + // Display elements + this.fileList = document.getElementById('file-list'); + this.progressBar = document.getElementById('progress-fill'); + this.progressText = document.getElementById('progress-text'); + this.statusBar = document.getElementById('status-bar'); + this.statusText = document.getElementById('status-text'); + + // Overlays + this.dropOverlay = document.getElementById('drop-overlay'); + this.shortcutsOverlay = document.getElementById('shortcuts-overlay'); + this.closeShortcuts = document.getElementById('close-shortcuts'); + } + + setupEventListeners() { + // Browse button + this.browseButton.addEventListener('click', () => this.openFileDialog()); + this.addMoreButton.addEventListener('click', () => this.openFileDialog()); + + // File input + this.fileInput.addEventListener('change', (e) => this.handleFileSelection(e)); + + // Clear button + this.clearButton.addEventListener('click', () => this.clearFileList()); + + // Preferences + this.preferencesButton.addEventListener('click', () => this.openPreferences()); + + // Shortcuts overlay + this.closeShortcuts.addEventListener('click', () => this.hideShortcuts()); + + // Keyboard shortcuts + document.addEventListener('keydown', (e) => this.handleKeyboard(e)); + + // Drag and drop + this.setupDragAndDrop(); + } + + setupDragAndDrop() { + const body = document.body; + let dragCounter = 0; + + // Prevent default drag behaviors on document + document.addEventListener('dragover', (e) => e.preventDefault()); + document.addEventListener('drop', (e) => e.preventDefault()); + + // Body drag events + body.addEventListener('dragenter', (e) => { + e.preventDefault(); + dragCounter++; + body.classList.add('drag-over'); + }); + + body.addEventListener('dragleave', (e) => { + e.preventDefault(); + dragCounter--; + if (dragCounter === 0) { + body.classList.remove('drag-over'); + } + }); + + body.addEventListener('dragover', (e) => { + e.preventDefault(); + }); + + body.addEventListener('drop', (e) => { + e.preventDefault(); + dragCounter = 0; + body.classList.remove('drag-over'); + + const files = Array.from(e.dataTransfer.files); + this.handleDroppedFiles(files); + }); + } + + setupIPC() { + // File opened from system + window.subzilla.onFileOpened((filePath) => { + this.addFile(filePath); + }); + + // Menu actions + window.subzilla.onOpenFilesDialog(() => this.openFileDialog()); + window.subzilla.onClearFileList(() => this.clearFileList()); + window.subzilla.onShowShortcuts(() => this.showShortcuts()); + + // Processing progress + window.subzilla.onProcessingProgress((progress) => { + this.updateProgress(progress); + }); + + // Update download progress + window.subzilla.onUpdateDownloadProgress((progress) => { + this.updateStatus(`Downloading update: ${progress.percent}%`); + }); + } + + async loadInitialState() { + try { + const appName = await window.subzilla.getAppName(); + const version = await window.subzilla.getAppVersion(); + console.log(`🚀 ${appName} v${version} ready`); + + this.updateStatus('Ready'); + } catch (error) { + console.error('❌ Error loading initial state:', error); + } + } + + async openFileDialog() { + try { + const result = await window.subzilla.showOpenDialog(); + if (!result.canceled && result.filePaths.length > 0) { + this.addFiles(result.filePaths); + } + } catch (error) { + console.error('❌ Error opening file dialog:', error); + this.showError('Failed to open file dialog'); + } + } + + async handleFileSelection(event) { + const files = Array.from(event.target.files); + const filePaths = files.map((file) => file.path); + this.addFiles(filePaths); + + // Reset file input + event.target.value = ''; + } + + async handleDroppedFiles(files) { + const filePaths = files.map((file) => file.path || file.name); + console.log(`📁 Handling ${files.length} dropped files:`, filePaths); + this.addFiles(filePaths); + } + + async addFiles(filePaths) { + try { + console.log(`📁 Adding ${filePaths.length} files...`); + + // Validate files + const validation = await window.subzilla.validateFiles(filePaths); + + if (validation.invalidFiles.length > 0) { + this.showError(`${validation.invalidFiles.length} files skipped (unsupported format)`); + } + + // Add valid files + for (const filePath of validation.validFiles) { + this.addFile(filePath); + } + + // Switch to processing state if we have files + if (this.files.size > 0) { + this.switchState('processing'); + this.startProcessing(); + } + } catch (error) { + console.error('❌ Error adding files:', error); + this.showError('Failed to add files'); + } + } + + addFile(filePath) { + const fileName = filePath.split('/').pop() || filePath; + const fileId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + + const fileItem = { + id: fileId, + filePath, + fileName, + status: 'pending', + originalEncoding: undefined, + resultEncoding: undefined, + error: undefined, + }; + + this.files.set(fileId, fileItem); + this.renderFileList(); + + console.log(`📄 Added file: ${fileName}`); + } + + async startProcessing() { + if (this.isProcessing) return; + + this.isProcessing = true; + const fileArray = Array.from(this.files.values()); + + console.log(`🔄 Starting processing of ${fileArray.length} files...`); + this.updateStatus(`Processing ${fileArray.length} files...`); + + // Use the FileProcessingManager for individual file processing with UI updates + if (window.fileProcessingManager) { + await window.fileProcessingManager.processFiles(fileArray); + + // Calculate final stats + const completed = fileArray.filter((f) => f.status === 'completed').length; + const failed = fileArray.filter((f) => f.status === 'error').length; + + this.updateStatus(`✓ ${completed} converted, ${failed} failed`); + } + + this.isProcessing = false; + } + + markAllCompleted() { + for (const [id, file] of this.files) { + if (file.status === 'processing' || file.status === 'pending') { + file.status = 'completed'; + file.resultEncoding = 'UTF-8'; + } + } + this.renderFileList(); + } + + updateProgress(progress) { + const percent = Math.round((progress.current / progress.total) * 100); + this.progressBar.style.width = `${percent}%`; + this.progressText.textContent = `${progress.current} of ${progress.total} files`; + + if (progress.currentFile) { + this.updateStatus(`Processing: ${progress.currentFile}`); + } + } + + renderFileList() { + this.fileList.innerHTML = ''; + + for (const file of this.files.values()) { + const fileElement = this.createFileElement(file); + this.fileList.appendChild(fileElement); + } + } + + createFileElement(file) { + const element = document.createElement('div'); + element.className = `file-item ${file.status}`; + element.dataset.fileId = file.id; + + const statusIcon = this.getStatusIcon(file.status); + const statusText = this.getStatusText(file.status); + + element.innerHTML = ` +
${file.fileName}
+
+ ${statusIcon} + ${statusText} +
+
${file.originalEncoding || '—'}
+
${file.resultEncoding || '—'}
+ `; + + // Add click handler for completed files + if (file.status === 'completed') { + element.style.cursor = 'pointer'; + element.addEventListener('click', () => { + window.subzilla.showInFinder(file.filePath); + }); + } + + return element; + } + + getStatusIcon(status) { + switch (status) { + case 'pending': + return '⏸'; + case 'processing': + return '⟳'; + case 'completed': + return '✅'; + case 'error': + return '❌'; + default: + return '—'; + } + } + + getStatusText(status) { + switch (status) { + case 'pending': + return 'Waiting'; + case 'processing': + return 'Processing'; + case 'completed': + return 'Done'; + case 'error': + return 'Error'; + default: + return '—'; + } + } + + switchState(newState) { + console.log(`🔄 Switching to ${newState} state`); + + // Hide all states + this.emptyState.classList.add('hidden'); + this.processingState.classList.add('hidden'); + + // Show target state + switch (newState) { + case 'empty': + this.emptyState.classList.remove('hidden'); + this.statusBar.classList.add('hidden'); + break; + case 'processing': + this.processingState.classList.remove('hidden'); + this.statusBar.classList.remove('hidden'); + break; + } + + this.currentState = newState; + } + + clearFileList() { + console.log('🗑️ Clearing file list...'); + this.files.clear(); + this.isProcessing = false; + this.switchState('empty'); + this.updateStatus('Ready'); + } + + async openPreferences() { + try { + await window.subzilla.showPreferences(); + } catch (error) { + console.error('❌ Error opening preferences:', error); + } + } + + showShortcuts() { + this.shortcutsOverlay.classList.remove('hidden'); + } + + hideShortcuts() { + this.shortcutsOverlay.classList.add('hidden'); + } + + handleKeyboard(event) { + // Handle keyboard shortcuts + if (event.metaKey || event.ctrlKey) { + switch (event.key) { + case 'o': + event.preventDefault(); + this.openFileDialog(); + break; + case 'Backspace': + case 'Delete': + event.preventDefault(); + this.clearFileList(); + break; + case ',': + event.preventDefault(); + this.openPreferences(); + break; + } + } + + // Space to pause/resume (if processing) + if (event.key === ' ' && this.isProcessing) { + event.preventDefault(); + // TODO: Implement pause/resume functionality + } + + // Escape to close overlays + if (event.key === 'Escape') { + this.hideShortcuts(); + } + } + + updateStatus(message) { + this.statusText.textContent = message; + console.log(`📊 Status: ${message}`); + } + + showError(message) { + this.updateStatus(`❌ ${message}`); + console.error(`❌ Error: ${message}`); + + // Show error for 3 seconds, then revert + setTimeout(() => { + if (!this.isProcessing) { + this.updateStatus('Ready'); + } + }, 3000); + } + + // Utility methods + generateFileId() { + return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + } + + formatFileSize(bytes) { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; + } + + formatDuration(ms) { + if (ms < 1000) return `${ms}ms`; + if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`; + return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`; + } +} + +// Drag and Drop Handler +class DragDropHandler { + constructor(app) { + this.app = app; + this.setupEventListeners(); + } + + setupEventListeners() { + const dropZone = document.body; + let dragCounter = 0; + + // Prevent default drag behaviors + ['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => { + dropZone.addEventListener(eventName, this.preventDefaults, false); + document.body.addEventListener(eventName, this.preventDefaults, false); + }); + + // Highlight drop zone when item is dragged over it + ['dragenter', 'dragover'].forEach((eventName) => { + dropZone.addEventListener(eventName, () => this.highlight(), false); + }); + + ['dragleave', 'drop'].forEach((eventName) => { + dropZone.addEventListener(eventName, () => this.unhighlight(), false); + }); + + // Handle dropped files + dropZone.addEventListener('drop', (e) => this.handleDrop(e), false); + } + + preventDefaults(e) { + e.preventDefault(); + e.stopPropagation(); + } + + highlight() { + document.body.classList.add('drag-over'); + } + + unhighlight() { + document.body.classList.remove('drag-over'); + } + + async handleDrop(e) { + const dt = e.dataTransfer; + const files = dt.files; + + if (files.length > 0) { + console.log(`📁 Files dropped: ${files.length}`); + this.app.handleDroppedFiles(Array.from(files)); + } + } + + isValidSubtitle(filePath) { + const validExtensions = ['.srt', '.sub', '.ass', '.ssa', '.txt']; + const ext = filePath.toLowerCase().split('.').pop(); + return validExtensions.includes(`.${ext}`); + } +} + +// File Processing Manager +class FileProcessingManager { + constructor(app) { + this.app = app; + this.processingQueue = []; + this.isProcessing = false; + } + + async processFiles(files) { + if (this.isProcessing) { + console.log('⚠️ Already processing files'); + return; + } + + this.isProcessing = true; + console.log(`🔄 Starting to process ${files.length} files...`); + + try { + for (let i = 0; i < files.length; i++) { + const file = files[i]; + await this.processFile(file, i + 1, files.length); + } + + console.log('✅ All files processed'); + } catch (error) { + console.error('❌ Error during file processing:', error); + } finally { + this.isProcessing = false; + } + } + + async processFile(file, current, total) { + try { + // Update file status + file.status = 'processing'; + this.app.renderFileList(); + this.app.updateProgress({ current: current - 1, total, currentFile: file.fileName }); + + // Process the file + const result = await window.subzilla.processFile(file.filePath); + + if (result.success) { + file.status = 'completed'; + file.resultEncoding = 'UTF-8'; + console.log(`✅ Processed: ${file.fileName}`); + } else { + file.status = 'error'; + file.error = result.error; + console.error(`❌ Failed to process: ${file.fileName} - ${result.error}`); + } + } catch (error) { + file.status = 'error'; + file.error = error.message; + console.error(`❌ Error processing ${file.fileName}:`, error); + } + + // Update UI + this.app.renderFileList(); + this.app.updateProgress({ current, total }); + } +} + +// Initialize the application when DOM is ready +document.addEventListener('DOMContentLoaded', () => { + console.log('🚀 DOM loaded, starting Subzilla App...'); + + window.subzillaApp = new SubzillaApp(); + // window.dragDropHandler = new DragDropHandler(window.subzillaApp); // Disabled - main app handles drag/drop + window.fileProcessingManager = new FileProcessingManager(window.subzillaApp); + + console.log('✅ Subzilla App initialized successfully'); +}); diff --git a/packages/mac/src/renderer/js/preferences.js b/packages/mac/src/renderer/js/preferences.js new file mode 100644 index 0000000..ebe7264 --- /dev/null +++ b/packages/mac/src/renderer/js/preferences.js @@ -0,0 +1,573 @@ +// Preferences window logic for Subzilla Mac +class PreferencesApp { + constructor() { + console.log('⚙️ Initializing Preferences...'); + + this.config = null; + this.originalConfig = null; + this.hasChanges = false; + + this.initializeElements(); + this.setupEventListeners(); + this.loadConfiguration(); + this.loadAppInfo(); + this.loadConfigPath(); + } + + initializeElements() { + // Tab navigation + this.tabButtons = document.querySelectorAll('.tab-button'); + this.tabPanes = document.querySelectorAll('.tab-pane'); + + // General tab + this.notifications = document.getElementById('notifications'); + this.sounds = document.getElementById('sounds'); + this.autoUpdate = document.getElementById('auto-update'); + this.showInDock = document.getElementById('show-in-dock'); + this.createBackup = document.getElementById('create-backup'); + this.overwriteBackup = document.getElementById('overwrite-backup'); + this.overwriteInput = document.getElementById('overwrite-input'); + + // Formatting tab + this.presetButtons = document.querySelectorAll('.preset-button'); + this.stripHtml = document.getElementById('strip-html'); + this.stripColors = document.getElementById('strip-colors'); + this.stripStyles = document.getElementById('strip-styles'); + this.stripUrls = document.getElementById('strip-urls'); + this.stripTimestamps = document.getElementById('strip-timestamps'); + this.stripNumbers = document.getElementById('strip-numbers'); + this.stripPunctuation = document.getElementById('strip-punctuation'); + this.stripEmojis = document.getElementById('strip-emojis'); + this.stripBrackets = document.getElementById('strip-brackets'); + this.stripBidiControl = document.getElementById('strip-bidi-control'); + + // Output tab + this.outputEncoding = document.getElementById('output-encoding'); + this.outputBom = document.getElementById('output-bom'); + this.lineEndings = document.getElementById('line-endings'); + this.outputFormat = document.getElementById('output-format'); + this.overwriteExisting = document.getElementById('overwrite-existing'); + + // Processing tab + this.parallelProcessing = document.getElementById('parallel-processing'); + this.chunkSize = document.getElementById('chunk-size'); + this.skipExisting = document.getElementById('skip-existing'); + this.failFast = document.getElementById('fail-fast'); + this.retryCount = document.getElementById('retry-count'); + + // Advanced tab + this.configPath = document.getElementById('config-path'); + this.showConfigButton = document.getElementById('show-config-button'); + this.resetConfigButton = document.getElementById('reset-config-button'); + this.appName = document.getElementById('app-name'); + this.appVersion = document.getElementById('app-version'); + this.githubLink = document.getElementById('github-link'); + this.reportIssueLink = document.getElementById('report-issue-link'); + + // Actions + this.restoreDefaults = document.getElementById('restore-defaults'); + this.cancelButton = document.getElementById('cancel-button'); + this.saveButton = document.getElementById('save-button'); + } + + setupEventListeners() { + // Tab navigation + this.tabButtons.forEach((button) => { + button.addEventListener('click', () => this.switchTab(button.dataset.tab)); + }); + + // Preset buttons + this.presetButtons.forEach((button) => { + button.addEventListener('click', () => this.applyPreset(button.dataset.preset)); + }); + + // Form change detection + const formElements = [ + this.notifications, + this.sounds, + this.autoUpdate, + this.showInDock, + this.createBackup, + this.overwriteBackup, + this.overwriteInput, + this.stripHtml, + this.stripColors, + this.stripStyles, + this.stripUrls, + this.stripTimestamps, + this.stripNumbers, + this.stripPunctuation, + this.stripEmojis, + this.stripBrackets, + this.stripBidiControl, + this.outputEncoding, + this.outputBom, + this.lineEndings, + this.outputFormat, + this.overwriteExisting, + this.parallelProcessing, + this.chunkSize, + this.skipExisting, + this.failFast, + this.retryCount, + ]; + + formElements.forEach((element) => { + if (element) { + element.addEventListener('change', () => this.markChanged()); + } + }); + + // Action buttons + this.showConfigButton.addEventListener('click', () => this.showConfigInFinder()); + this.resetConfigButton.addEventListener('click', () => this.resetConfiguration()); + this.githubLink.addEventListener('click', () => this.openGitHub()); + this.reportIssueLink.addEventListener('click', () => this.openIssueTracker()); + this.restoreDefaults.addEventListener('click', () => this.restoreDefaults()); + this.cancelButton.addEventListener('click', () => this.cancel()); + this.saveButton.addEventListener('click', () => this.save()); + + // Keyboard shortcuts + document.addEventListener('keydown', (e) => this.handleKeyboard(e)); + } + + switchTab(tabName) { + // Update tab buttons + this.tabButtons.forEach((button) => { + button.classList.toggle('active', button.dataset.tab === tabName); + }); + + // Update tab panes + this.tabPanes.forEach((pane) => { + pane.classList.toggle('active', pane.id === `${tabName}-tab`); + }); + + console.log(`📑 Switched to ${tabName} tab`); + } + + async loadConfiguration() { + try { + console.log('📖 Loading configuration...'); + this.config = await window.subzilla.getConfig(); + this.originalConfig = JSON.parse(JSON.stringify(this.config)); + + this.populateForm(); + console.log('✅ Configuration loaded'); + } catch (error) { + console.error('❌ Error loading configuration:', error); + } + } + + async loadAppInfo() { + try { + const name = await window.subzilla.getAppName(); + const version = await window.subzilla.getAppVersion(); + + this.appName.textContent = name; + this.appVersion.textContent = `v${version}`; + } catch (error) { + console.error('❌ Error loading app info:', error); + } + } + + async loadConfigPath() { + try { + const configPath = await window.subzilla.getConfigPath(); + this.configPath.textContent = configPath; + } catch (error) { + console.error('❌ Error loading config path:', error); + this.configPath.textContent = 'Unknown'; + } + } + + populateForm() { + if (!this.config) return; + + // General tab + this.createBackup.checked = this.config.output?.createBackup ?? false; + this.overwriteBackup.checked = this.config.output?.overwriteBackup ?? false; + this.overwriteInput.checked = this.config.output?.overwriteInput ?? false; + + // Formatting tab - strip options + if (this.config.strip) { + this.stripHtml.checked = this.config.strip.html ?? false; + this.stripColors.checked = this.config.strip.colors ?? false; + this.stripStyles.checked = this.config.strip.styles ?? false; + this.stripUrls.checked = this.config.strip.urls ?? false; + this.stripTimestamps.checked = this.config.strip.timestamps ?? false; + this.stripNumbers.checked = this.config.strip.numbers ?? false; + this.stripPunctuation.checked = this.config.strip.punctuation ?? false; + this.stripEmojis.checked = this.config.strip.emojis ?? false; + this.stripBrackets.checked = this.config.strip.brackets ?? false; + this.stripBidiControl.checked = this.config.strip.bidiControl ?? true; + } + + // Output tab + this.outputEncoding.value = this.config.output?.encoding ?? 'utf8'; + this.outputBom.checked = this.config.output?.bom ?? true; + this.lineEndings.value = this.config.output?.lineEndings ?? 'auto'; + this.outputFormat.value = this.config.output?.format ?? 'srt'; + this.overwriteExisting.checked = this.config.output?.overwriteExisting ?? false; + + // Processing tab + this.parallelProcessing.checked = this.config.batch?.parallel ?? true; + this.chunkSize.value = this.config.batch?.chunkSize?.toString() ?? '5'; + this.skipExisting.checked = this.config.batch?.skipExisting ?? false; + this.failFast.checked = this.config.batch?.failFast ?? false; + this.retryCount.value = this.config.batch?.retryCount?.toString() ?? '0'; + + this.updatePresetButtons(); + } + + gatherFormData() { + const config = { + input: { + encoding: 'auto', + format: 'auto', + }, + output: { + encoding: this.outputEncoding.value, + createBackup: this.createBackup.checked, + overwriteBackup: this.overwriteBackup.checked, + bom: this.outputBom.checked, + lineEndings: this.lineEndings.value, + format: this.outputFormat.value, + overwriteInput: this.overwriteInput.checked, + overwriteExisting: this.overwriteExisting.checked, + }, + strip: { + html: this.stripHtml.checked, + colors: this.stripColors.checked, + styles: this.stripStyles.checked, + urls: this.stripUrls.checked, + timestamps: this.stripTimestamps.checked, + numbers: this.stripNumbers.checked, + punctuation: this.stripPunctuation.checked, + emojis: this.stripEmojis.checked, + brackets: this.stripBrackets.checked, + bidiControl: this.stripBidiControl.checked, + }, + batch: { + recursive: false, + parallel: this.parallelProcessing.checked, + skipExisting: this.skipExisting.checked, + preserveStructure: false, + chunkSize: parseInt(this.chunkSize.value, 10), + retryCount: parseInt(this.retryCount.value, 10), + retryDelay: 1000, + failFast: this.failFast.checked, + }, + }; + + return config; + } + + applyPreset(presetName) { + console.log(`🎛️ Applying preset: ${presetName}`); + + const presets = { + None: { + html: false, + colors: false, + styles: false, + urls: false, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: false, + }, + 'Basic Clean': { + html: true, + colors: true, + styles: true, + urls: false, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: true, + }, + 'Deep Clean': { + html: true, + colors: true, + styles: true, + urls: true, + timestamps: false, + numbers: false, + punctuation: true, + emojis: false, + brackets: true, + bidiControl: true, + }, + 'Arabic Optimized': { + html: true, + colors: true, + styles: true, + urls: true, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: true, + }, + 'Maximum Clean': { + html: true, + colors: true, + styles: true, + urls: true, + timestamps: true, + numbers: true, + punctuation: true, + emojis: true, + brackets: true, + bidiControl: true, + }, + }; + + const preset = presets[presetName]; + if (preset) { + // Apply preset to checkboxes + this.stripHtml.checked = preset.html; + this.stripColors.checked = preset.colors; + this.stripStyles.checked = preset.styles; + this.stripUrls.checked = preset.urls; + this.stripTimestamps.checked = preset.timestamps; + this.stripNumbers.checked = preset.numbers; + this.stripPunctuation.checked = preset.punctuation; + this.stripEmojis.checked = preset.emojis; + this.stripBrackets.checked = preset.brackets; + this.stripBidiControl.checked = preset.bidiControl; + + this.updatePresetButtons(); + this.markChanged(); + } + } + + updatePresetButtons() { + const currentStrip = { + html: this.stripHtml.checked, + colors: this.stripColors.checked, + styles: this.stripStyles.checked, + urls: this.stripUrls.checked, + timestamps: this.stripTimestamps.checked, + numbers: this.stripNumbers.checked, + punctuation: this.stripPunctuation.checked, + emojis: this.stripEmojis.checked, + brackets: this.stripBrackets.checked, + bidiControl: this.stripBidiControl.checked, + }; + + // Check which preset matches current settings + this.presetButtons.forEach((button) => { + button.classList.remove('active'); + }); + + // Find matching preset + const presets = { + None: { + html: false, + colors: false, + styles: false, + urls: false, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: false, + }, + 'Basic Clean': { + html: true, + colors: true, + styles: true, + urls: false, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: true, + }, + 'Deep Clean': { + html: true, + colors: true, + styles: true, + urls: true, + timestamps: false, + numbers: false, + punctuation: true, + emojis: false, + brackets: true, + bidiControl: true, + }, + 'Arabic Optimized': { + html: true, + colors: true, + styles: true, + urls: true, + timestamps: false, + numbers: false, + punctuation: false, + emojis: false, + brackets: false, + bidiControl: true, + }, + 'Maximum Clean': { + html: true, + colors: true, + styles: true, + urls: true, + timestamps: true, + numbers: true, + punctuation: true, + emojis: true, + brackets: true, + bidiControl: true, + }, + }; + + for (const [presetName, preset] of Object.entries(presets)) { + if (this.presetsMatch(currentStrip, preset)) { + const button = document.querySelector(`[data-preset="${presetName}"]`); + if (button) { + button.classList.add('active'); + } + break; + } + } + } + + presetsMatch(current, preset) { + return Object.keys(preset).every((key) => current[key] === preset[key]); + } + + markChanged() { + this.hasChanges = true; + this.saveButton.textContent = 'Save Changes'; + this.saveButton.classList.add('primary-button'); + } + + async showConfigInFinder() { + try { + const configPath = await window.subzilla.getConfigPath(); + await window.subzilla.showInFinder(configPath); + } catch (error) { + console.error('❌ Error showing config in Finder:', error); + } + } + + async resetConfiguration() { + const confirmed = confirm('Are you sure you want to reset all preferences to defaults? This cannot be undone.'); + if (confirmed) { + try { + console.log('🔄 Resetting configuration...'); + await window.subzilla.resetConfig(); + await this.loadConfiguration(); + this.hasChanges = false; + this.saveButton.textContent = 'Save'; + console.log('✅ Configuration reset successfully'); + } catch (error) { + console.error('❌ Error resetting configuration:', error); + alert('Failed to reset configuration'); + } + } + } + + openGitHub() { + // This will be handled by the main process + console.log('🔗 Opening GitHub repository...'); + } + + openIssueTracker() { + // This will be handled by the main process + console.log('🔗 Opening issue tracker...'); + } + + async restoreDefaults() { + const confirmed = confirm('Restore all settings to defaults?'); + if (confirmed) { + await this.resetConfiguration(); + } + } + + async save() { + try { + console.log('💾 Saving preferences...'); + + const config = this.gatherFormData(); + const result = await window.subzilla.saveConfig(config); + + if (result.success) { + console.log('✅ Preferences saved successfully'); + this.hasChanges = false; + this.saveButton.textContent = 'Save'; + this.originalConfig = JSON.parse(JSON.stringify(config)); + + // Show brief success feedback + this.saveButton.textContent = 'Saved!'; + setTimeout(() => { + if (!this.hasChanges) { + this.saveButton.textContent = 'Save'; + } + }, 1000); + } else { + console.error('❌ Failed to save preferences:', result.error); + alert(`Failed to save preferences: ${result.error}`); + } + } catch (error) { + console.error('❌ Error saving preferences:', error); + alert('Failed to save preferences'); + } + } + + cancel() { + if (this.hasChanges) { + const confirmed = confirm('You have unsaved changes. Are you sure you want to cancel?'); + if (!confirmed) return; + } + + console.log('❌ Cancelling preferences...'); + window.subzilla.closePreferences(); + } + + handleKeyboard(event) { + if (event.metaKey || event.ctrlKey) { + switch (event.key) { + case 's': + event.preventDefault(); + this.save(); + break; + case 'w': + event.preventDefault(); + this.cancel(); + break; + } + } + + if (event.key === 'Escape') { + this.cancel(); + } + } + + // Utility methods + formatBytes(bytes) { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; + } +} + +// Initialize preferences when DOM is ready +document.addEventListener('DOMContentLoaded', () => { + console.log('🚀 DOM loaded, starting Preferences App...'); + + window.preferencesApp = new PreferencesApp(); + + console.log('✅ Preferences App initialized successfully'); +}); diff --git a/packages/mac/src/renderer/preferences.html b/packages/mac/src/renderer/preferences.html new file mode 100644 index 0000000..63ec7cb --- /dev/null +++ b/packages/mac/src/renderer/preferences.html @@ -0,0 +1,301 @@ + + + + + + + Subzilla Preferences + + + +
+ +
+ + + + + +
+ + +
+ +
+
+

Application

+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+

File Handling

+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+

Quick Presets

+
+ + + + + +
+
+ +
+

Strip Options

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
+
+

Encoding

+
+ + +
+
+ +
+
+ +
+

Line Endings

+
+ + +
+
+ +
+

File Format

+
+ + +
+
+ +
+

File Overwriting

+
+ +
+
+
+ + +
+
+

Performance

+
+ +
+
+ + +
+
+ +
+

Error Handling

+
+ +
+
+ +
+
+ + +
+
+
+ + +
+
+

Application Data

+
+ +
Loading...
+
+
+ + +
+
+ +
+

About

+
+
+ Subzilla + v1.0.0 +
+

A powerful subtitle converter with UTF-8 and Arabic language support.

+ +
+
+
+
+ + +
+ +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/packages/mac/src/renderer/styles/main.css b/packages/mac/src/renderer/styles/main.css new file mode 100644 index 0000000..654314e --- /dev/null +++ b/packages/mac/src/renderer/styles/main.css @@ -0,0 +1,482 @@ +/* Reset and base styles */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif; + font-size: 13px; + line-height: 1.5; + color: #333; + background: #f5f5f5; + overflow: hidden; + user-select: none; + -webkit-user-select: none; +} + +#app { + height: 100vh; + display: flex; + flex-direction: column; +} + +/* State containers */ +.state-container { + flex: 1; + display: flex; + flex-direction: column; + transition: opacity 0.3s ease; +} + +.state-container.hidden { + display: none; +} + +/* Empty state */ +#empty-state { + justify-content: center; + align-items: center; + text-align: center; + padding: 40px 20px; +} + +.empty-content { + max-width: 300px; +} + +.logo { + font-size: 64px; + margin-bottom: 20px; + animation: pulse 2s ease-in-out infinite; +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.7; } +} + +h2 { + font-size: 18px; + font-weight: 500; + color: #333; + margin-bottom: 8px; +} + +p { + color: #666; + margin-bottom: 20px; +} + +.link-button { + background: none; + border: none; + color: #007AFF; + cursor: pointer; + text-decoration: underline; + font-size: inherit; + padding: 0; +} + +.link-button:hover { + color: #0056CC; +} + +.supported-formats { + padding: 12px 16px; + background: #e8e8e8; + border-radius: 8px; + font-size: 11px; + color: #666; +} + +/* Processing state */ +#processing-state { + padding: 0; +} + +.file-list-container { + flex: 1; + background: white; + border-bottom: 1px solid #ddd; +} + +.file-list-header { + display: grid; + grid-template-columns: 2fr 1fr 1fr 1fr; + gap: 16px; + padding: 12px 16px; + background: #f8f8f8; + border-bottom: 1px solid #e0e0e0; + font-weight: 600; + font-size: 11px; + color: #666; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.file-list { + max-height: calc(100vh - 120px); + overflow-y: auto; +} + +.file-item { + display: grid; + grid-template-columns: 2fr 1fr 1fr 1fr; + gap: 16px; + padding: 12px 16px; + border-bottom: 1px solid #f0f0f0; + transition: background-color 0.2s ease; +} + +.file-item:hover { + background: #f8f8f8; +} + +.file-item.processing { + background: #fff8e1; +} + +.file-item.completed { + background: #f1f8e9; +} + +.file-item.error { + background: #ffebee; +} + +.file-name { + font-weight: 500; + color: #333; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.file-status { + display: flex; + align-items: center; + gap: 4px; + font-size: 12px; +} + +.status-icon { + font-size: 14px; +} + +.encoding-info { + font-size: 11px; + color: #666; +} + +/* Progress container */ +.progress-container { + padding: 16px; + background: white; + border-top: 1px solid #ddd; +} + +.progress-bar-container { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 16px; +} + +.progress-bar { + flex: 1; + height: 8px; + background: #e0e0e0; + border-radius: 4px; + overflow: hidden; +} + +.progress-fill { + height: 100%; + background: linear-gradient(90deg, #007AFF, #34C759); + border-radius: 4px; + transition: width 0.3s ease; + width: 0%; +} + +.progress-text { + font-size: 11px; + color: #666; + white-space: nowrap; + min-width: 80px; + text-align: right; +} + +.actions { + display: flex; + gap: 8px; + justify-content: flex-end; +} + +/* Buttons */ +.primary-button { + background: #007AFF; + color: white; + border: none; + border-radius: 6px; + padding: 8px 16px; + font-size: 12px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.primary-button:hover { + background: #0056CC; +} + +.primary-button:active { + background: #004999; +} + +.secondary-button { + background: #f0f0f0; + color: #333; + border: none; + border-radius: 6px; + padding: 8px 16px; + font-size: 12px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.secondary-button:hover { + background: #e0e0e0; +} + +.icon-button { + background: none; + border: none; + font-size: 14px; + padding: 4px; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.icon-button:hover { + background: #f0f0f0; +} + +/* Drop overlay */ +.drop-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 122, 255, 0.1); + border: 3px dashed #007AFF; + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; + backdrop-filter: blur(5px); +} + +.drop-overlay.hidden { + display: none; +} + +.drop-content { + text-align: center; + color: #007AFF; +} + +.drop-icon { + font-size: 48px; + margin-bottom: 16px; +} + +.drop-content h3 { + font-size: 18px; + font-weight: 600; + margin-bottom: 8px; +} + +.drop-content p { + font-size: 14px; + opacity: 0.8; +} + +/* Shortcuts overlay */ +.shortcuts-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 2000; +} + +.shortcuts-overlay.hidden { + display: none; +} + +.shortcuts-content { + background: white; + border-radius: 12px; + padding: 24px; + max-width: 300px; + position: relative; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); +} + +.shortcuts-content h3 { + font-size: 16px; + font-weight: 600; + margin-bottom: 16px; + text-align: center; +} + +.shortcuts-list { + display: flex; + flex-direction: column; + gap: 8px; +} + +.shortcut { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 0; +} + +.key { + font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace; + background: #f0f0f0; + padding: 4px 8px; + border-radius: 4px; + font-size: 11px; + font-weight: 500; +} + +.action { + font-size: 12px; + color: #666; +} + +.close-button { + position: absolute; + top: 8px; + right: 12px; + background: none; + border: none; + font-size: 20px; + color: #999; + cursor: pointer; + width: 24px; + height: 24px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} + +.close-button:hover { + background: #f0f0f0; + color: #333; +} + +/* Status bar */ +.status-bar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 16px; + background: #f8f8f8; + border-top: 1px solid #e0e0e0; + font-size: 11px; + color: #666; + height: 32px; +} + +.status-bar.hidden { + display: none; +} + +.status-actions { + display: flex; + gap: 4px; +} + +/* Drag and drop styling */ +body.drag-over { + background: #e3f2fd; +} + +body.drag-over #drop-overlay { + display: flex; +} + +/* Animations */ +.fade-in { + animation: fadeIn 0.3s ease-in; +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +.slide-up { + animation: slideUp 0.3s ease-out; +} + +@keyframes slideUp { + from { transform: translateY(20px); opacity: 0; } + to { transform: translateY(0); opacity: 1; } +} + +/* Scrollbar styling for webkit */ +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: #f1f1f1; +} + +::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: #a8a8a8; +} + +/* Status icons */ +.status-pending { color: #666; } +.status-processing { color: #FF9500; } +.status-completed { color: #34C759; } +.status-error { color: #FF3B30; } + +/* Responsive adjustments */ +@media (max-width: 500px) { + .file-list-header, + .file-item { + grid-template-columns: 1.5fr 80px 60px 60px; + gap: 8px; + padding: 8px 12px; + } + + .file-list-header { + font-size: 10px; + } + + .file-item { + font-size: 11px; + } +} \ No newline at end of file diff --git a/packages/mac/src/renderer/styles/preferences.css b/packages/mac/src/renderer/styles/preferences.css new file mode 100644 index 0000000..ec1b921 --- /dev/null +++ b/packages/mac/src/renderer/styles/preferences.css @@ -0,0 +1,367 @@ +/* Preferences window styles */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif; + font-size: 13px; + line-height: 1.5; + color: #333; + background: #f5f5f5; + overflow: hidden; + user-select: none; + -webkit-user-select: none; +} + +#preferences-app { + height: 100vh; + display: flex; + flex-direction: column; +} + +/* Tab bar */ +.tab-bar { + display: flex; + background: #e8e8e8; + border-bottom: 1px solid #d0d0d0; + padding: 0; +} + +.tab-button { + flex: 1; + background: none; + border: none; + padding: 12px 16px; + font-size: 12px; + font-weight: 500; + color: #666; + cursor: pointer; + transition: all 0.2s ease; + border-bottom: 2px solid transparent; +} + +.tab-button:hover { + background: #ddd; + color: #333; +} + +.tab-button.active { + background: #f5f5f5; + color: #333; + border-bottom-color: #007AFF; +} + +/* Tab content */ +.tab-content { + flex: 1; + overflow-y: auto; + padding: 20px; +} + +.tab-pane { + display: none; +} + +.tab-pane.active { + display: block; +} + +/* Sections */ +.section { + background: white; + border-radius: 8px; + padding: 20px; + margin-bottom: 16px; + border: 1px solid #e0e0e0; +} + +.section h3 { + font-size: 14px; + font-weight: 600; + color: #333; + margin-bottom: 16px; + padding-bottom: 8px; + border-bottom: 1px solid #f0f0f0; +} + +/* Form groups */ +.form-group { + margin-bottom: 16px; +} + +.form-group:last-child { + margin-bottom: 0; +} + +/* Labels */ +label { + display: block; + font-size: 12px; + font-weight: 500; + color: #333; + margin-bottom: 6px; +} + +/* Checkbox labels */ +.checkbox-label { + display: flex; + align-items: center; + gap: 8px; + cursor: pointer; + padding: 4px 0; + margin-bottom: 0; +} + +.checkbox-label input[type="checkbox"] { + margin: 0; + transform: scale(1.1); +} + +.checkbox-label span { + font-size: 13px; + color: #333; +} + +/* Select inputs */ +select { + width: 100%; + max-width: 200px; + padding: 6px 8px; + border: 1px solid #d0d0d0; + border-radius: 4px; + background: white; + font-size: 12px; + color: #333; +} + +select:focus { + outline: none; + border-color: #007AFF; + box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2); +} + +/* Preset buttons */ +.preset-buttons { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 20px; +} + +.preset-button { + background: #f0f0f0; + border: 1px solid #d0d0d0; + border-radius: 6px; + padding: 8px 12px; + font-size: 11px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; +} + +.preset-button:hover { + background: #e0e0e0; + border-color: #007AFF; +} + +.preset-button.active { + background: #007AFF; + color: white; + border-color: #007AFF; +} + +/* Strip options grid */ +.strip-options { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px 20px; +} + +/* File path display */ +.file-path { + background: #f8f8f8; + border: 1px solid #e0e0e0; + border-radius: 4px; + padding: 8px 12px; + font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace; + font-size: 11px; + color: #666; + word-break: break-all; + max-height: 60px; + overflow-y: auto; +} + +/* About section */ +.about-info { + text-align: center; +} + +.app-info { + margin-bottom: 12px; +} + +.app-info strong { + font-size: 16px; + font-weight: 600; + color: #333; + margin-right: 8px; +} + +.app-info span { + font-size: 12px; + color: #666; + background: #f0f0f0; + padding: 2px 6px; + border-radius: 3px; +} + +.about-info p { + font-size: 12px; + color: #666; + margin-bottom: 16px; +} + +.links { + display: flex; + gap: 12px; + justify-content: center; +} + +/* Buttons */ +.primary-button { + background: #007AFF; + color: white; + border: none; + border-radius: 6px; + padding: 8px 16px; + font-size: 12px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.primary-button:hover { + background: #0056CC; +} + +.primary-button:active { + background: #004999; +} + +.secondary-button { + background: #f0f0f0; + color: #333; + border: 1px solid #d0d0d0; + border-radius: 6px; + padding: 8px 16px; + font-size: 12px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; +} + +.secondary-button:hover { + background: #e0e0e0; + border-color: #c0c0c0; +} + +.danger-button { + background: #FF3B30; + color: white; + border: none; + border-radius: 6px; + padding: 8px 16px; + font-size: 12px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.danger-button:hover { + background: #D70015; +} + +.link-button { + background: none; + border: none; + color: #007AFF; + cursor: pointer; + text-decoration: underline; + font-size: inherit; + padding: 0; +} + +.link-button:hover { + color: #0056CC; +} + +/* Actions bar */ +.actions-bar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px 20px; + background: #f8f8f8; + border-top: 1px solid #e0e0e0; +} + +.actions-right { + display: flex; + gap: 8px; +} + +/* Scrollbar styling */ +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: #f1f1f1; +} + +::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: #a8a8a8; +} + +/* Animations */ +.fade-in { + animation: fadeIn 0.3s ease-in; +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +/* Responsive adjustments */ +@media (max-width: 600px) { + .strip-options { + grid-template-columns: 1fr; + gap: 8px; + } + + .tab-content { + padding: 16px; + } + + .section { + padding: 16px; + } + + .preset-buttons { + flex-direction: column; + align-items: stretch; + } + + .preset-button { + text-align: center; + } +} \ No newline at end of file diff --git a/packages/mac/tsconfig.json b/packages/mac/tsconfig.json new file mode 100644 index 0000000..96f8550 --- /dev/null +++ b/packages/mac/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2020", + "module": "commonjs", + "lib": ["ES2020", "DOM"], + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "dist-electron"], + "references": [{ "path": "../core" }, { "path": "../types" }] +} diff --git a/packages/types/README.md b/packages/types/README.md index b7f83bf..d43c190 100644 --- a/packages/types/README.md +++ b/packages/types/README.md @@ -245,14 +245,7 @@ export const configSchema = z.object({ ### Importing Types ```typescript -import { - IConfig, - IConvertOptions, - IBatchOptions, - ICommandDefinition, - TEncoding, - configSchema, -} from '@subzilla/types'; +import { IConfig, IConvertOptions, IBatchOptions, ICommandDefinition, TEncoding, configSchema } from '@subzilla/types'; ``` ### Using Validation diff --git a/packages/types/src/validation.ts b/packages/types/src/validation.ts index 2066217..cf6285b 100644 --- a/packages/types/src/validation.ts +++ b/packages/types/src/validation.ts @@ -16,9 +16,7 @@ export const stripOptionsSchema = z.object({ export const configSchema = z.object({ input: z .object({ - encoding: z - .enum(['auto', 'utf8', 'utf16le', 'utf16be', 'ascii', 'windows1256']) - .default('auto'), + encoding: z.enum(['auto', 'utf8', 'utf16le', 'utf16be', 'ascii', 'windows1256']).default('auto'), format: z.enum(['auto', 'srt', 'sub', 'ass', 'ssa', 'txt']).default('auto'), }) .optional(), diff --git a/tsconfig.json b/tsconfig.json index 5af817b..07269e3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,11 +11,7 @@ "declaration": true, "composite": true }, - "references": [ - { "path": "./packages/types" }, - { "path": "./packages/core" }, - { "path": "./packages/cli" } - ], + "references": [{ "path": "./packages/types" }, { "path": "./packages/core" }, { "path": "./packages/cli" }], "files": [], "include": [] } diff --git a/yarn.lock b/yarn.lock index 575a603..88a6f07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,13 @@ __metadata: version: 8 cacheKey: 10c0 +"7zip-bin@npm:~5.2.0": + version: 5.2.0 + resolution: "7zip-bin@npm:5.2.0" + checksum: 10c0/7f6c69b4cb10c4060fb8fda258ae2ab88d30516b5a52941efa0e2cbd9ce362ab7d8d568549cd85e9f125c1c68f95c7bb076cc314c2f3c0cb306d3b638080c2ce + languageName: node + linkType: hard + "@ampproject/remapping@npm:^2.2.0": version: 2.3.0 resolution: "@ampproject/remapping@npm:2.3.0" @@ -391,6 +398,91 @@ __metadata: languageName: node linkType: hard +"@develar/schema-utils@npm:~2.6.5": + version: 2.6.5 + resolution: "@develar/schema-utils@npm:2.6.5" + dependencies: + ajv: "npm:^6.12.0" + ajv-keywords: "npm:^3.4.1" + checksum: 10c0/7c6075ce6742dd5c89b3cebf81351ec1d73dafc7c3409748860e4f8262fb26ffe6d998c5baab4eca579cd436e7c6c12c615fe89819c19484a22d25b3e6825cb5 + languageName: node + linkType: hard + +"@electron/asar@npm:^3.2.1": + version: 3.4.1 + resolution: "@electron/asar@npm:3.4.1" + dependencies: + commander: "npm:^5.0.0" + glob: "npm:^7.1.6" + minimatch: "npm:^3.0.4" + bin: + asar: bin/asar.js + checksum: 10c0/9df7983125faaa29c266e4beec6ceb205e139ede0e8fb81dde84c73ac8114388a99aad21379412a972163d8879ca959621f4e4896214bf8d296ba217e7cf8170 + languageName: node + linkType: hard + +"@electron/get@npm:^2.0.0": + version: 2.0.3 + resolution: "@electron/get@npm:2.0.3" + dependencies: + debug: "npm:^4.1.1" + env-paths: "npm:^2.2.0" + fs-extra: "npm:^8.1.0" + global-agent: "npm:^3.0.0" + got: "npm:^11.8.5" + progress: "npm:^2.0.3" + semver: "npm:^6.2.0" + sumchecker: "npm:^3.0.1" + dependenciesMeta: + global-agent: + optional: true + checksum: 10c0/148957d531bac50c29541515f2483c3e5c9c6ba9f0269a5d536540d2b8d849188a89588f18901f3a84c2b4fd376d1e0c5ea2159eb2d17bda68558f57df19015e + languageName: node + linkType: hard + +"@electron/notarize@npm:2.2.1": + version: 2.2.1 + resolution: "@electron/notarize@npm:2.2.1" + dependencies: + debug: "npm:^4.1.1" + fs-extra: "npm:^9.0.1" + promise-retry: "npm:^2.0.1" + checksum: 10c0/d3fbbaaf26e809d4484f87826f02ba9108eba222a495ff533d9728a58a0cca6e267764baefc5616952318a6674eb6d3b7d07b1136ca0254da1c51012a0e6e6ae + languageName: node + linkType: hard + +"@electron/osx-sign@npm:1.0.5": + version: 1.0.5 + resolution: "@electron/osx-sign@npm:1.0.5" + dependencies: + compare-version: "npm:^0.1.2" + debug: "npm:^4.3.4" + fs-extra: "npm:^10.0.0" + isbinaryfile: "npm:^4.0.8" + minimist: "npm:^1.2.6" + plist: "npm:^3.0.5" + bin: + electron-osx-flat: bin/electron-osx-flat.js + electron-osx-sign: bin/electron-osx-sign.js + checksum: 10c0/9b1099858cfe32c2d9329c16e832c003e246cf14356e541342e91876dcbb7a9bab27c89d1f521c3192d1a1d0fd06a186fa101b45341608c434fe850a3053bfb0 + languageName: node + linkType: hard + +"@electron/universal@npm:1.5.1": + version: 1.5.1 + resolution: "@electron/universal@npm:1.5.1" + dependencies: + "@electron/asar": "npm:^3.2.1" + "@malept/cross-spawn-promise": "npm:^1.1.0" + debug: "npm:^4.3.1" + dir-compare: "npm:^3.0.0" + fs-extra: "npm:^9.0.1" + minimatch: "npm:^3.0.4" + plist: "npm:^3.0.4" + checksum: 10c0/2ba4cfd6c7ba4a475c73ae9b168481b1c106e2f8d618a35185d72cf6bd0b9f6b8051e153fab2b63c2514f4fc9da879cca606e63e253d886b29e0e364a87bf840 + languageName: node + linkType: hard + "@emnapi/core@npm:^1.4.3": version: 1.5.0 resolution: "@emnapi/core@npm:1.5.0" @@ -914,6 +1006,27 @@ __metadata: languageName: node linkType: hard +"@malept/cross-spawn-promise@npm:^1.1.0": + version: 1.1.1 + resolution: "@malept/cross-spawn-promise@npm:1.1.1" + dependencies: + cross-spawn: "npm:^7.0.1" + checksum: 10c0/74c427a152ffff0f19b74af6479d05bef1e996d5e081cfc3b8c47477b9240bd1c42a930884cbcd0c89ee3835201a3bd88d0b0bfd754c0cbb56fc84a28996a8e7 + languageName: node + linkType: hard + +"@malept/flatpak-bundler@npm:^0.4.0": + version: 0.4.0 + resolution: "@malept/flatpak-bundler@npm:0.4.0" + dependencies: + debug: "npm:^4.1.1" + fs-extra: "npm:^9.0.0" + lodash: "npm:^4.17.15" + tmp-promise: "npm:^3.0.2" + checksum: 10c0/b3c87f6482b1956411af1118c771afb39cd9a0568fbb5e86015547ff6d68d2e73a7f0d74b75a57f0a156391c347c8d0adc1037e75172b92da72b96e0a05a2f4f + languageName: node + linkType: hard + "@napi-rs/wasm-runtime@npm:^0.2.11": version: 0.2.12 resolution: "@napi-rs/wasm-runtime@npm:0.2.12" @@ -1002,6 +1115,13 @@ __metadata: languageName: node linkType: hard +"@sindresorhus/is@npm:^4.0.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: 10c0/33b6fb1d0834ec8dd7689ddc0e2781c2bfd8b9c4e4bacbcb14111e0ae00621f2c264b8a7d36541799d74888b5dccdf422a891a5cb5a709ace26325eedc81e22e + languageName: node + linkType: hard + "@sinonjs/commons@npm:^3.0.1": version: 3.0.1 resolution: "@sinonjs/commons@npm:3.0.1" @@ -1056,6 +1176,22 @@ __metadata: languageName: unknown linkType: soft +"@subzilla/mac@workspace:packages/mac": + version: 0.0.0-use.local + resolution: "@subzilla/mac@workspace:packages/mac" + dependencies: + "@subzilla/core": "workspace:*" + "@subzilla/types": "workspace:*" + "@types/node": "npm:^24.3.0" + electron: "npm:^31.0.0" + electron-builder: "npm:^24.0.0" + electron-store: "npm:^8.1.0" + electron-updater: "npm:^6.1.0" + module-alias: "npm:^2.2.3" + typescript: "npm:^5.9.2" + languageName: unknown + linkType: soft + "@subzilla/types@workspace:*, @subzilla/types@workspace:packages/types": version: 0.0.0-use.local resolution: "@subzilla/types@workspace:packages/types" @@ -1066,6 +1202,22 @@ __metadata: languageName: unknown linkType: soft +"@szmarczak/http-timer@npm:^4.0.5": + version: 4.0.6 + resolution: "@szmarczak/http-timer@npm:4.0.6" + dependencies: + defer-to-connect: "npm:^2.0.0" + checksum: 10c0/73946918c025339db68b09abd91fa3001e87fc749c619d2e9c2003a663039d4c3cb89836c98a96598b3d47dec2481284ba85355392644911f5ecd2336536697f + languageName: node + linkType: hard + +"@tootallnate/once@npm:2": + version: 2.0.0 + resolution: "@tootallnate/once@npm:2.0.0" + checksum: 10c0/073bfa548026b1ebaf1659eb8961e526be22fa77139b10d60e712f46d2f0f05f4e6c8bec62a087d41088ee9e29faa7f54838568e475ab2f776171003c3920858 + languageName: node + linkType: hard + "@tybys/wasm-util@npm:^0.10.0": version: 0.10.0 resolution: "@tybys/wasm-util@npm:0.10.0" @@ -1116,6 +1268,18 @@ __metadata: languageName: node linkType: hard +"@types/cacheable-request@npm:^6.0.1": + version: 6.0.3 + resolution: "@types/cacheable-request@npm:6.0.3" + dependencies: + "@types/http-cache-semantics": "npm:*" + "@types/keyv": "npm:^3.1.4" + "@types/node": "npm:*" + "@types/responselike": "npm:^1.0.0" + checksum: 10c0/10816a88e4e5b144d43c1d15a81003f86d649776c7f410c9b5e6579d0ad9d4ca71c541962fb403077388b446e41af7ae38d313e46692144985f006ac5e11fa03 + languageName: node + linkType: hard + "@types/chardet@npm:^1.0.0": version: 1.0.0 resolution: "@types/chardet@npm:1.0.0" @@ -1143,6 +1307,15 @@ __metadata: languageName: node linkType: hard +"@types/debug@npm:^4.1.6": + version: 4.1.12 + resolution: "@types/debug@npm:4.1.12" + dependencies: + "@types/ms": "npm:*" + checksum: 10c0/5dcd465edbb5a7f226e9a5efd1f399c6172407ef5840686b73e3608ce135eeca54ae8037dcd9f16bdb2768ac74925b820a8b9ecc588a58ca09eca6acabe33e2f + languageName: node + linkType: hard + "@types/estree@npm:^1.0.6": version: 1.0.8 resolution: "@types/estree@npm:1.0.8" @@ -1150,6 +1323,15 @@ __metadata: languageName: node linkType: hard +"@types/fs-extra@npm:9.0.13, @types/fs-extra@npm:^9.0.11": + version: 9.0.13 + resolution: "@types/fs-extra@npm:9.0.13" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/576d4e9d382393316ed815c593f7f5c157408ec5e184521d077fcb15d514b5a985245f153ef52142b9b976cb9bd8f801850d51238153ebd0dc9e96b7a7548588 + languageName: node + linkType: hard + "@types/glob@npm:^9.0.0": version: 9.0.0 resolution: "@types/glob@npm:9.0.0" @@ -1159,6 +1341,13 @@ __metadata: languageName: node linkType: hard +"@types/http-cache-semantics@npm:*": + version: 4.0.4 + resolution: "@types/http-cache-semantics@npm:4.0.4" + checksum: 10c0/51b72568b4b2863e0fe8d6ce8aad72a784b7510d72dc866215642da51d84945a9459fa89f49ec48f1e9a1752e6a78e85a4cda0ded06b1c73e727610c925f9ce6 + languageName: node + linkType: hard + "@types/iconv-lite@npm:^0.0.1": version: 0.0.1 resolution: "@types/iconv-lite@npm:0.0.1" @@ -1217,6 +1406,15 @@ __metadata: languageName: node linkType: hard +"@types/keyv@npm:^3.1.4": + version: 3.1.4 + resolution: "@types/keyv@npm:3.1.4" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/ff8f54fc49621210291f815fe5b15d809fd7d032941b3180743440bd507ecdf08b9e844625fa346af568c84bf34114eb378dcdc3e921a08ba1e2a08d7e3c809c + languageName: node + linkType: hard + "@types/module-alias@npm:^2.0.4": version: 2.0.4 resolution: "@types/module-alias@npm:2.0.4" @@ -1224,6 +1422,13 @@ __metadata: languageName: node linkType: hard +"@types/ms@npm:*": + version: 2.1.0 + resolution: "@types/ms@npm:2.1.0" + checksum: 10c0/5ce692ffe1549e1b827d99ef8ff71187457e0eb44adbae38fdf7b9a74bae8d20642ee963c14516db1d35fa2652e65f47680fdf679dcbde52bbfadd021f497225 + languageName: node + linkType: hard + "@types/node@npm:*, @types/node@npm:^24.3.0": version: 24.3.0 resolution: "@types/node@npm:24.3.0" @@ -1233,6 +1438,34 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^20.9.0": + version: 20.19.13 + resolution: "@types/node@npm:20.19.13" + dependencies: + undici-types: "npm:~6.21.0" + checksum: 10c0/25fba13d50c4f18ac56a50d4491502e7d095f09e44c17c0c6887aa5e4e6122e961e92fc3b682ed8c053ab87a05ce10f501345d23d96fdfba8002ecce6c8ced51 + languageName: node + linkType: hard + +"@types/plist@npm:^3.0.1": + version: 3.0.5 + resolution: "@types/plist@npm:3.0.5" + dependencies: + "@types/node": "npm:*" + xmlbuilder: "npm:>=11.0.1" + checksum: 10c0/2a929f4482e3bea8c3288a46ae589a2ae2d01df5b7841ead7032d7baa79d79af6c875a5798c90705eea9306c2fb1544d7ed12ab3c905c5626d5dd5dc9f464b94 + languageName: node + linkType: hard + +"@types/responselike@npm:^1.0.0": + version: 1.0.3 + resolution: "@types/responselike@npm:1.0.3" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/a58ba341cb9e7d74f71810a88862da7b2a6fa42e2a1fc0ce40498f6ea1d44382f0640117057da779f74c47039f7166bf48fad02dc876f94e005c7afa50f5e129 + languageName: node + linkType: hard + "@types/stack-utils@npm:^2.0.3": version: 2.0.3 resolution: "@types/stack-utils@npm:2.0.3" @@ -1240,6 +1473,13 @@ __metadata: languageName: node linkType: hard +"@types/verror@npm:^1.10.3": + version: 1.10.11 + resolution: "@types/verror@npm:1.10.11" + checksum: 10c0/6d815cb2b76501f976cf9fa0feaf572e83b2ec3043eff92507c9976e52b7844453bd47c84f1298bf583f8e6568f39063a2541f80656f4af8e179072a711f9ab5 + languageName: node + linkType: hard + "@types/yargs-parser@npm:*": version: 21.0.3 resolution: "@types/yargs-parser@npm:21.0.3" @@ -1256,6 +1496,15 @@ __metadata: languageName: node linkType: hard +"@types/yauzl@npm:^2.9.1": + version: 2.10.3 + resolution: "@types/yauzl@npm:2.10.3" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/f1b7c1b99fef9f2fe7f1985ef7426d0cebe48cd031f1780fcdc7451eec7e31ac97028f16f50121a59bcf53086a1fc8c856fd5b7d3e00970e43d92ae27d6b43dc + languageName: node + linkType: hard + "@typescript-eslint/eslint-plugin@npm:^8.42.0": version: 8.42.0 resolution: "@typescript-eslint/eslint-plugin@npm:8.42.0" @@ -1535,6 +1784,13 @@ __metadata: languageName: node linkType: hard +"@xmldom/xmldom@npm:^0.8.8": + version: 0.8.11 + resolution: "@xmldom/xmldom@npm:0.8.11" + checksum: 10c0/e768623de72c95d3dae6b5da8e33dda0d81665047811b5498d23a328d45b13feb5536fe921d0308b96a4a8dd8addf80b1f6ef466508051c0b581e63e0dc74ed5 + languageName: node + linkType: hard + "abbrev@npm:^3.0.0": version: 3.0.1 resolution: "abbrev@npm:3.0.1" @@ -1560,6 +1816,15 @@ __metadata: languageName: node linkType: hard +"agent-base@npm:6": + version: 6.0.2 + resolution: "agent-base@npm:6.0.2" + dependencies: + debug: "npm:4" + checksum: 10c0/dc4f757e40b5f3e3d674bc9beb4f1048f4ee83af189bae39be99f57bf1f48dde166a8b0a5342a84b5944ee8e6ed1e5a9d801858f4ad44764e84957122fe46261 + languageName: node + linkType: hard + "agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": version: 7.1.4 resolution: "agent-base@npm:7.1.4" @@ -1567,7 +1832,30 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.12.4": +"ajv-formats@npm:^2.1.1": + version: 2.1.1 + resolution: "ajv-formats@npm:2.1.1" + dependencies: + ajv: "npm:^8.0.0" + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 10c0/e43ba22e91b6a48d96224b83d260d3a3a561b42d391f8d3c6d2c1559f9aa5b253bfb306bc94bbeca1d967c014e15a6efe9a207309e95b3eaae07fcbcdc2af662 + languageName: node + linkType: hard + +"ajv-keywords@npm:^3.4.1": + version: 3.5.2 + resolution: "ajv-keywords@npm:3.5.2" + peerDependencies: + ajv: ^6.9.1 + checksum: 10c0/0c57a47cbd656e8cdfd99d7c2264de5868918ffa207c8d7a72a7f63379d4333254b2ba03d69e3c035e996a3fd3eb6d5725d7a1597cca10694296e32510546360 + languageName: node + linkType: hard + +"ajv@npm:^6.10.0, ajv@npm:^6.12.0, ajv@npm:^6.12.4": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -1579,6 +1867,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^8.0.0, ajv@npm:^8.6.3": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^3.0.1" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35 + languageName: node + linkType: hard + "ansi-escapes@npm:^4.3.2": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" @@ -1635,6 +1935,51 @@ __metadata: languageName: node linkType: hard +"app-builder-bin@npm:4.0.0": + version: 4.0.0 + resolution: "app-builder-bin@npm:4.0.0" + checksum: 10c0/9df57b2460aa058971c8619132c4ab5b7b4572449c8f5b562e44c9d6c1c73ec7284f4d1e170549c42eef53cd9e0b7579409fb49fba862ab4d3050433579ef14c + languageName: node + linkType: hard + +"app-builder-lib@npm:24.13.3": + version: 24.13.3 + resolution: "app-builder-lib@npm:24.13.3" + dependencies: + "@develar/schema-utils": "npm:~2.6.5" + "@electron/notarize": "npm:2.2.1" + "@electron/osx-sign": "npm:1.0.5" + "@electron/universal": "npm:1.5.1" + "@malept/flatpak-bundler": "npm:^0.4.0" + "@types/fs-extra": "npm:9.0.13" + async-exit-hook: "npm:^2.0.1" + bluebird-lst: "npm:^1.0.9" + builder-util: "npm:24.13.1" + builder-util-runtime: "npm:9.2.4" + chromium-pickle-js: "npm:^0.2.0" + debug: "npm:^4.3.4" + ejs: "npm:^3.1.8" + electron-publish: "npm:24.13.1" + form-data: "npm:^4.0.0" + fs-extra: "npm:^10.1.0" + hosted-git-info: "npm:^4.1.0" + is-ci: "npm:^3.0.0" + isbinaryfile: "npm:^5.0.0" + js-yaml: "npm:^4.1.0" + lazy-val: "npm:^1.0.5" + minimatch: "npm:^5.1.1" + read-config-file: "npm:6.3.2" + sanitize-filename: "npm:^1.6.3" + semver: "npm:^7.3.8" + tar: "npm:^6.1.12" + temp-file: "npm:^3.4.0" + peerDependencies: + dmg-builder: 24.13.3 + electron-builder-squirrel-windows: 24.13.3 + checksum: 10c0/a3ff90e63f738e8a0d8a2f52fc336cd130adf1c00c7fe8e575a3b2bbb23b733135d530589882b45735fb8e43ff9ad8ed19d5992b4ac81029371efbb4bc6ffdb2 + languageName: node + linkType: hard + "argparse@npm:^1.0.7": version: 1.0.10 resolution: "argparse@npm:1.0.10" @@ -1731,6 +2076,27 @@ __metadata: languageName: node linkType: hard +"assert-plus@npm:^1.0.0": + version: 1.0.0 + resolution: "assert-plus@npm:1.0.0" + checksum: 10c0/b194b9d50c3a8f872ee85ab110784911e696a4d49f7ee6fc5fb63216dedbefd2c55999c70cb2eaeb4cf4a0e0338b44e9ace3627117b5bf0d42460e9132f21b91 + languageName: node + linkType: hard + +"astral-regex@npm:^2.0.0": + version: 2.0.0 + resolution: "astral-regex@npm:2.0.0" + checksum: 10c0/f63d439cc383db1b9c5c6080d1e240bd14dae745f15d11ec5da863e182bbeca70df6c8191cffef5deba0b566ef98834610a68be79ac6379c95eeb26e1b310e25 + languageName: node + linkType: hard + +"async-exit-hook@npm:^2.0.1": + version: 2.0.1 + resolution: "async-exit-hook@npm:2.0.1" + checksum: 10c0/81407a440ef0aab328df2369f1a9d957ee53e9a5a43e3b3dcb2be05151a68de0e4ff5e927f4718c88abf85800731f5b3f69a47a6642ce135f5e7d43ca0fce41d + languageName: node + linkType: hard + "async-function@npm:^1.0.0": version: 1.0.0 resolution: "async-function@npm:1.0.0" @@ -1738,6 +2104,34 @@ __metadata: languageName: node linkType: hard +"async@npm:^3.2.6": + version: 3.2.6 + resolution: "async@npm:3.2.6" + checksum: 10c0/36484bb15ceddf07078688d95e27076379cc2f87b10c03b6dd8a83e89475a3c8df5848859dd06a4c95af1e4c16fc973de0171a77f18ea00be899aca2a4f85e70 + languageName: node + linkType: hard + +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d + languageName: node + linkType: hard + +"at-least-node@npm:^1.0.0": + version: 1.0.0 + resolution: "at-least-node@npm:1.0.0" + checksum: 10c0/4c058baf6df1bc5a1697cf182e2029c58cd99975288a13f9e70068ef5d6f4e1f1fd7c4d2c3c4912eae44797d1725be9700995736deca441b39f3e66d8dee97ef + languageName: node + linkType: hard + +"atomically@npm:^1.7.0": + version: 1.7.0 + resolution: "atomically@npm:1.7.0" + checksum: 10c0/31f5efd5d69474681268557af4024f9e10223bb6b39fdedb5f2e19405186c4b76284fac9f6c43c9af75013cad6437e93b7168268f5ddb7aaf1cfc5fdb415f227 + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.7": version: 1.0.7 resolution: "available-typed-arrays@npm:1.0.7" @@ -1832,6 +2226,36 @@ __metadata: languageName: node linkType: hard +"base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": + version: 1.5.1 + resolution: "base64-js@npm:1.5.1" + checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf + languageName: node + linkType: hard + +"bluebird-lst@npm:^1.0.9": + version: 1.0.9 + resolution: "bluebird-lst@npm:1.0.9" + dependencies: + bluebird: "npm:^3.5.5" + checksum: 10c0/701eef18f37a53277adeacb21281a70fc4536e521fe0deb665a284f4d8480056c6932988c3dfa6a0c46b4d55f4599f716a15873f30ed5fc2470928093438f87e + languageName: node + linkType: hard + +"bluebird@npm:^3.5.5": + version: 3.7.2 + resolution: "bluebird@npm:3.7.2" + checksum: 10c0/680de03adc54ff925eaa6c7bb9a47a0690e8b5de60f4792604aae8ed618c65e6b63a7893b57ca924beaf53eee69c5af4f8314148c08124c550fe1df1add897d2 + languageName: node + linkType: hard + +"boolean@npm:^3.0.1": + version: 3.2.0 + resolution: "boolean@npm:3.2.0" + checksum: 10c0/6a0dc9668f6f3dda42a53c181fcbdad223169c8d87b6c4011b87a8b14a21770efb2934a778f063d7ece17280f8c06d313c87f7b834bb1dd526a867ffcd00febf + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.12 resolution: "brace-expansion@npm:1.1.12" @@ -1892,6 +2316,20 @@ __metadata: languageName: node linkType: hard +"buffer-crc32@npm:~0.2.3": + version: 0.2.13 + resolution: "buffer-crc32@npm:0.2.13" + checksum: 10c0/cb0a8ddf5cf4f766466db63279e47761eb825693eeba6a5a95ee4ec8cb8f81ede70aa7f9d8aeec083e781d47154290eb5d4d26b3f7a465ec57fb9e7d59c47150 + languageName: node + linkType: hard + +"buffer-equal@npm:^1.0.0": + version: 1.0.1 + resolution: "buffer-equal@npm:1.0.1" + checksum: 10c0/578f03cc9458f9151f68478ab80ebee99a4203de0647a47b491aa3d5fb821938cb4139119a2dae1a1ef9ed5506e0eee4d6a37178efbf2e2e0ee3a9886898fffd + languageName: node + linkType: hard + "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" @@ -1899,6 +2337,60 @@ __metadata: languageName: node linkType: hard +"buffer@npm:^5.1.0": + version: 5.7.1 + resolution: "buffer@npm:5.7.1" + dependencies: + base64-js: "npm:^1.3.1" + ieee754: "npm:^1.1.13" + checksum: 10c0/27cac81cff434ed2876058d72e7c4789d11ff1120ef32c9de48f59eab58179b66710c488987d295ae89a228f835fc66d088652dffeb8e3ba8659f80eb091d55e + languageName: node + linkType: hard + +"builder-util-runtime@npm:9.2.4": + version: 9.2.4 + resolution: "builder-util-runtime@npm:9.2.4" + dependencies: + debug: "npm:^4.3.4" + sax: "npm:^1.2.4" + checksum: 10c0/858978ffced52935db9c13139235679933616095459796ef2969e86641be53edec8c07bf14cfb42516e017124c653839aa4f66451dd5b41ba84728f54a167c64 + languageName: node + linkType: hard + +"builder-util-runtime@npm:9.4.0": + version: 9.4.0 + resolution: "builder-util-runtime@npm:9.4.0" + dependencies: + debug: "npm:^4.3.4" + sax: "npm:^1.2.4" + checksum: 10c0/cd7c54af44c9785a8f0ca759a5d6798f408b292d50557ae156756d5306e4e0980ed07029190f9178d1caa7cf38b4fdb16e16c08c40c3563a2aeaea081d440209 + languageName: node + linkType: hard + +"builder-util@npm:24.13.1": + version: 24.13.1 + resolution: "builder-util@npm:24.13.1" + dependencies: + 7zip-bin: "npm:~5.2.0" + "@types/debug": "npm:^4.1.6" + app-builder-bin: "npm:4.0.0" + bluebird-lst: "npm:^1.0.9" + builder-util-runtime: "npm:9.2.4" + chalk: "npm:^4.1.2" + cross-spawn: "npm:^7.0.3" + debug: "npm:^4.3.4" + fs-extra: "npm:^10.1.0" + http-proxy-agent: "npm:^5.0.0" + https-proxy-agent: "npm:^5.0.1" + is-ci: "npm:^3.0.0" + js-yaml: "npm:^4.1.0" + source-map-support: "npm:^0.5.19" + stat-mode: "npm:^1.0.0" + temp-file: "npm:^3.4.0" + checksum: 10c0/4f6654a73eaca8cb2a6d83e5a73318d47843df72d0eaa28392cdc0e38d8e343b91c6019bae0274eba4dfde9e82abd94e0eee75157f1fba7e8a8590631624987a + languageName: node + linkType: hard + "cacache@npm:^19.0.1": version: 19.0.1 resolution: "cacache@npm:19.0.1" @@ -1919,6 +2411,28 @@ __metadata: languageName: node linkType: hard +"cacheable-lookup@npm:^5.0.3": + version: 5.0.4 + resolution: "cacheable-lookup@npm:5.0.4" + checksum: 10c0/a6547fb4954b318aa831cbdd2f7b376824bc784fb1fa67610e4147099e3074726072d9af89f12efb69121415a0e1f2918a8ddd4aafcbcf4e91fbeef4a59cd42c + languageName: node + linkType: hard + +"cacheable-request@npm:^7.0.2": + version: 7.0.4 + resolution: "cacheable-request@npm:7.0.4" + dependencies: + clone-response: "npm:^1.0.2" + get-stream: "npm:^5.1.0" + http-cache-semantics: "npm:^4.0.0" + keyv: "npm:^4.0.0" + lowercase-keys: "npm:^2.0.0" + normalize-url: "npm:^6.0.1" + responselike: "npm:^2.0.0" + checksum: 10c0/0834a7d17ae71a177bc34eab06de112a43f9b5ad05ebe929bec983d890a7d9f2bc5f1aa8bb67ea2b65e07a3bc74bea35fa62dd36dbac52876afe36fdcf83da41 + languageName: node + linkType: hard + "call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": version: 1.0.2 resolution: "call-bind-apply-helpers@npm:1.0.2" @@ -2003,6 +2517,13 @@ __metadata: languageName: node linkType: hard +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: 10c0/594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6 + languageName: node + linkType: hard + "chownr@npm:^3.0.0": version: 3.0.0 resolution: "chownr@npm:3.0.0" @@ -2010,6 +2531,20 @@ __metadata: languageName: node linkType: hard +"chromium-pickle-js@npm:^0.2.0": + version: 0.2.0 + resolution: "chromium-pickle-js@npm:0.2.0" + checksum: 10c0/0a95bd280acdf05b0e08fa1a0e1db58c815dd24e92d639add8f494d23a8a49c26e4829721224d68f2f0e57a69047714db29bcff6deb5d029332321223416cb29 + languageName: node + linkType: hard + +"ci-info@npm:^3.2.0": + version: 3.9.0 + resolution: "ci-info@npm:3.9.0" + checksum: 10c0/6f0109e36e111684291d46123d491bc4e7b7a1934c3a20dea28cba89f1d4a03acd892f5f6a81ed3855c38647e285a150e3c9ba062e38943bef57fee6c1554c3a + languageName: node + linkType: hard + "ci-info@npm:^4.2.0": version: 4.3.0 resolution: "ci-info@npm:4.3.0" @@ -2033,6 +2568,16 @@ __metadata: languageName: node linkType: hard +"cli-truncate@npm:^2.1.0": + version: 2.1.0 + resolution: "cli-truncate@npm:2.1.0" + dependencies: + slice-ansi: "npm:^3.0.0" + string-width: "npm:^4.2.0" + checksum: 10c0/dfaa3df675bcef7a3254773de768712b590250420345a4c7ac151f041a4bacb4c25864b1377bee54a39b5925a030c00eabf014e312e3a4ac130952ed3b3879e9 + languageName: node + linkType: hard + "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -2044,7 +2589,16 @@ __metadata: languageName: node linkType: hard -"co@npm:^4.6.0": +"clone-response@npm:^1.0.2": + version: 1.0.3 + resolution: "clone-response@npm:1.0.3" + dependencies: + mimic-response: "npm:^1.0.0" + checksum: 10c0/06a2b611824efb128810708baee3bd169ec9a1bf5976a5258cd7eb3f7db25f00166c6eee5961f075c7e38e194f373d4fdf86b8166ad5b9c7e82bbd2e333a6087 + languageName: node + linkType: hard + +"co@npm:^4.6.0": version: 4.6.0 resolution: "co@npm:4.6.0" checksum: 10c0/c0e85ea0ca8bf0a50cbdca82efc5af0301240ca88ebe3644a6ffb8ffe911f34d40f8fbcf8f1d52c5ddd66706abd4d3bfcd64259f1e8e2371d4f47573b0dc8c28 @@ -2074,6 +2628,15 @@ __metadata: languageName: node linkType: hard +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: "npm:~1.0.0" + checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5 + languageName: node + linkType: hard + "commander@npm:*, commander@npm:^14.0.0": version: 14.0.0 resolution: "commander@npm:14.0.0" @@ -2081,6 +2644,20 @@ __metadata: languageName: node linkType: hard +"commander@npm:^5.0.0": + version: 5.1.0 + resolution: "commander@npm:5.1.0" + checksum: 10c0/da9d71dbe4ce039faf1fe9eac3771dca8c11d66963341f62602f7b66e36d2a3f8883407af4f9a37b1db1a55c59c0c1325f186425764c2e963dc1d67aec2a4b6d + languageName: node + linkType: hard + +"compare-version@npm:^0.1.2": + version: 0.1.2 + resolution: "compare-version@npm:0.1.2" + checksum: 10c0/f38b853cf0d244c0af5f444409abde3d2198cd97312efa1dbc4ab41b520009327c2a63db59bbaf2d69288eff6167ef22be9788dc5476157d073ecdff1a8eeb2d + languageName: node + linkType: hard + "concat-map@npm:0.0.1": version: 0.0.1 resolution: "concat-map@npm:0.0.1" @@ -2088,6 +2665,34 @@ __metadata: languageName: node linkType: hard +"conf@npm:^10.2.0": + version: 10.2.0 + resolution: "conf@npm:10.2.0" + dependencies: + ajv: "npm:^8.6.3" + ajv-formats: "npm:^2.1.1" + atomically: "npm:^1.7.0" + debounce-fn: "npm:^4.0.0" + dot-prop: "npm:^6.0.1" + env-paths: "npm:^2.2.1" + json-schema-typed: "npm:^7.0.3" + onetime: "npm:^5.1.2" + pkg-up: "npm:^3.1.0" + semver: "npm:^7.3.5" + checksum: 10c0/d608d8c54ba7fad368eac640e77f2ce0334ec27cfd62ac39f44e361af8af9915eaa6c2ada81fbc25c3219273d972b4868bc752e8e2116cb6e12d35df72dc25a4 + languageName: node + linkType: hard + +"config-file-ts@npm:^0.2.4": + version: 0.2.6 + resolution: "config-file-ts@npm:0.2.6" + dependencies: + glob: "npm:^10.3.10" + typescript: "npm:^5.3.3" + checksum: 10c0/ae4c213550aaa1c50671938ff0106495b7610b99a810fed9e35b5ca94dd49fcdd4f22cf132d3368cd19d67e37fff761352d63559f0e8866105a877f476a07be7 + languageName: node + linkType: hard + "convert-source-map@npm:^2.0.0": version: 2.0.0 resolution: "convert-source-map@npm:2.0.0" @@ -2095,7 +2700,23 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": +"core-util-is@npm:1.0.2": + version: 1.0.2 + resolution: "core-util-is@npm:1.0.2" + checksum: 10c0/980a37a93956d0de8a828ce508f9b9e3317039d68922ca79995421944146700e4aaf490a6dbfebcb1c5292a7184600c7710b957d724be1e37b8254c6bc0fe246 + languageName: node + linkType: hard + +"crc@npm:^3.8.0": + version: 3.8.0 + resolution: "crc@npm:3.8.0" + dependencies: + buffer: "npm:^5.1.0" + checksum: 10c0/1a0da36e5f95b19cd2a7b2eab5306a08f1c47bdd22da6f761ab764e2222e8e90a877398907cea94108bd5e41a6d311ea84d7914eaca67da2baa4050bd6384b3d + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -2139,6 +2760,15 @@ __metadata: languageName: node linkType: hard +"debounce-fn@npm:^4.0.0": + version: 4.0.0 + resolution: "debounce-fn@npm:4.0.0" + dependencies: + mimic-fn: "npm:^3.0.0" + checksum: 10c0/bcbd8eb253bdb6ee2f32759c95973c62bc479e74efbe1a44e17acfb0ea7d4bcbe615bf7e34aab80247ac08669c1ab72f7da0f384ceb7f15c18333d31d9030384 + languageName: node + linkType: hard + "debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.1": version: 4.4.1 resolution: "debug@npm:4.4.1" @@ -2160,6 +2790,15 @@ __metadata: languageName: node linkType: hard +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e + languageName: node + linkType: hard + "dedent@npm:^1.6.0": version: 1.6.0 resolution: "dedent@npm:1.6.0" @@ -2186,6 +2825,13 @@ __metadata: languageName: node linkType: hard +"defer-to-connect@npm:^2.0.0": + version: 2.0.1 + resolution: "defer-to-connect@npm:2.0.1" + checksum: 10c0/625ce28e1b5ad10cf77057b9a6a727bf84780c17660f6644dab61dd34c23de3001f03cedc401f7d30a4ed9965c2e8a7336e220a329146f2cf85d4eddea429782 + languageName: node + linkType: hard + "define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": version: 1.1.4 resolution: "define-data-property@npm:1.1.4" @@ -2208,6 +2854,13 @@ __metadata: languageName: node linkType: hard +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19 + languageName: node + linkType: hard + "detect-newline@npm:^3.1.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" @@ -2215,6 +2868,59 @@ __metadata: languageName: node linkType: hard +"detect-node@npm:^2.0.4": + version: 2.1.0 + resolution: "detect-node@npm:2.1.0" + checksum: 10c0/f039f601790f2e9d4654e499913259a798b1f5246ae24f86ab5e8bd4aaf3bce50484234c494f11fb00aecb0c6e2733aa7b1cf3f530865640b65fbbd65b2c4e09 + languageName: node + linkType: hard + +"dir-compare@npm:^3.0.0": + version: 3.3.0 + resolution: "dir-compare@npm:3.3.0" + dependencies: + buffer-equal: "npm:^1.0.0" + minimatch: "npm:^3.0.4" + checksum: 10c0/bafcb225a629994f1d5808eeb11b3b8adf49356c86bdc87588b30f22f8709044166e3b368c050b6a72bc54397c52d7e8013d5b5741306ee3511bf6b924f66212 + languageName: node + linkType: hard + +"dmg-builder@npm:24.13.3": + version: 24.13.3 + resolution: "dmg-builder@npm:24.13.3" + dependencies: + app-builder-lib: "npm:24.13.3" + builder-util: "npm:24.13.1" + builder-util-runtime: "npm:9.2.4" + dmg-license: "npm:^1.0.11" + fs-extra: "npm:^10.1.0" + iconv-lite: "npm:^0.6.2" + js-yaml: "npm:^4.1.0" + dependenciesMeta: + dmg-license: + optional: true + checksum: 10c0/1eb9e2d1396a9072d156657e537191ceb9d468e4884ef501ac58931f8d423e02ec48644e417cbb52e916d738d691d8a7254fe487b4882848527d58b8658b94f6 + languageName: node + linkType: hard + +"dmg-license@npm:^1.0.11": + version: 1.0.11 + resolution: "dmg-license@npm:1.0.11" + dependencies: + "@types/plist": "npm:^3.0.1" + "@types/verror": "npm:^1.10.3" + ajv: "npm:^6.10.0" + crc: "npm:^3.8.0" + iconv-corefoundation: "npm:^1.1.7" + plist: "npm:^3.0.4" + smart-buffer: "npm:^4.0.2" + verror: "npm:^1.10.0" + bin: + dmg-license: bin/dmg-license.js + conditions: os=darwin + languageName: node + linkType: hard + "doctrine@npm:^2.1.0": version: 2.1.0 resolution: "doctrine@npm:2.1.0" @@ -2224,6 +2930,29 @@ __metadata: languageName: node linkType: hard +"dot-prop@npm:^6.0.1": + version: 6.0.1 + resolution: "dot-prop@npm:6.0.1" + dependencies: + is-obj: "npm:^2.0.0" + checksum: 10c0/30e51ec6408978a6951b21e7bc4938aad01a86f2fdf779efe52330205c6bb8a8ea12f35925c2029d6dc9d1df22f916f32f828ce1e9b259b1371c580541c22b5a + languageName: node + linkType: hard + +"dotenv-expand@npm:^5.1.0": + version: 5.1.0 + resolution: "dotenv-expand@npm:5.1.0" + checksum: 10c0/24ac633de853ef474d0421cc639328b7134109c8dc2baaa5e3afb7495af5e9237136d7e6971e55668e4dce915487eb140967cdd2b3e99aa439e0f6bf8b56faeb + languageName: node + linkType: hard + +"dotenv@npm:^9.0.2": + version: 9.0.2 + resolution: "dotenv@npm:9.0.2" + checksum: 10c0/535f04d59e0bf58fe0c7966886eff42fb5e0227e2f7bfa38d37439bbf6b3c25d1b085bd235c9b98e7e9a032b1cd310904366e5588b320c29335d359660fab0d4 + languageName: node + linkType: hard + "dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" @@ -2242,6 +2971,64 @@ __metadata: languageName: node linkType: hard +"ejs@npm:^3.1.8": + version: 3.1.10 + resolution: "ejs@npm:3.1.10" + dependencies: + jake: "npm:^10.8.5" + bin: + ejs: bin/cli.js + checksum: 10c0/52eade9e68416ed04f7f92c492183340582a36482836b11eab97b159fcdcfdedc62233a1bf0bf5e5e1851c501f2dca0e2e9afd111db2599e4e7f53ee29429ae1 + languageName: node + linkType: hard + +"electron-builder@npm:^24.0.0": + version: 24.13.3 + resolution: "electron-builder@npm:24.13.3" + dependencies: + app-builder-lib: "npm:24.13.3" + builder-util: "npm:24.13.1" + builder-util-runtime: "npm:9.2.4" + chalk: "npm:^4.1.2" + dmg-builder: "npm:24.13.3" + fs-extra: "npm:^10.1.0" + is-ci: "npm:^3.0.0" + lazy-val: "npm:^1.0.5" + read-config-file: "npm:6.3.2" + simple-update-notifier: "npm:2.0.0" + yargs: "npm:^17.6.2" + bin: + electron-builder: cli.js + install-app-deps: install-app-deps.js + checksum: 10c0/497b83ef6c95e1756eb11f824cc52e434b1a83c3abe24df6958a348b6faf77b274892a09ca21ef60a241aac8d55804b321e443471fc8afdbac2dc563dea321c5 + languageName: node + linkType: hard + +"electron-publish@npm:24.13.1": + version: 24.13.1 + resolution: "electron-publish@npm:24.13.1" + dependencies: + "@types/fs-extra": "npm:^9.0.11" + builder-util: "npm:24.13.1" + builder-util-runtime: "npm:9.2.4" + chalk: "npm:^4.1.2" + fs-extra: "npm:^10.1.0" + lazy-val: "npm:^1.0.5" + mime: "npm:^2.5.2" + checksum: 10c0/d31e14f836c7cb4e56f897fcebedbe4c13c32974688d5c3a77681df882a24229188de4c0d46e9ae4981df6f308889118671a6ef5279105f8e6b920c34e1fcc2c + languageName: node + linkType: hard + +"electron-store@npm:^8.1.0": + version: 8.2.0 + resolution: "electron-store@npm:8.2.0" + dependencies: + conf: "npm:^10.2.0" + type-fest: "npm:^2.17.0" + checksum: 10c0/a4d19827e96ab67bf6c2a375910f51b147b23f4a0468da5cfeeb069acdfdbcd3a9f5650248a62a05aa0967149e4d1c47f2d0ba7582205e5eb38952c93b6882e1 + languageName: node + linkType: hard + "electron-to-chromium@npm:^1.5.211": version: 1.5.212 resolution: "electron-to-chromium@npm:1.5.212" @@ -2249,6 +3036,35 @@ __metadata: languageName: node linkType: hard +"electron-updater@npm:^6.1.0": + version: 6.6.8 + resolution: "electron-updater@npm:6.6.8" + dependencies: + builder-util-runtime: "npm:9.4.0" + fs-extra: "npm:^10.1.0" + js-yaml: "npm:^4.1.0" + lazy-val: "npm:^1.0.5" + lodash.escaperegexp: "npm:^4.1.2" + lodash.isequal: "npm:^4.5.0" + semver: "npm:^7.6.3" + tiny-typed-emitter: "npm:^2.1.0" + checksum: 10c0/e3531fe9e75d893b73bcb0eb0b6add1322cb230e146d5565e9f3ea2ffe66a2d070af5d0f68076c429b6c74ec44757d8c0e4ccfd11a4966b379f834c1cab9b98f + languageName: node + linkType: hard + +"electron@npm:^31.0.0": + version: 31.7.7 + resolution: "electron@npm:31.7.7" + dependencies: + "@electron/get": "npm:^2.0.0" + "@types/node": "npm:^20.9.0" + extract-zip: "npm:^2.0.1" + bin: + electron: cli.js + checksum: 10c0/f7e68fa44a2f802d9090de570d07279ea0d473be55c7f26b870ca0afb2b074d8f140a7f83f81d5c54687178efca145d9206d71430a754d8031bda785f20b49a2 + languageName: node + linkType: hard + "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -2279,7 +3095,16 @@ __metadata: languageName: node linkType: hard -"env-paths@npm:^2.2.0": +"end-of-stream@npm:^1.1.0": + version: 1.4.5 + resolution: "end-of-stream@npm:1.4.5" + dependencies: + once: "npm:^1.4.0" + checksum: 10c0/b0701c92a10b89afb1cb45bf54a5292c6f008d744eb4382fa559d54775ff31617d1d7bc3ef617575f552e24fad2c7c1a1835948c66b3f3a4be0a6c1f35c883d8 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0, env-paths@npm:^2.2.1": version: 2.2.1 resolution: "env-paths@npm:2.2.1" checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 @@ -2419,6 +3244,13 @@ __metadata: languageName: node linkType: hard +"es6-error@npm:^4.1.1": + version: 4.1.1 + resolution: "es6-error@npm:4.1.1" + checksum: 10c0/357663fb1e845c047d548c3d30f86e005db71e122678f4184ced0693f634688c3f3ef2d7de7d4af732f734de01f528b05954e270f06aa7d133679fb9fe6600ef + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -2734,6 +3566,30 @@ __metadata: languageName: node linkType: hard +"extract-zip@npm:^2.0.1": + version: 2.0.1 + resolution: "extract-zip@npm:2.0.1" + dependencies: + "@types/yauzl": "npm:^2.9.1" + debug: "npm:^4.1.1" + get-stream: "npm:^5.1.0" + yauzl: "npm:^2.10.0" + dependenciesMeta: + "@types/yauzl": + optional: true + bin: + extract-zip: cli.js + checksum: 10c0/9afbd46854aa15a857ae0341a63a92743a7b89c8779102c3b4ffc207516b2019337353962309f85c66ee3d9092202a83cdc26dbf449a11981272038443974aee + languageName: node + linkType: hard + +"extsprintf@npm:^1.2.0": + version: 1.4.1 + resolution: "extsprintf@npm:1.4.1" + checksum: 10c0/e10e2769985d0e9b6c7199b053a9957589d02e84de42832c295798cb422a025e6d4a92e0259c1fb4d07090f5bfde6b55fd9f880ac5855bd61d775f8ab75a7ab0 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -2775,6 +3631,13 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^3.0.1": + version: 3.1.0 + resolution: "fast-uri@npm:3.1.0" + checksum: 10c0/44364adca566f70f40d1e9b772c923138d47efeac2ae9732a872baafd77061f26b097ba2f68f0892885ad177becd065520412b8ffeec34b16c99433c5b9e2de7 + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.19.1 resolution: "fastq@npm:1.19.1" @@ -2793,6 +3656,15 @@ __metadata: languageName: node linkType: hard +"fd-slicer@npm:~1.1.0": + version: 1.1.0 + resolution: "fd-slicer@npm:1.1.0" + dependencies: + pend: "npm:~1.2.0" + checksum: 10c0/304dd70270298e3ffe3bcc05e6f7ade2511acc278bc52d025f8918b48b6aa3b77f10361bddfadfe2a28163f7af7adbdce96f4d22c31b2f648ba2901f0c5fc20e + languageName: node + linkType: hard + "fdir@npm:^6.4.4": version: 6.5.0 resolution: "fdir@npm:6.5.0" @@ -2814,6 +3686,15 @@ __metadata: languageName: node linkType: hard +"filelist@npm:^1.0.4": + version: 1.0.4 + resolution: "filelist@npm:1.0.4" + dependencies: + minimatch: "npm:^5.0.1" + checksum: 10c0/426b1de3944a3d153b053f1c0ebfd02dccd0308a4f9e832ad220707a6d1f1b3c9784d6cadf6b2f68f09a57565f63ebc7bcdc913ccf8012d834f472c46e596f41 + languageName: node + linkType: hard + "fill-range@npm:^7.1.1": version: 7.1.1 resolution: "fill-range@npm:7.1.1" @@ -2823,6 +3704,15 @@ __metadata: languageName: node linkType: hard +"find-up@npm:^3.0.0": + version: 3.0.0 + resolution: "find-up@npm:3.0.0" + dependencies: + locate-path: "npm:^3.0.0" + checksum: 10c0/2c2e7d0a26db858e2f624f39038c74739e38306dee42b45f404f770db357947be9d0d587f1cac72d20c114deb38aa57316e879eb0a78b17b46da7dab0a3bd6e3 + languageName: node + linkType: hard + "find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" @@ -2879,6 +3769,62 @@ __metadata: languageName: node linkType: hard +"form-data@npm:^4.0.0": + version: 4.0.4 + resolution: "form-data@npm:4.0.4" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + es-set-tostringtag: "npm:^2.1.0" + hasown: "npm:^2.0.2" + mime-types: "npm:^2.1.12" + checksum: 10c0/373525a9a034b9d57073e55eab79e501a714ffac02e7a9b01be1c820780652b16e4101819785e1e18f8d98f0aee866cc654d660a435c378e16a72f2e7cac9695 + languageName: node + linkType: hard + +"fs-extra@npm:^10.0.0, fs-extra@npm:^10.1.0": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/5f579466e7109719d162a9249abbeffe7f426eb133ea486e020b89bc6d67a741134076bf439983f2eb79276ceaf6bd7b7c1e43c3fd67fe889863e69072fb0a5e + languageName: node + linkType: hard + +"fs-extra@npm:^8.1.0": + version: 8.1.0 + resolution: "fs-extra@npm:8.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^4.0.0" + universalify: "npm:^0.1.0" + checksum: 10c0/259f7b814d9e50d686899550c4f9ded85c46c643f7fe19be69504888e007fcbc08f306fae8ec495b8b998635e997c9e3e175ff2eeed230524ef1c1684cc96423 + languageName: node + linkType: hard + +"fs-extra@npm:^9.0.0, fs-extra@npm:^9.0.1": + version: 9.1.0 + resolution: "fs-extra@npm:9.1.0" + dependencies: + at-least-node: "npm:^1.0.0" + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/9b808bd884beff5cb940773018179a6b94a966381d005479f00adda6b44e5e3d4abf765135773d849cc27efe68c349e4a7b86acd7d3306d5932c14f3a4b17a92 + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004 + languageName: node + linkType: hard + "fs-minipass@npm:^3.0.0": version: 3.0.3 resolution: "fs-minipass@npm:3.0.3" @@ -2991,6 +3937,15 @@ __metadata: languageName: node linkType: hard +"get-stream@npm:^5.1.0": + version: 5.2.0 + resolution: "get-stream@npm:5.2.0" + dependencies: + pump: "npm:^3.0.0" + checksum: 10c0/43797ffd815fbb26685bf188c8cfebecb8af87b3925091dd7b9a9c915993293d78e3c9e1bce125928ff92f2d0796f3889b92b5ec6d58d1041b574682132e0a80 + languageName: node + linkType: hard + "get-stream@npm:^6.0.0": version: 6.0.1 resolution: "get-stream@npm:6.0.1" @@ -3068,7 +4023,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.1.4": +"glob@npm:^7.1.4, glob@npm:^7.1.6": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -3082,6 +4037,20 @@ __metadata: languageName: node linkType: hard +"global-agent@npm:^3.0.0": + version: 3.0.0 + resolution: "global-agent@npm:3.0.0" + dependencies: + boolean: "npm:^3.0.1" + es6-error: "npm:^4.1.1" + matcher: "npm:^3.0.0" + roarr: "npm:^2.15.3" + semver: "npm:^7.3.2" + serialize-error: "npm:^7.0.1" + checksum: 10c0/bb8750d026b25da437072762fd739098bad92ff72f66483c3929db4579e072f5523960f7e7fd70ee0d75db48898067b5dc1c9c1d17888128cff008fcc34d1bd3 + languageName: node + linkType: hard + "globals@npm:^14.0.0": version: 14.0.0 resolution: "globals@npm:14.0.0" @@ -3089,7 +4058,7 @@ __metadata: languageName: node linkType: hard -"globalthis@npm:^1.0.4": +"globalthis@npm:^1.0.1, globalthis@npm:^1.0.4": version: 1.0.4 resolution: "globalthis@npm:1.0.4" dependencies: @@ -3106,7 +4075,26 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6": +"got@npm:^11.8.5": + version: 11.8.6 + resolution: "got@npm:11.8.6" + dependencies: + "@sindresorhus/is": "npm:^4.0.0" + "@szmarczak/http-timer": "npm:^4.0.5" + "@types/cacheable-request": "npm:^6.0.1" + "@types/responselike": "npm:^1.0.0" + cacheable-lookup: "npm:^5.0.3" + cacheable-request: "npm:^7.0.2" + decompress-response: "npm:^6.0.0" + http2-wrapper: "npm:^1.0.0-beta.5.2" + lowercase-keys: "npm:^2.0.0" + p-cancelable: "npm:^2.0.0" + responselike: "npm:^2.0.0" + checksum: 10c0/754dd44877e5cf6183f1e989ff01c648d9a4719e357457bd4c78943911168881f1cfb7b2cb15d885e2105b3ad313adb8f017a67265dd7ade771afdb261ee8cb1 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -3195,6 +4183,15 @@ __metadata: languageName: node linkType: hard +"hosted-git-info@npm:^4.1.0": + version: 4.1.0 + resolution: "hosted-git-info@npm:4.1.0" + dependencies: + lru-cache: "npm:^6.0.0" + checksum: 10c0/150fbcb001600336d17fdbae803264abed013548eea7946c2264c49ebe2ebd8c4441ba71dd23dd8e18c65de79d637f98b22d4760ba5fb2e0b15d62543d0fff07 + languageName: node + linkType: hard + "html-escaper@npm:^2.0.0": version: 2.0.2 resolution: "html-escaper@npm:2.0.2" @@ -3202,13 +4199,24 @@ __metadata: languageName: node linkType: hard -"http-cache-semantics@npm:^4.1.1": +"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.1": version: 4.2.0 resolution: "http-cache-semantics@npm:4.2.0" checksum: 10c0/45b66a945cf13ec2d1f29432277201313babf4a01d9e52f44b31ca923434083afeca03f18417f599c9ab3d0e7b618ceb21257542338b57c54b710463b4a53e37 languageName: node linkType: hard +"http-proxy-agent@npm:^5.0.0": + version: 5.0.0 + resolution: "http-proxy-agent@npm:5.0.0" + dependencies: + "@tootallnate/once": "npm:2" + agent-base: "npm:6" + debug: "npm:4" + checksum: 10c0/32a05e413430b2c1e542e5c74b38a9f14865301dd69dff2e53ddb684989440e3d2ce0c4b64d25eb63cf6283e6265ff979a61cf93e3ca3d23047ddfdc8df34a32 + languageName: node + linkType: hard + "http-proxy-agent@npm:^7.0.0": version: 7.0.2 resolution: "http-proxy-agent@npm:7.0.2" @@ -3219,6 +4227,26 @@ __metadata: languageName: node linkType: hard +"http2-wrapper@npm:^1.0.0-beta.5.2": + version: 1.0.3 + resolution: "http2-wrapper@npm:1.0.3" + dependencies: + quick-lru: "npm:^5.1.1" + resolve-alpn: "npm:^1.0.0" + checksum: 10c0/6a9b72a033e9812e1476b9d776ce2f387bc94bc46c88aea0d5dab6bd47d0a539b8178830e77054dd26d1142c866d515a28a4dc7c3ff4232c88ff2ebe4f5d12d1 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^5.0.1": + version: 5.0.1 + resolution: "https-proxy-agent@npm:5.0.1" + dependencies: + agent-base: "npm:6" + debug: "npm:4" + checksum: 10c0/6dd639f03434003577c62b27cafdb864784ef19b2de430d8ae2a1d45e31c4fd60719e5637b44db1a88a046934307da7089e03d6089ec3ddacc1189d8de8897d1 + languageName: node + linkType: hard + "https-proxy-agent@npm:^7.0.1": version: 7.0.6 resolution: "https-proxy-agent@npm:7.0.6" @@ -3236,6 +4264,16 @@ __metadata: languageName: node linkType: hard +"iconv-corefoundation@npm:^1.1.7": + version: 1.1.7 + resolution: "iconv-corefoundation@npm:1.1.7" + dependencies: + cli-truncate: "npm:^2.1.0" + node-addon-api: "npm:^1.6.3" + conditions: os=darwin + languageName: node + linkType: hard + "iconv-lite@npm:^0.6.2": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" @@ -3254,6 +4292,13 @@ __metadata: languageName: node linkType: hard +"ieee754@npm:^1.1.13": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb + languageName: node + linkType: hard + "ignore@npm:^5.2.0": version: 5.3.2 resolution: "ignore@npm:5.3.2" @@ -3398,6 +4443,17 @@ __metadata: languageName: node linkType: hard +"is-ci@npm:^3.0.0": + version: 3.0.1 + resolution: "is-ci@npm:3.0.1" + dependencies: + ci-info: "npm:^3.2.0" + bin: + is-ci: bin.js + checksum: 10c0/0e81caa62f4520d4088a5bef6d6337d773828a88610346c4b1119fb50c842587ed8bef1e5d9a656835a599e7209405b5761ddf2339668f2d0f4e889a92fe6051 + languageName: node + linkType: hard + "is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.0, is-core-module@npm:^2.16.1": version: 2.16.1 resolution: "is-core-module@npm:2.16.1" @@ -3510,6 +4566,13 @@ __metadata: languageName: node linkType: hard +"is-obj@npm:^2.0.0": + version: 2.0.0 + resolution: "is-obj@npm:2.0.0" + checksum: 10c0/85044ed7ba8bd169e2c2af3a178cacb92a97aa75de9569d02efef7f443a824b5e153eba72b9ae3aca6f8ce81955271aa2dc7da67a8b720575d3e38104208cb4e + languageName: node + linkType: hard + "is-regex@npm:^1.2.1": version: 1.2.1 resolution: "is-regex@npm:1.2.1" @@ -3608,6 +4671,20 @@ __metadata: languageName: node linkType: hard +"isbinaryfile@npm:^4.0.8": + version: 4.0.10 + resolution: "isbinaryfile@npm:4.0.10" + checksum: 10c0/0703d8cfeb69ed79e6d173120f327450011a066755150a6bbf97ffecec1069a5f2092777868315b21359098c84b54984871cad1abce877ad9141fb2caf3dcabf + languageName: node + linkType: hard + +"isbinaryfile@npm:^5.0.0": + version: 5.0.6 + resolution: "isbinaryfile@npm:5.0.6" + checksum: 10c0/53d700189a2a97965f2dcc9ced47644daad24b68ca42eb8a170f0cc0f2b83d52d58d956d969f0dd5f0d4f0012dc488dba079cacd7086c595932897da71085a7f + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -3696,6 +4773,19 @@ __metadata: languageName: node linkType: hard +"jake@npm:^10.8.5": + version: 10.9.4 + resolution: "jake@npm:10.9.4" + dependencies: + async: "npm:^3.2.6" + filelist: "npm:^1.0.4" + picocolors: "npm:^1.1.1" + bin: + jake: bin/cli.js + checksum: 10c0/bb52f000340d4a32f1a3893b9abe56ef2b77c25da4dbf2c0c874a8159d082dddda50a5ad10e26060198bd645b928ba8dba3b362710f46a247e335321188c5a9c + languageName: node + linkType: hard + "jest-changed-files@npm:30.0.5": version: 30.0.5 resolution: "jest-changed-files@npm:30.0.5" @@ -4194,10 +5284,31 @@ __metadata: languageName: node linkType: hard -"json-stable-stringify-without-jsonify@npm:^1.0.1": - version: 1.0.1 - resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" - checksum: 10c0/cb168b61fd4de83e58d09aaa6425ef71001bae30d260e2c57e7d09a5fd82223e2f22a042dedaab8db23b7d9ae46854b08bb1f91675a8be11c5cffebef5fb66a5 +"json-schema-traverse@npm:^1.0.0": + version: 1.0.0 + resolution: "json-schema-traverse@npm:1.0.0" + checksum: 10c0/71e30015d7f3d6dc1c316d6298047c8ef98a06d31ad064919976583eb61e1018a60a0067338f0f79cabc00d84af3fcc489bd48ce8a46ea165d9541ba17fb30c6 + languageName: node + linkType: hard + +"json-schema-typed@npm:^7.0.3": + version: 7.0.3 + resolution: "json-schema-typed@npm:7.0.3" + checksum: 10c0/b4a6d984dd91f9aba72df8768c5ced99e789b8e17b55ee24afb3a687ce55b70a7b3f4360cac67939e1ff98e136ca26f3aa530635c13ef371ae5edc48b69a65f6 + languageName: node + linkType: hard + +"json-stable-stringify-without-jsonify@npm:^1.0.1": + version: 1.0.1 + resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" + checksum: 10c0/cb168b61fd4de83e58d09aaa6425ef71001bae30d260e2c57e7d09a5fd82223e2f22a042dedaab8db23b7d9ae46854b08bb1f91675a8be11c5cffebef5fb66a5 + languageName: node + linkType: hard + +"json-stringify-safe@npm:^5.0.1": + version: 5.0.1 + resolution: "json-stringify-safe@npm:5.0.1" + checksum: 10c0/7dbf35cd0411d1d648dceb6d59ce5857ec939e52e4afc37601aa3da611f0987d5cee5b38d58329ceddf3ed48bd7215229c8d52059ab01f2444a338bf24ed0f37 languageName: node linkType: hard @@ -4212,7 +5323,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:^2.2.3": +"json5@npm:^2.2.0, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" bin: @@ -4221,7 +5332,32 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.4": +"jsonfile@npm:^4.0.0": + version: 4.0.0 + resolution: "jsonfile@npm:4.0.0" + dependencies: + graceful-fs: "npm:^4.1.6" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/7dc94b628d57a66b71fb1b79510d460d662eb975b5f876d723f81549c2e9cd316d58a2ddf742b2b93a4fa6b17b2accaf1a738a0e2ea114bdfb13a32e5377e480 + languageName: node + linkType: hard + +"jsonfile@npm:^6.0.1": + version: 6.2.0 + resolution: "jsonfile@npm:6.2.0" + dependencies: + graceful-fs: "npm:^4.1.6" + universalify: "npm:^2.0.0" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/7f4f43b08d1869ded8a6822213d13ae3b99d651151d77efd1557ced0889c466296a7d9684e397bd126acf5eb2cfcb605808c3e681d0fdccd2fe5a04b47e76c0d + languageName: node + linkType: hard + +"keyv@npm:^4.0.0, keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -4230,6 +5366,13 @@ __metadata: languageName: node linkType: hard +"lazy-val@npm:^1.0.4, lazy-val@npm:^1.0.5": + version: 1.0.5 + resolution: "lazy-val@npm:1.0.5" + checksum: 10c0/28ba7a0e704895a444eed47d110274090f485b991f2ea6fff2ab0878c529c53f60f2eb2d944cbbd68b91408e7455eabc62861c48289d4757fa9c818b97454f24 + languageName: node + linkType: hard + "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -4254,6 +5397,16 @@ __metadata: languageName: node linkType: hard +"locate-path@npm:^3.0.0": + version: 3.0.0 + resolution: "locate-path@npm:3.0.0" + dependencies: + p-locate: "npm:^3.0.0" + path-exists: "npm:^3.0.0" + checksum: 10c0/3db394b7829a7fe2f4fbdd25d3c4689b85f003c318c5da4052c7e56eed697da8f1bce5294f685c69ff76e32cba7a33629d94396976f6d05fb7f4c755c5e2ae8b + languageName: node + linkType: hard + "locate-path@npm:^5.0.0": version: 5.0.0 resolution: "locate-path@npm:5.0.0" @@ -4272,6 +5425,20 @@ __metadata: languageName: node linkType: hard +"lodash.escaperegexp@npm:^4.1.2": + version: 4.1.2 + resolution: "lodash.escaperegexp@npm:4.1.2" + checksum: 10c0/484ad4067fa9119bb0f7c19a36ab143d0173a081314993fe977bd00cf2a3c6a487ce417a10f6bac598d968364f992153315f0dbe25c9e38e3eb7581dd333e087 + languageName: node + linkType: hard + +"lodash.isequal@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.isequal@npm:4.5.0" + checksum: 10c0/dfdb2356db19631a4b445d5f37868a095e2402292d59539a987f134a8778c62a2810c2452d11ae9e6dcac71fc9de40a6fedcb20e2952a15b431ad8b29e50e28f + languageName: node + linkType: hard + "lodash.memoize@npm:^4.1.2": version: 4.1.2 resolution: "lodash.memoize@npm:4.1.2" @@ -4286,6 +5453,20 @@ __metadata: languageName: node linkType: hard +"lodash@npm:^4.17.15": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c + languageName: node + linkType: hard + +"lowercase-keys@npm:^2.0.0": + version: 2.0.0 + resolution: "lowercase-keys@npm:2.0.0" + checksum: 10c0/f82a2b3568910509da4b7906362efa40f5b54ea14c2584778ddb313226f9cbf21020a5db35f9b9a0e95847a9b781d548601f31793d736b22a2b8ae8eb9ab1082 + languageName: node + linkType: hard + "lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" @@ -4309,6 +5490,15 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^6.0.0": + version: 6.0.0 + resolution: "lru-cache@npm:6.0.0" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10c0/cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9 + languageName: node + linkType: hard + "make-dir@npm:^4.0.0": version: 4.0.0 resolution: "make-dir@npm:4.0.0" @@ -4353,6 +5543,15 @@ __metadata: languageName: node linkType: hard +"matcher@npm:^3.0.0": + version: 3.0.0 + resolution: "matcher@npm:3.0.0" + dependencies: + escape-string-regexp: "npm:^4.0.0" + checksum: 10c0/2edf24194a2879690bcdb29985fc6bc0d003df44e04df21ebcac721fa6ce2f6201c579866bb92f9380bffe946f11ecd8cd31f34117fb67ebf8aca604918e127e + languageName: node + linkType: hard + "math-intrinsics@npm:^1.1.0": version: 1.1.0 resolution: "math-intrinsics@npm:1.1.0" @@ -4384,6 +5583,31 @@ __metadata: languageName: node linkType: hard +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 + languageName: node + linkType: hard + +"mime@npm:^2.5.2": + version: 2.6.0 + resolution: "mime@npm:2.6.0" + bin: + mime: cli.js + checksum: 10c0/a7f2589900d9c16e3bdf7672d16a6274df903da958c1643c9c45771f0478f3846dcb1097f31eb9178452570271361e2149310931ec705c037210fc69639c8e6c + languageName: node + linkType: hard + "mimic-fn@npm:^2.1.0": version: 2.1.0 resolution: "mimic-fn@npm:2.1.0" @@ -4391,6 +5615,27 @@ __metadata: languageName: node linkType: hard +"mimic-fn@npm:^3.0.0": + version: 3.1.0 + resolution: "mimic-fn@npm:3.1.0" + checksum: 10c0/a07cdd8ed6490c2dff5b11f889b245d9556b80f5a653a552a651d17cff5a2d156e632d235106c2369f00cccef4071704589574cf3601bc1b1400a1f620dff067 + languageName: node + linkType: hard + +"mimic-response@npm:^1.0.0": + version: 1.0.1 + resolution: "mimic-response@npm:1.0.1" + checksum: 10c0/c5381a5eae997f1c3b5e90ca7f209ed58c3615caeee850e85329c598f0c000ae7bec40196580eef1781c60c709f47258131dab237cad8786f8f56750594f27fa + languageName: node + linkType: hard + +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 + languageName: node + linkType: hard + "minimatch@npm:^10.0.3": version: 10.0.3 resolution: "minimatch@npm:10.0.3" @@ -4409,6 +5654,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^5.0.1, minimatch@npm:^5.1.1": + version: 5.1.6 + resolution: "minimatch@npm:5.1.6" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10c0/3defdfd230914f22a8da203747c42ee3c405c39d4d37ffda284dac5e45b7e1f6c49aa8be606509002898e73091ff2a3bbfc59c2c6c71d4660609f63aa92f98e3 + languageName: node + linkType: hard + "minimatch@npm:^9.0.4": version: 9.0.5 resolution: "minimatch@npm:9.0.5" @@ -4485,6 +5739,13 @@ __metadata: languageName: node linkType: hard +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 10c0/a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462 + languageName: node + linkType: hard + "minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": version: 7.1.2 resolution: "minipass@npm:7.1.2" @@ -4492,6 +5753,16 @@ __metadata: languageName: node linkType: hard +"minizlib@npm:^2.1.1": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: 10c0/64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78 + languageName: node + linkType: hard + "minizlib@npm:^3.0.1": version: 3.0.2 resolution: "minizlib@npm:3.0.2" @@ -4501,6 +5772,15 @@ __metadata: languageName: node linkType: hard +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf + languageName: node + linkType: hard + "mkdirp@npm:^3.0.1": version: 3.0.1 resolution: "mkdirp@npm:3.0.1" @@ -4554,6 +5834,15 @@ __metadata: languageName: node linkType: hard +"node-addon-api@npm:^1.6.3": + version: 1.7.2 + resolution: "node-addon-api@npm:1.7.2" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/bcf526f2ce788182730d3c3df5206585873d1e837a6e1378ff84abccf2f19cf3f93a8274f9c1245af0de63a0dbd1bb95ca2f767ecf5c678d6930326aaf396c4e + languageName: node + linkType: hard + "node-gyp@npm:latest": version: 11.4.2 resolution: "node-gyp@npm:11.4.2" @@ -4606,6 +5895,13 @@ __metadata: languageName: node linkType: hard +"normalize-url@npm:^6.0.1": + version: 6.1.0 + resolution: "normalize-url@npm:6.1.0" + checksum: 10c0/95d948f9bdd2cfde91aa786d1816ae40f8262946e13700bf6628105994fe0ff361662c20af3961161c38a119dc977adeb41fc0b41b1745eb77edaaf9cb22db23 + languageName: node + linkType: hard + "npm-run-path@npm:^4.0.1": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" @@ -4678,7 +5974,7 @@ __metadata: languageName: node linkType: hard -"once@npm:^1.3.0": +"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": version: 1.4.0 resolution: "once@npm:1.4.0" dependencies: @@ -4721,7 +6017,14 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^2.2.0": +"p-cancelable@npm:^2.0.0": + version: 2.1.1 + resolution: "p-cancelable@npm:2.1.1" + checksum: 10c0/8c6dc1f8dd4154fd8b96a10e55a3a832684c4365fb9108056d89e79fbf21a2465027c04a59d0d797b5ffe10b54a61a32043af287d5c4860f1e996cbdbc847f01 + languageName: node + linkType: hard + +"p-limit@npm:^2.0.0, p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" dependencies: @@ -4739,6 +6042,15 @@ __metadata: languageName: node linkType: hard +"p-locate@npm:^3.0.0": + version: 3.0.0 + resolution: "p-locate@npm:3.0.0" + dependencies: + p-limit: "npm:^2.0.0" + checksum: 10c0/7b7f06f718f19e989ce6280ed4396fb3c34dabdee0df948376483032f9d5ec22fdf7077ec942143a75827bb85b11da72016497fc10dac1106c837ed593969ee8 + languageName: node + linkType: hard + "p-locate@npm:^4.1.0": version: 4.1.0 resolution: "p-locate@npm:4.1.0" @@ -4799,6 +6111,13 @@ __metadata: languageName: node linkType: hard +"path-exists@npm:^3.0.0": + version: 3.0.0 + resolution: "path-exists@npm:3.0.0" + checksum: 10c0/17d6a5664bc0a11d48e2b2127d28a0e58822c6740bde30403f08013da599182289c56518bec89407e3f31d3c2b6b296a4220bc3f867f0911fee6952208b04167 + languageName: node + linkType: hard + "path-exists@npm:^4.0.0": version: 4.0.0 resolution: "path-exists@npm:4.0.0" @@ -4847,6 +6166,13 @@ __metadata: languageName: node linkType: hard +"pend@npm:~1.2.0": + version: 1.2.0 + resolution: "pend@npm:1.2.0" + checksum: 10c0/8a87e63f7a4afcfb0f9f77b39bb92374afc723418b9cb716ee4257689224171002e07768eeade4ecd0e86f1fa3d8f022994219fb45634f2dbd78c6803e452458 + languageName: node + linkType: hard + "picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" @@ -4884,6 +6210,26 @@ __metadata: languageName: node linkType: hard +"pkg-up@npm:^3.1.0": + version: 3.1.0 + resolution: "pkg-up@npm:3.1.0" + dependencies: + find-up: "npm:^3.0.0" + checksum: 10c0/ecb60e1f8e1f611c0bdf1a0b6a474d6dfb51185567dc6f29cdef37c8d480ecba5362e006606bb290519bbb6f49526c403fabea93c3090c20368d98bb90c999ab + languageName: node + linkType: hard + +"plist@npm:^3.0.4, plist@npm:^3.0.5": + version: 3.1.0 + resolution: "plist@npm:3.1.0" + dependencies: + "@xmldom/xmldom": "npm:^0.8.8" + base64-js: "npm:^1.5.1" + xmlbuilder: "npm:^15.1.1" + checksum: 10c0/db19ba50faafc4103df8e79bcd6b08004a56db2a9dd30b3e5c8b0ef30398ef44344a674e594d012c8fc39e539a2b72cb58c60a76b4b4401cbbc7c8f6b028d93d + languageName: node + linkType: hard + "possible-typed-array-names@npm:^1.0.0": version: 1.1.0 resolution: "possible-typed-array-names@npm:1.1.0" @@ -4934,6 +6280,13 @@ __metadata: languageName: node linkType: hard +"progress@npm:^2.0.3": + version: 2.0.3 + resolution: "progress@npm:2.0.3" + checksum: 10c0/1697e07cb1068055dbe9fe858d242368ff5d2073639e652b75a7eb1f2a1a8d4afd404d719de23c7b48481a6aa0040686310e2dac2f53d776daa2176d3f96369c + languageName: node + linkType: hard + "promise-retry@npm:^2.0.1": version: 2.0.1 resolution: "promise-retry@npm:2.0.1" @@ -4944,6 +6297,16 @@ __metadata: languageName: node linkType: hard +"pump@npm:^3.0.0": + version: 3.0.3 + resolution: "pump@npm:3.0.3" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: 10c0/ada5cdf1d813065bbc99aa2c393b8f6beee73b5de2890a8754c9f488d7323ffd2ca5f5a0943b48934e3fcbd97637d0337369c3c631aeb9614915db629f1c75c9 + languageName: node + linkType: hard + "punycode@npm:^2.1.0": version: 2.3.1 resolution: "punycode@npm:2.3.1" @@ -4965,6 +6328,13 @@ __metadata: languageName: node linkType: hard +"quick-lru@npm:^5.1.1": + version: 5.1.1 + resolution: "quick-lru@npm:5.1.1" + checksum: 10c0/a24cba5da8cec30d70d2484be37622580f64765fb6390a928b17f60cd69e8dbd32a954b3ff9176fa1b86d86ff2ba05252fae55dc4d40d0291c60412b0ad096da + languageName: node + linkType: hard + "react-is@npm:^18.3.1": version: 18.3.1 resolution: "react-is@npm:18.3.1" @@ -4972,6 +6342,20 @@ __metadata: languageName: node linkType: hard +"read-config-file@npm:6.3.2": + version: 6.3.2 + resolution: "read-config-file@npm:6.3.2" + dependencies: + config-file-ts: "npm:^0.2.4" + dotenv: "npm:^9.0.2" + dotenv-expand: "npm:^5.1.0" + js-yaml: "npm:^4.1.0" + json5: "npm:^2.2.0" + lazy-val: "npm:^1.0.4" + checksum: 10c0/b249d165c342e32497ce2ca9f31cddad150111763c2199601e3b9a33b726ff0f7fefbea7680c19c422e2cac810b4b4daf5d1890c06ebf65ed6feef1173238f91 + languageName: node + linkType: hard + "reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9": version: 1.0.10 resolution: "reflect.getprototypeof@npm:1.0.10" @@ -5009,6 +6393,20 @@ __metadata: languageName: node linkType: hard +"require-from-string@npm:^2.0.2": + version: 2.0.2 + resolution: "require-from-string@npm:2.0.2" + checksum: 10c0/aaa267e0c5b022fc5fd4eef49d8285086b15f2a1c54b28240fdf03599cbd9c26049fee3eab894f2e1f6ca65e513b030a7c264201e3f005601e80c49fb2937ce2 + languageName: node + linkType: hard + +"resolve-alpn@npm:^1.0.0": + version: 1.2.1 + resolution: "resolve-alpn@npm:1.2.1" + checksum: 10c0/b70b29c1843bc39781ef946c8cd4482e6d425976599c0f9c138cec8209e4e0736161bf39319b01676a847000085dfdaf63583c6fb4427bf751a10635bd2aa0c4 + languageName: node + linkType: hard + "resolve-cwd@npm:^3.0.0": version: 3.0.0 resolution: "resolve-cwd@npm:3.0.0" @@ -5065,6 +6463,15 @@ __metadata: languageName: node linkType: hard +"responselike@npm:^2.0.0": + version: 2.0.1 + resolution: "responselike@npm:2.0.1" + dependencies: + lowercase-keys: "npm:^2.0.0" + checksum: 10c0/360b6deb5f101a9f8a4174f7837c523c3ec78b7ca8a7c1d45a1062b303659308a23757e318b1e91ed8684ad1205721142dd664d94771cd63499353fd4ee732b5 + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -5079,6 +6486,20 @@ __metadata: languageName: node linkType: hard +"roarr@npm:^2.15.3": + version: 2.15.4 + resolution: "roarr@npm:2.15.4" + dependencies: + boolean: "npm:^3.0.1" + detect-node: "npm:^2.0.4" + globalthis: "npm:^1.0.1" + json-stringify-safe: "npm:^5.0.1" + semver-compare: "npm:^1.0.0" + sprintf-js: "npm:^1.1.2" + checksum: 10c0/7d01d4c14513c461778dd673a8f9e53255221f8d04173aafeb8e11b23d8b659bb83f1c90cfe81af7f9c213b8084b404b918108fd792bda76678f555340cc64ec + languageName: node + linkType: hard + "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -5129,7 +6550,30 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.3.1": +"sanitize-filename@npm:^1.6.3": + version: 1.6.3 + resolution: "sanitize-filename@npm:1.6.3" + dependencies: + truncate-utf8-bytes: "npm:^1.0.0" + checksum: 10c0/16ff47556a6e54e228c28db096bedd303da67b030d4bea4925fd71324932d6b02c7b0446f00ad33987b25b6414f24ae968e01a1a1679ce599542e82c4b07eb1f + languageName: node + linkType: hard + +"sax@npm:^1.2.4": + version: 1.4.1 + resolution: "sax@npm:1.4.1" + checksum: 10c0/6bf86318a254c5d898ede6bd3ded15daf68ae08a5495a2739564eb265cd13bcc64a07ab466fb204f67ce472bb534eb8612dac587435515169593f4fffa11de7c + languageName: node + linkType: hard + +"semver-compare@npm:^1.0.0": + version: 1.0.0 + resolution: "semver-compare@npm:1.0.0" + checksum: 10c0/9ef4d8b81847556f0865f46ddc4d276bace118c7cb46811867af82e837b7fc473911981d5a0abc561fa2db487065572217e5b06e18701c4281bcdd2a1affaff1 + languageName: node + linkType: hard + +"semver@npm:^6.2.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -5138,7 +6582,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.1, semver@npm:^7.7.2": +"semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.1, semver@npm:^7.7.2": version: 7.7.2 resolution: "semver@npm:7.7.2" bin: @@ -5147,6 +6591,15 @@ __metadata: languageName: node linkType: hard +"serialize-error@npm:^7.0.1": + version: 7.0.1 + resolution: "serialize-error@npm:7.0.1" + dependencies: + type-fest: "npm:^0.13.1" + checksum: 10c0/7982937d578cd901276c8ab3e2c6ed8a4c174137730f1fb0402d005af209a0e84d04acc874e317c936724c7b5b26c7a96ff7e4b8d11a469f4924a4b0ea814c05 + languageName: node + linkType: hard + "set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" @@ -5262,6 +6715,15 @@ __metadata: languageName: node linkType: hard +"simple-update-notifier@npm:2.0.0": + version: 2.0.0 + resolution: "simple-update-notifier@npm:2.0.0" + dependencies: + semver: "npm:^7.5.3" + checksum: 10c0/2a00bd03bfbcbf8a737c47ab230d7920f8bfb92d1159d421bdd194479f6d01ebc995d13fbe13d45dace23066a78a3dc6642999b4e3b38b847e6664191575b20c + languageName: node + linkType: hard + "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0" @@ -5269,7 +6731,18 @@ __metadata: languageName: node linkType: hard -"smart-buffer@npm:^4.2.0": +"slice-ansi@npm:^3.0.0": + version: 3.0.0 + resolution: "slice-ansi@npm:3.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + astral-regex: "npm:^2.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + checksum: 10c0/88083c9d0ca67d09f8b4c78f68833d69cabbb7236b74df5d741ad572bbf022deaf243fa54009cd434350622a1174ab267710fcc80a214ecc7689797fe00cb27c + languageName: node + linkType: hard + +"smart-buffer@npm:^4.0.2, smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539 @@ -5307,6 +6780,16 @@ __metadata: languageName: node linkType: hard +"source-map-support@npm:^0.5.19": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: 10c0/9ee09942f415e0f721d6daad3917ec1516af746a8120bba7bb56278707a37f1eb8642bde456e98454b8a885023af81a16e646869975f06afc1a711fb90484e7d + languageName: node + linkType: hard + "source-map@npm:^0.6.0, source-map@npm:^0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" @@ -5314,6 +6797,13 @@ __metadata: languageName: node linkType: hard +"sprintf-js@npm:^1.1.2": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec + languageName: node + linkType: hard + "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -5346,6 +6836,13 @@ __metadata: languageName: node linkType: hard +"stat-mode@npm:^1.0.0": + version: 1.0.0 + resolution: "stat-mode@npm:1.0.0" + checksum: 10c0/89b66a538dbfd45038fefdaf5b2104dc6e911605af1c201793e9629592ed9fdc7bdd1bca42806d0d4167c6d9cacac1f3fda41ddfe334a5c1f898113da38fae74 + languageName: node + linkType: hard + "stop-iteration-iterator@npm:^1.1.0": version: 1.1.0 resolution: "stop-iteration-iterator@npm:1.1.0" @@ -5497,6 +6994,15 @@ __metadata: languageName: unknown linkType: soft +"sumchecker@npm:^3.0.1": + version: 3.0.1 + resolution: "sumchecker@npm:3.0.1" + dependencies: + debug: "npm:^4.1.0" + checksum: 10c0/43c387be9dfe22dbeaf39dfa4ffb279847aeb37a42a8988c0b066f548bbd209aa8c65e03da29f2b29be1a66b577801bf89fff0007df4183db2f286263a9569e5 + languageName: node + linkType: hard + "supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" @@ -5531,6 +7037,20 @@ __metadata: languageName: node linkType: hard +"tar@npm:^6.1.12": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: 10c0/a5eca3eb50bc11552d453488344e6507156b9193efd7635e98e867fab275d527af53d8866e2370cd09dfe74378a18111622ace35af6a608e5223a7d27fe99537 + languageName: node + linkType: hard + "tar@npm:^7.4.3": version: 7.4.3 resolution: "tar@npm:7.4.3" @@ -5545,6 +7065,16 @@ __metadata: languageName: node linkType: hard +"temp-file@npm:^3.4.0": + version: 3.4.0 + resolution: "temp-file@npm:3.4.0" + dependencies: + async-exit-hook: "npm:^2.0.1" + fs-extra: "npm:^10.0.0" + checksum: 10c0/70e441909097346a930ae02278df9b0133cd02dddf0b49e5ddaade735fef1410a50a448a2a812106f97c045294c99cc19f26943eb88f1d728d41fbc445a40298 + languageName: node + linkType: hard + "test-exclude@npm:^6.0.0": version: 6.0.0 resolution: "test-exclude@npm:6.0.0" @@ -5556,6 +7086,13 @@ __metadata: languageName: node linkType: hard +"tiny-typed-emitter@npm:^2.1.0": + version: 2.1.0 + resolution: "tiny-typed-emitter@npm:2.1.0" + checksum: 10c0/522bed4c579ee7ee16548540cb693a3d098b137496110f5a74bff970b54187e6b7343a359b703e33f77c5b4b90ec6cebc0d0ec3dbdf1bd418723c5c3ce36d8a2 + languageName: node + linkType: hard + "tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14": version: 0.2.14 resolution: "tinyglobby@npm:0.2.14" @@ -5566,6 +7103,22 @@ __metadata: languageName: node linkType: hard +"tmp-promise@npm:^3.0.2": + version: 3.0.3 + resolution: "tmp-promise@npm:3.0.3" + dependencies: + tmp: "npm:^0.2.0" + checksum: 10c0/23b47dcb2e82b14bbd8f61ed7a9d9353cdb6a6f09d7716616cfd27d0087040cd40152965a518e598d7aabe1489b9569bf1eebde0c5fadeaf3ec8098adcebea4e + languageName: node + linkType: hard + +"tmp@npm:^0.2.0": + version: 0.2.5 + resolution: "tmp@npm:0.2.5" + checksum: 10c0/cee5bb7d674bb4ba3ab3f3841c2ca7e46daeb2109eec395c1ec7329a91d52fcb21032b79ac25161a37b2565c4858fefab927af9735926a113ef7bac9091a6e0e + languageName: node + linkType: hard + "tmpl@npm:1.0.5": version: 1.0.5 resolution: "tmpl@npm:1.0.5" @@ -5582,6 +7135,15 @@ __metadata: languageName: node linkType: hard +"truncate-utf8-bytes@npm:^1.0.0": + version: 1.0.2 + resolution: "truncate-utf8-bytes@npm:1.0.2" + dependencies: + utf8-byte-length: "npm:^1.0.1" + checksum: 10c0/af2b431fc4314f119b551e5fccfad49d4c0ef82e13ba9ca61be6567801195b08e732ce9643542e8ad1b3df44f3df2d7345b3dd34f723954b6bb43a14584d6b3c + languageName: node + linkType: hard + "ts-api-utils@npm:^2.1.0": version: 2.1.0 resolution: "ts-api-utils@npm:2.1.0" @@ -5666,6 +7228,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^0.13.1": + version: 0.13.1 + resolution: "type-fest@npm:0.13.1" + checksum: 10c0/0c0fa07ae53d4e776cf4dac30d25ad799443e9eef9226f9fddbb69242db86b08584084a99885cfa5a9dfe4c063ebdc9aa7b69da348e735baede8d43f1aeae93b + languageName: node + linkType: hard + "type-fest@npm:^0.21.3": version: 0.21.3 resolution: "type-fest@npm:0.21.3" @@ -5673,6 +7242,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^2.17.0": + version: 2.19.0 + resolution: "type-fest@npm:2.19.0" + checksum: 10c0/a5a7ecf2e654251613218c215c7493574594951c08e52ab9881c9df6a6da0aeca7528c213c622bc374b4e0cb5c443aa3ab758da4e3c959783ce884c3194e12cb + languageName: node + linkType: hard + "type-fest@npm:^4.41.0": version: 4.41.0 resolution: "type-fest@npm:4.41.0" @@ -5733,7 +7309,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.9.2": +"typescript@npm:^5.3.3, typescript@npm:^5.9.2": version: 5.9.2 resolution: "typescript@npm:5.9.2" bin: @@ -5743,7 +7319,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.9.2#optional!builtin": +"typescript@patch:typescript@npm%3A^5.3.3#optional!builtin, typescript@patch:typescript@npm%3A^5.9.2#optional!builtin": version: 5.9.2 resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=cef18b" bin: @@ -5774,6 +7350,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04 + languageName: node + linkType: hard + "undici-types@npm:~7.10.0": version: 7.10.0 resolution: "undici-types@npm:7.10.0" @@ -5799,6 +7382,20 @@ __metadata: languageName: node linkType: hard +"universalify@npm:^0.1.0": + version: 0.1.2 + resolution: "universalify@npm:0.1.2" + checksum: 10c0/e70e0339f6b36f34c9816f6bf9662372bd241714dc77508d231d08386d94f2c4aa1ba1318614f92015f40d45aae1b9075cd30bd490efbe39387b60a76ca3f045 + languageName: node + linkType: hard + +"universalify@npm:^2.0.0": + version: 2.0.1 + resolution: "universalify@npm:2.0.1" + checksum: 10c0/73e8ee3809041ca8b818efb141801a1004e3fc0002727f1531f4de613ea281b494a40909596dae4a042a4fb6cd385af5d4db2e137b1362e0e91384b828effd3a + languageName: node + linkType: hard + "unrs-resolver@npm:^1.7.11": version: 1.11.1 resolution: "unrs-resolver@npm:1.11.1" @@ -5889,6 +7486,13 @@ __metadata: languageName: node linkType: hard +"utf8-byte-length@npm:^1.0.1": + version: 1.0.5 + resolution: "utf8-byte-length@npm:1.0.5" + checksum: 10c0/e69bda3299608f4cc75976da9fb74ac94801a58b9ca29fdad03a20ec952e7477d7f226c12716b5f36bd4cff8151d1d152d02ee1df3752f017d4b2c725ce3e47a + languageName: node + linkType: hard + "v8-to-istanbul@npm:^9.0.1": version: 9.3.0 resolution: "v8-to-istanbul@npm:9.3.0" @@ -5900,6 +7504,17 @@ __metadata: languageName: node linkType: hard +"verror@npm:^1.10.0": + version: 1.10.1 + resolution: "verror@npm:1.10.1" + dependencies: + assert-plus: "npm:^1.0.0" + core-util-is: "npm:1.0.2" + extsprintf: "npm:^1.2.0" + checksum: 10c0/293fb060a4c9b07965569a0c3e45efa954127818707995a8a4311f691b5d6687be99f972c759838ba6eecae717f9af28e3c49d2afc7bbdf5f0b675238f1426e8 + languageName: node + linkType: hard + "walker@npm:^1.0.8": version: 1.0.8 resolution: "walker@npm:1.0.8" @@ -6045,6 +7660,13 @@ __metadata: languageName: node linkType: hard +"xmlbuilder@npm:>=11.0.1, xmlbuilder@npm:^15.1.1": + version: 15.1.1 + resolution: "xmlbuilder@npm:15.1.1" + checksum: 10c0/665266a8916498ff8d82b3d46d3993913477a254b98149ff7cff060d9b7cc0db7cf5a3dae99aed92355254a808c0e2e3ec74ad1b04aa1061bdb8dfbea26c18b8 + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" @@ -6089,7 +7711,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.7.2": +"yargs@npm:^17.6.2, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: @@ -6104,6 +7726,16 @@ __metadata: languageName: node linkType: hard +"yauzl@npm:^2.10.0": + version: 2.10.0 + resolution: "yauzl@npm:2.10.0" + dependencies: + buffer-crc32: "npm:~0.2.3" + fd-slicer: "npm:~1.1.0" + checksum: 10c0/f265002af7541b9ec3589a27f5fb8f11cf348b53cc15e2751272e3c062cd73f3e715bc72d43257de71bbaecae446c3f1b14af7559e8ab0261625375541816422 + languageName: node + linkType: hard + "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0"