diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7c7dcef0..c395a501 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -122,10 +122,10 @@ jobs: APPLE_API_KEY_ID: ${{ secrets.api_key_id }} APPLE_API_ISSUER: ${{ secrets.api_key_issuer_id }} - - run: npx tsx script/e2e.mts 'dist/mac-arm64/LosslessCut.app/Contents/MacOS/LosslessCut' 0:none screenshot.jpeg + - run: node script/e2e.mts 'dist/mac-arm64/LosslessCut.app/Contents/MacOS/LosslessCut' 0:none screenshot.jpeg if: startsWith(matrix.os, 'macos') - - run: npx tsx script/e2e.mts 'dist\win-unpacked\LosslessCut.exe' desktop screenshot.jpeg + - run: node script/e2e.mts 'dist\win-unpacked\LosslessCut.exe' desktop screenshot.jpeg if: startsWith(matrix.os, 'windows') - run: | @@ -133,13 +133,13 @@ jobs: sudo Xvfb -ac :0 -screen 0 1280x1024x24 > /dev/null 2>&1 & sleep 5 chmod +x dist/linux-unpacked/losslesscut - npx tsx script/e2e.mts 'dist/linux-unpacked/losslesscut' ':0.0+0,0' screenshot.jpeg + node script/e2e.mts 'dist/linux-unpacked/losslesscut' ':0.0+0,0' screenshot.jpeg if: startsWith(matrix.os, 'ubuntu') - name: (MacOS) Upload to Mac App Store if: startsWith(matrix.os, 'macos') && env.is_tag == 'true' run: | - npx tsx script/xcrunWrapper.mts dist/mas-universal/LosslessCut-mac-universal.pkg ${{ secrets.api_key_id }} ${{ secrets.api_key_issuer_id }} 1505323402 no.mifi.losslesscut-mac + node script/xcrunWrapper.mts dist/mas-universal/LosslessCut-mac-universal.pkg ${{ secrets.api_key_id }} ${{ secrets.api_key_issuer_id }} 1505323402 no.mifi.losslesscut-mac - name: (MacOS) Upload artifacts uses: actions/upload-artifact@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c34bc831..d09c0b3c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,6 +33,7 @@ jobs: yarn generate-docs git diff --quiet HEAD git reset --hard HEAD + - run: yarn check-licenses - name: Generate licenses run: | yarn generate-licenses diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index abecd750..9c069b06 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,7 +72,7 @@ Before releasing, consider [Maintainence chores](#maintainence-chores) first. - `git merge stores` (in case there's an old unmerged stores hotfix) - **Prepare release notes** from commit history - Create a new file `versions/x.y.z.md` and write the most important highlights from the release notes, but **remove github issue #references** -- `tsx script/generateVersions.mts && git add versions/*.md src/renderer/src/versions.json && git commit -m 'Update change log'` +- `node script/generateVersions.mts && git add versions/*.md src/renderer/src/versions.json && git commit -m 'Update change log'` - *If Store-only hotfix release* - `git checkout stores` - `npm version patch` @@ -157,12 +157,6 @@ Links: yarn scan-i18n ``` -### Generate license summary - -```bash -npx license-checker --summary -``` - ### Regenerate licenses file ```bash diff --git a/electron.vite.config.ts b/electron.vite.config.ts index 5e0dbf9b..3ce60534 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -1,24 +1,27 @@ -import { defineConfig, externalizeDepsPlugin } from 'electron-vite'; +import { defineConfig } from 'electron-vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ main: { - // https://electron-vite.org/guide/dev#dependencies-vs-devdependencies - // For the main process and preload, the best practice is to externalize dependencies and only bundle our own code. - // However, until we use ESM for electron main, we need to include ESM-only deps in the bundle: (exclude from externalize) - plugins: [externalizeDepsPlugin({ exclude: ['p-map', 'execa', 'nanoid', 'file-type'] })], build: { + // https://electron-vite.org/guide/dev#dependencies-vs-devdependencies + // For the main process and preload, the best practice is to externalize dependencies and only bundle our own code. + externalizeDeps: true, target: 'node22.18', sourcemap: true, }, }, preload: { - // https://electron-vite.org/guide/dev#dependencies-vs-devdependencies - plugins: [externalizeDepsPlugin({ exclude: [] })], build: { + externalizeDeps: true, target: 'node22.18', sourcemap: true, + rollupOptions: { + output: { + format: 'cjs', + }, + }, }, }, renderer: { diff --git a/i18next.config.ts b/i18next.config.ts index f87aa0c6..a2a689d1 100644 --- a/i18next.config.ts +++ b/i18next.config.ts @@ -1,7 +1,8 @@ // eslint-disable-next-line import/no-extraneous-dependencies import { defineConfig } from 'i18next-cli'; -import { langNames, mapLang, SupportedLanguage } from './src/common/i18n.js'; +import type { SupportedLanguage } from './src/common/i18n.js'; +import { langNames, mapLang } from './src/common/i18n.js'; import configBase from './i18next.config.base.js'; export default defineConfig({ diff --git a/package.json b/package.json index 7ffdd736..3807b6c6 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "version": "3.67.2", "main": "./out/main/index.js", "homepage": "./", + "type": "module", "scripts": { "clean": "rimraf dist out common-ts-dist main-ts-dist build-resources icon-build", "start": "electron-vite preview", @@ -22,12 +23,13 @@ "pack-mas-dev": "yarn build && electron-builder --mac mas-dev -c.mas.provisioningProfile=LosslessCut_Dev.provisionprofile -c.mas.identity='Mikael Finstad (JH4PH8B3C8)'", "pack-win": "yarn build && electron-builder --win zip --x64", "postinstall": "electron-builder install-app-deps", - "version": "tsx script/postversion.mts && git add no.mifi.losslesscut.appdata.xml", + "version": "node script/postversion.mts && git add no.mifi.losslesscut.appdata.xml", "pack-linux": "yarn build && electron-builder --linux", "scan-i18n": "i18next-cli -c i18next.config.scan.ts extract", - "generate-icon": "mkdirp icon-build build-resources/appx && tsx script/generateIcon.mts", - "generate-licenses": "yarn licenses generate-disclaimer > licenses.txt && echo '\n\nffmpeg is licensed under GPL v2+:\n\nhttp://www.gnu.org/licenses/old-licenses/gpl-2.0.html' >> licenses.txt", - "generate-docs": "tsx script/generateDocs.mts" + "generate-icon": "mkdirp icon-build build-resources/appx && node script/generateIcon.mts", + "generate-licenses": "yarn licenses generate-disclaimer -R > licenses.txt && echo '\n\nffmpeg is licensed under GPL v2+:\n\nhttp://www.gnu.org/licenses/old-licenses/gpl-2.0.html' >> licenses.txt", + "generate-docs": "node script/generateDocs.mts", + "check-licenses": "node script/checkLicenses.mts" }, "author": { "name": "Mikael Finstad", @@ -87,7 +89,7 @@ "electron": "^38.3.0", "electron-builder": "26.0.12", "electron-devtools-installer": "^4.0.0", - "electron-vite": "^2.3.0", + "electron-vite": "^5.0.0", "eslint": "^8.2.0", "eslint-config-mifi": "^0.0.3", "eslint-plugin-import": "^2.25.3", @@ -131,13 +133,12 @@ "sweetalert2-react-content": "^5.0.7", "tiny-invariant": "^1.3.3", "ts-morph": "^27.0.2", - "tsx": "^4.7.1", "type-fest": "^4.23.0", "typescript": "^5.9.3", "use-debounce": "^5.1.0", "use-trace-update": "^1.3.0", - "vite": "^6.4.1", - "vitest": "^3.0.8" + "vite": "^7.3.0", + "vitest": "^4.0.16" }, "dependencies": { "@electron/remote": "^2.1.3", @@ -149,7 +150,6 @@ "express": "^4.20.0", "express-async-handler": "^1.2.0", "file-type": "patch:file-type@npm%3A19.4.1#~/.yarn/patches/file-type-npm-19.4.1-d18086444c.patch", - "fs-extra": "^8.1.0", "i18next": "^25.6.1", "i18next-fs-backend": "^2.3.2", "json5": "^2.2.2", diff --git a/script/checkLicenses.mts b/script/checkLicenses.mts new file mode 100644 index 00000000..cb9f219d --- /dev/null +++ b/script/checkLicenses.mts @@ -0,0 +1,91 @@ +import { execa } from 'execa'; + +const { stdout } = await execa('yarn', ['licenses', 'list', '-R', '--json'], { encoding: 'utf8' }); + +const licensesJson: { value: string; children: Record }[] = JSON.parse(`[${stdout.split('\n').join(',')}]`); + +const safeLicenses: Record = { + // These aim to remove almost all restrictions + 'CC0-1.0': true, + Unlicense: true, + WTFPL: true, + '0BSD': true, + + // Permissive licenses: These impose minimal requirements (mostly attribution + license notice). You can generally use them interchangeably in commercial and proprietary software. + MIT: true, + 'BSD-2-Clause': true, + 'BSD-3-Clause': true, + ISC: true, + Zlib: true, + 'Python-2.0': true, + 'BlueOak-1.0.0': true, + + // Permissive licenses with some conditions + 'Apache-2.0': true, + + // Copyleft licenses: These require that derivative works be distributed under the same license terms. They ensure that modifications remain open source. + // which is OK because LosslessCut is also GPL-2.0-only + 'GPL-2.0-only': ['lossless-cut'], + // Weak copyleft licenses: These allow linking with proprietary software under certain conditions, making them more flexible than strong copyleft licenses. + 'LGPL-3.0-only': true, + 'MPL-2.0': true, + + // Special purpose licenses + 'Hippocratic-2.1': ['@react-leaflet/core', 'react-leaflet'], + + // not software licenses + 'CC-BY-3.0': ['spdx-exceptions'], // eslint-plugin-unicorn + 'CC-BY-4.0': ['caniuse-lite'], + + UNKNOWN: ['fast-shallow-equal', 'react-universal-interface'], +}; + +const unsafeLicenses = licensesJson.flatMap((l) => { + const checkLicense = (license: string) => { + const safeLicense = safeLicenses[license]; + if (safeLicense === true) { + return true; + } + if (safeLicense == null) { + return false; + } + return Object.keys(l.children).every((pkg) => ( + safeLicense.some((safeLicensePackage) => pkg.startsWith(safeLicensePackage)) + )); + }; + + // e.g. "(BSD-2-Clause OR MIT OR Apache-2.0)" + // e.g. "(LGPL-3.0-only AND MIT)" + const trimmed = l.value.replace(/^\(/, '').replace(/\)$/, ''); + + const isOr = l.value.includes(' OR '); + const isAnd = l.value.includes(' AND '); + + if (isOr || isAnd) { + const licenses = trimmed.split(isOr ? ' OR ' : ' AND ').map((s) => s.trim()); + + if (isOr) { + return licenses.some((license) => checkLicense(license)) ? [] : [l]; + } + if (isAnd) { + return licenses.every((license) => checkLicense(license)) ? [] : [l]; + } + } + + return checkLicense(trimmed) ? [] : [l]; +}); + + +if (unsafeLicenses.length > 0) { + console.error('Found unsafe licenses:'); + console.error(); + + for (const l of unsafeLicenses) { + console.error(l.value); + console.error(`${Object.keys(l.children).map((v) => `- ${v}`).join('\n')}`); + console.error(); + } + process.exitCode = 1; +} else { + console.log('All licenses are safe.'); +} diff --git a/src/common/types.ts b/src/common/types.ts index 0abd737f..cb2c0a93 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -1,4 +1,4 @@ -import { SupportedLanguage } from './i18n'; +import type { SupportedLanguage } from './i18n.ts'; export type KeyboardAction = 'addSegment' | 'togglePlayResetSpeed' | 'togglePlayNoResetSpeed' | 'reducePlaybackRate' | 'reducePlaybackRateMore' | 'increasePlaybackRate' | 'increasePlaybackRateMore' | 'timelineToggleComfortZoom' | 'seekPreviousFrame' | 'seekNextFrame' | 'captureSnapshot' | 'captureSnapshotToClipboard' | 'setCutStart' | 'setCutEnd' | 'removeCurrentSegment' | 'removeCurrentCutpoint' | 'cleanupFilesDialog' | 'splitCurrentSegment' | 'focusSegmentAtCursor' | 'selectSegmentsAtCursor' | 'increaseRotation' | 'goToTimecode' | 'seekBackwards' | 'seekBackwards2' | 'seekBackwards3' | 'seekBackwardsPercent' | 'seekBackwardsPercent' | 'seekBackwardsKeyframe' | 'jumpCutStart' | 'seekForwards' | 'seekForwards2' | 'seekForwards3' | 'seekForwardsPercent' | 'seekForwardsPercent' | 'seekForwardsKeyframe' | 'jumpCutEnd' | 'jumpTimelineStart' | 'jumpTimelineEnd' | 'jumpFirstSegment' | 'jumpPrevSegment' | 'jumpSeekFirstSegment' | 'jumpSeekPrevSegment' | 'timelineZoomIn' | 'timelineZoomIn' | 'batchPreviousFile' | 'jumpLastSegment' | 'jumpNextSegment' | 'jumpSeekLastSegment' | 'jumpSeekNextSegment' | 'timelineZoomOut' | 'timelineZoomOut' | 'batchNextFile' | 'batchOpenSelectedFile' | 'batchOpenPreviousFile' | 'batchOpenNextFile' | 'undo' | 'undo' | 'redo' | 'redo' | 'copySegmentsToClipboard' | 'copySegmentsToClipboard' | 'toggleFullscreenVideo' | 'labelCurrentSegment' | 'export' | 'toggleKeyboardShortcuts' | 'increaseVolume' | 'decreaseVolume' | 'toggleMuted' | 'detectBlackScenes' | 'detectSilentScenes' | 'detectSceneChanges' | 'toggleLastCommands' | 'play' | 'pause' | 'reloadFile' | 'html5ify' | 'makeCursorTimeZero' | 'togglePlayOnlyCurrentSegment' | 'toggleLoopOnlyCurrentSegment' | 'toggleLoopStartEndOnlyCurrentSegment' | 'togglePlaySelectedSegments' | 'toggleLoopSelectedSegments' | 'editCurrentSegmentTags' | 'duplicateCurrentSegment' | 'reorderSegsByStartTime' | 'invertAllSegments' | 'fillSegmentsGaps' | 'shiftAllSegmentTimes' | 'alignSegmentTimesToKeyframes' | 'readAllKeyframes' | 'createSegmentsFromKeyframes' | 'createFixedDurationSegments' | 'createNumSegments' | 'createFixedByteSizedSegments' | 'createRandomSegments' | 'shuffleSegments' | 'combineOverlappingSegments' | 'combineSelectedSegments' | 'clearSegments' | 'toggleSegmentsList' | 'selectOnlyCurrentSegment' | 'deselectAllSegments' | 'selectAllSegments' | 'toggleCurrentSegmentSelected' | 'invertSelectedSegments' | 'removeSelectedSegments' | 'toggleStreamsSelector' | 'extractAllStreams' | 'showStreamsSelector' | 'showIncludeExternalStreamsDialog' | 'captureSnapshotAsCoverArt' | 'extractCurrentSegmentFramesAsImages' | 'extractSelectedSegmentsFramesAsImages' | 'convertFormatBatch' | 'convertFormatCurrentFile' | 'fixInvalidDuration' | 'closeBatch' | 'concatBatch' | 'toggleKeyframeCutMode' | 'toggleCaptureFormat' | 'toggleStripAudio' | 'toggleStripVideo' | 'toggleStripSubtitle' | 'toggleStripThumbnail' | 'toggleStripCurrentFilter' | 'toggleStripAll' | 'toggleDarkMode' | 'setStartTimeOffset' | 'toggleWaveformMode' | 'toggleShowThumbnails' | 'toggleShowKeyframes' | 'toggleSettings' | 'openSendReportDialog' | 'openFilesDialog' | 'openDirDialog' | 'exportYouTube' | 'closeCurrentFile' | 'quit' | 'selectAllMarkers' | 'generateOverviewWaveform'; diff --git a/src/main/aboutPanel.ts b/src/main/aboutPanel.ts index f6a3d872..7efed0c2 100644 --- a/src/main/aboutPanel.ts +++ b/src/main/aboutPanel.ts @@ -1,5 +1,6 @@ +import type { AboutPanelOptionsOptions } from 'electron'; // eslint-disable-next-line import/no-extraneous-dependencies -import { AboutPanelOptionsOptions, app } from 'electron'; +import { app } from 'electron'; import { appName, copyrightYear } from './common.js'; import { isLinux } from './util.js'; diff --git a/src/main/configStore.ts b/src/main/configStore.ts index 3fe19e97..e866728c 100644 --- a/src/main/configStore.ts +++ b/src/main/configStore.ts @@ -2,13 +2,12 @@ import Store from 'electron-store'; // eslint-disable-next-line import/no-extraneous-dependencies import electron from 'electron'; import { join, dirname } from 'node:path'; -import { pathExists } from 'fs-extra'; import assert from 'node:assert'; import { copyFile } from 'node:fs/promises'; -import { KeyBinding, Config } from '../common/types.js'; +import type { KeyBinding, Config } from '../common/types.js'; import logger from './logger.js'; -import { isWindows } from './util.js'; +import { isWindows, pathExists } from './util.js'; import { fallbackLng } from './i18nCommon.js'; const { app } = electron; diff --git a/src/main/contextMenu.ts b/src/main/contextMenu.ts index d757085c..0d6d3a13 100644 --- a/src/main/contextMenu.ts +++ b/src/main/contextMenu.ts @@ -1,5 +1,6 @@ +import type { BrowserWindow } from 'electron'; // eslint-disable-next-line import/no-extraneous-dependencies -import { BrowserWindow, Menu } from 'electron'; +import { Menu } from 'electron'; // https://github.com/electron/electron/issues/4068#issuecomment-274159726 export default (window: BrowserWindow) => { diff --git a/src/main/ffmpeg.ts b/src/main/ffmpeg.ts index 11654156..10ac685f 100644 --- a/src/main/ffmpeg.ts +++ b/src/main/ffmpeg.ts @@ -1,14 +1,15 @@ import { join } from 'node:path'; import readline from 'node:readline'; import stringToStream from 'string-to-stream'; -import { execa, Options as ExecaOptions, ResultPromise } from 'execa'; +import type { Options as ExecaOptions, ResultPromise } from 'execa'; +import { execa } from 'execa'; import assert from 'node:assert'; -import { Readable } from 'node:stream'; +import type { Readable } from 'node:stream'; // eslint-disable-next-line import/no-extraneous-dependencies import { app, clipboard, nativeImage } from 'electron'; import { platform, arch, isWindows, isLinux } from './util.js'; -import { CaptureFormat, Waveform } from '../common/types.js'; +import type { CaptureFormat, Waveform } from '../common/types.js'; import isDev from './isDev.js'; import logger from './logger.js'; import { parseFfmpegProgressLine } from './progress.js'; diff --git a/src/main/i18nCommon.ts b/src/main/i18nCommon.ts index ac907426..11508767 100644 --- a/src/main/i18nCommon.ts +++ b/src/main/i18nCommon.ts @@ -3,9 +3,10 @@ // eslint-disable-next-line import/no-extraneous-dependencies import { app } from 'electron'; import { join } from 'node:path'; -import { InitOptions } from 'i18next'; +import type { InitOptions } from 'i18next'; -import { mapLang, SupportedLanguage } from '../common/i18n'; +import type { SupportedLanguage } from '../common/i18n'; +import { mapLang } from '../common/i18n'; let customLocalesPath: string | undefined; diff --git a/src/main/index.ts b/src/main/index.ts index 1a0877e0..06a4ac47 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -3,64 +3,40 @@ process.traceProcessWarnings = true; /* eslint-disable import/first */ // eslint-disable-next-line import/no-extraneous-dependencies -import electron, { BrowserWindow, BrowserWindowConstructorOptions, nativeTheme, shell, app, ipcMain, Notification, NotificationConstructorOptions } from 'electron'; +import electron, { BrowserWindow, type BrowserWindowConstructorOptions, nativeTheme, shell, app, ipcMain, Notification, type NotificationConstructorOptions } from 'electron'; import i18n from 'i18next'; import debounce from 'lodash.debounce/index.js'; import yargsParser from 'yargs-parser'; import JSON5 from 'json5'; -import remote from '@electron/remote/main'; +import remote from '@electron/remote/main/index.js'; import { stat } from 'node:fs/promises'; import assert from 'node:assert'; import timers from 'node:timers/promises'; import { z } from 'zod'; +import { pathToFileURL } from 'node:url'; +import electronUnhandled from 'electron-unhandled'; +import { fileTypeFromFile } from 'file-type/node'; import logger from './logger.js'; import menu from './menu.js'; import * as configStore from './configStore.js'; -import { isWindows } from './util.js'; +import { isLinux, isWindows, isMac, platform, arch, pathExists } from './util.js'; import { appName } from './common.js'; import attachContextMenu from './contextMenu.js'; import HttpServer from './httpServer.js'; import isDev from './isDev.js'; import isStoreBuild from './isStoreBuild.js'; import { getAboutPanelOptions } from './aboutPanel.js'; - import { checkNewVersion } from './updateChecker.js'; - import * as i18nCommon from './i18nCommon.js'; - import './i18n.js'; -import { ApiActionRequest } from '../common/types.js'; - -export * as ffmpeg from './ffmpeg.js'; - -export * as i18n from './i18nCommon.js'; - -export * as compatPlayer from './compatPlayer.js'; - -export * as configStore from './configStore.js'; - -export { isLinux, isWindows, isMac, platform, arch } from './util.js'; - -export { pathToFileURL } from 'node:url'; - -export { downloadMediaUrl } from './ffmpeg.js'; +import type { ApiActionRequest } from '../common/types.js'; +import * as ffmpeg from './ffmpeg.js'; +import * as compatPlayer from './compatPlayer.js'; +import { downloadMediaUrl } from './ffmpeg.js'; -const electronUnhandled = import('electron-unhandled'); -export const fileTypePromise = import('file-type/node'); - -// eslint-disable-next-line unicorn/prefer-top-level-await -(async () => { - try { - (await electronUnhandled).default({ showDialog: true, logger: (err) => logger.error('electron-unhandled', err) }); - } catch (err) { - logger.error(err); - } -})(); - -// eslint-disable-next-line unicorn/prefer-export-from -export { isDev }; +electronUnhandled({ showDialog: true, logger: (err) => logger.error('electron-unhandled', err) }); // https://chromestatus.com/feature/5748496434987008 // https://peter.sh/experiments/chromium-command-line-switches/ @@ -243,7 +219,6 @@ const argv = parseCliArgs(); const lossyModeSchema = z.object({ videoEncoder: z.union([z.literal('libx264'), z.literal('libx265'), z.literal('libsvtav1')]) }); // eslint-disable-next-line prefer-destructuring const lossyMode = argv['lossyMode'] ? lossyModeSchema.parse(JSON5.parse(argv['lossyMode'])) : undefined; -export { lossyMode }; export type LossyMode = z.infer; @@ -258,86 +233,13 @@ function safeRequestSingleInstanceLock(additionalData: Record) return app.requestSingleInstanceLock(additionalData); } -function initApp() { - // On macOS, the system enforces single instance automatically when users try to open a second instance of your app in Finder, and the open-file and open-url events will be emitted for that. - // However when users start your app in command line, the system's single instance mechanism will be bypassed, and you have to use this method to ensure single instance. - // This can be tested with one terminal: npx electron . - // and another terminal: npx electron . path/to/file.mp4 - app.on('second-instance', (_event, _commandLine, _workingDirectory, additionalData) => { - // Someone tried to run a second instance, we should focus our window. - if (mainWindow) { - if (mainWindow.isMinimized()) mainWindow.restore(); - mainWindow.focus(); - } - - if (!(additionalData != null && typeof additionalData === 'object' && 'argv' in additionalData) || !Array.isArray(additionalData.argv)) return; - - const argv2 = parseCliArgs(additionalData.argv); - - logger.info('second-instance', argv2); - - if (argv2._ && argv2._.length > 0) openFilesEventually(argv2._.map(String)); - else if (argv2['keyboardAction']) sendApiAction(argv2['keyboardAction']); - }); - - // Quit when all windows are closed. - app.on('window-all-closed', () => { - app.quit(); - }); - - app.on('activate', () => { - // On OS X it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (mainWindow === null) { - createWindow(); - } - }); - - ipcMain.on('renderer-ready', () => { - rendererReady = true; - if (filesToOpen.length > 0) openFiles(filesToOpen); - }); - - // Mac OS open with LosslessCut - // Emitted when the user wants to open a file with the application. The open-file event is usually emitted when the application is already open and the OS wants to reuse the application to open the file. - app.on('open-file', (event, path) => { - openFilesEventually([path]); - event.preventDefault(); // recommended in docs https://www.electronjs.org/docs/latest/api/app#event-open-file-macos - }); - - ipcMain.on('setAskBeforeClose', (_e, val) => { - askBeforeClose = val; - }); - - ipcMain.on('setLanguage', (_e, language) => { - i18n.changeLanguage(language).then(() => updateMenu()).catch((err) => logger.error('Failed to set language', err)); - }); - - ipcMain.handle('tryTrashItem', async (_e, path) => { - try { - await stat(path); - } catch (err) { - if (err instanceof Error && 'code' in err && err.code === 'ENOENT') return; - } - await shell.trashItem(path); - }); - - ipcMain.handle('showItemInFolder', (_e, path) => shell.showItemInFolder(path)); - - ipcMain.on('apiActionResponse', (_e, { id }) => { - apiActionRequests.get(id)?.(); - }); -} - - // This promise will be fulfilled when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. // Call this immediately, to make sure we don't miss it (race condition) const readyPromise = app.whenReady(); -// eslint-disable-next-line unicorn/prefer-top-level-await -(async () => { +async function init() { try { logger.info('LosslessCut version', app.getVersion(), { isDev }); await configStore.init({ customConfigDir: argv['configDir'] }); @@ -351,7 +253,74 @@ const readyPromise = app.whenReady(); return; } - initApp(); + // On macOS, the system enforces single instance automatically when users try to open a second instance of your app in Finder, and the open-file and open-url events will be emitted for that. + // However when users start your app in command line, the system's single instance mechanism will be bypassed, and you have to use this method to ensure single instance. + // This can be tested with one terminal: npx electron . + // and another terminal: npx electron . path/to/file.mp4 + app.on('second-instance', (_event, _commandLine, _workingDirectory, additionalData) => { + // Someone tried to run a second instance, we should focus our window. + if (mainWindow) { + if (mainWindow.isMinimized()) mainWindow.restore(); + mainWindow.focus(); + } + + if (!(additionalData != null && typeof additionalData === 'object' && 'argv' in additionalData) || !Array.isArray(additionalData.argv)) return; + + const argv2 = parseCliArgs(additionalData.argv); + + logger.info('second-instance', argv2); + + if (argv2._ && argv2._.length > 0) openFilesEventually(argv2._.map(String)); + else if (argv2['keyboardAction']) sendApiAction(argv2['keyboardAction']); + }); + + // Quit when all windows are closed. + app.on('window-all-closed', () => { + app.quit(); + }); + + app.on('activate', () => { + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (mainWindow === null) { + createWindow(); + } + }); + + ipcMain.on('renderer-ready', () => { + rendererReady = true; + if (filesToOpen.length > 0) openFiles(filesToOpen); + }); + + // Mac OS open with LosslessCut + // Emitted when the user wants to open a file with the application. The open-file event is usually emitted when the application is already open and the OS wants to reuse the application to open the file. + app.on('open-file', (event, path) => { + openFilesEventually([path]); + event.preventDefault(); // recommended in docs https://www.electronjs.org/docs/latest/api/app#event-open-file-macos + }); + + ipcMain.on('setAskBeforeClose', (_e, val) => { + askBeforeClose = val; + }); + + ipcMain.on('setLanguage', (_e, language) => { + i18n.changeLanguage(language).then(() => updateMenu()).catch((err) => logger.error('Failed to set language', err)); + }); + + ipcMain.handle('tryTrashItem', async (_e, path) => { + try { + await stat(path); + } catch (err) { + if (err instanceof Error && 'code' in err && err.code === 'ENOENT') return; + } + await shell.trashItem(path); + }); + + ipcMain.handle('showItemInFolder', (_e, path) => shell.showItemInFolder(path)); + + ipcMain.on('apiActionResponse', (_e, { id }) => { + apiActionRequests.get(id)?.(); + }); logger.info('Waiting for app to become ready'); await readyPromise; @@ -403,9 +372,9 @@ const readyPromise = app.whenReady(); } catch (err) { logger.error('Failed to initialize', err); } -})(); +} -export function focusWindow() { +function focusWindow() { try { app.focus({ steal: true }); } catch (err) { @@ -413,18 +382,55 @@ export function focusWindow() { } } -export function quitApp() { +function quitApp() { // allow HTTP API to respond etc. timers.setTimeout(1000).then(() => electron.app.quit()); } -export const hasDisabledNetworking = () => !!disableNetworking; +const hasDisabledNetworking = () => !!disableNetworking; -export const setProgressBar = (v: number) => mainWindow?.setProgressBar(v); +const setProgressBar = (v: number) => mainWindow?.setProgressBar(v); -export function sendOsNotification(options: NotificationConstructorOptions) { +function sendOsNotification(options: NotificationConstructorOptions) { if (!Notification.isSupported()) return; const notification = new Notification(options); notification.on('failed', (_e, error) => logger.warn('Notification failed', error)); notification.show(); } + +const remoteApi = { + ffmpeg, + i18n: i18nCommon, + compatPlayer, + configStore, + isLinux, + isWindows, + isMac, + platform, + arch, + pathExists, + pathToFileURL, + downloadMediaUrl, + fileTypeFromFile, + isDev, + lossyMode, + focusWindow, + quitApp, + hasDisabledNetworking, + setProgressBar, + sendOsNotification, +}; + +export type RemoteApi = typeof remoteApi; + +// @ts-expect-error don't know how to type +app.addListener('remote-require', (event: { returnValue: RemoteApi }, _webContents: unknown, moduleName: string) => { + if (moduleName === './index.js') { + // eslint-disable-next-line no-param-reassign + event.returnValue = remoteApi; + } +}); + +// cannot top level await because app.whenReady will hang forever +// eslint-disable-next-line unicorn/prefer-top-level-await +init(); diff --git a/src/main/menu.ts b/src/main/menu.ts index ee59e1b3..4f04dfe9 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -1,5 +1,6 @@ +import type { BrowserWindow, MenuItem, MenuItemConstructorOptions } from 'electron'; // eslint-disable-next-line import/no-extraneous-dependencies -import electron, { BrowserWindow, MenuItem, MenuItemConstructorOptions } from 'electron'; +import electron from 'electron'; import { t } from 'i18next'; import { homepageUrl, getReleaseUrl, licensesUrl, thanksUrl, usageUrl, faqUrl, troubleshootingUrl, featureRequestUrl } from '../common/constants.js'; diff --git a/src/main/util.ts b/src/main/util.ts index 9c3f1da7..c85814bb 100644 --- a/src/main/util.ts +++ b/src/main/util.ts @@ -1,3 +1,4 @@ +import { access, constants } from 'node:fs/promises'; import os from 'node:os'; export const platform = os.platform(); @@ -6,3 +7,12 @@ export const arch = os.arch(); export const isWindows = platform === 'win32'; export const isMac = platform === 'darwin'; export const isLinux = platform === 'linux'; + +export async function pathExists(path: string) { + try { + await access(path, constants.F_OK); + return true; + } catch { + return false; + } +} diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index efcd50d3..41dee390 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -1,4 +1,5 @@ -import { memo, useEffect, useState, useCallback, useRef, useMemo, CSSProperties, ReactEventHandler, FocusEventHandler, DragEventHandler } from 'react'; +import type { CSSProperties, ReactEventHandler, FocusEventHandler, DragEventHandler } from 'react'; +import { memo, useEffect, useState, useCallback, useRef, useMemo } from 'react'; import { FaAngleLeft, FaRegTimesCircle } from 'react-icons/fa'; import { MdRotate90DegreesCcw } from 'react-icons/md'; import { AnimatePresence, MotionConfig } from 'framer-motion'; @@ -6,12 +7,12 @@ import i18n from 'i18next'; import { useTranslation } from 'react-i18next'; import { produce } from 'immer'; import screenfull from 'screenfull'; -import { IpcRendererEvent } from 'electron'; +import type { IpcRendererEvent } from 'electron'; import fromPairs from 'lodash/fromPairs'; import sum from 'lodash/sum'; import invariant from 'tiny-invariant'; -import { SweetAlertOptions } from 'sweetalert2'; +import type { SweetAlertOptions } from 'sweetalert2'; import useTimelineScroll from './hooks/useTimelineScroll'; import useUserSettingsRoot from './hooks/useUserSettingsRoot'; @@ -24,7 +25,8 @@ import useFrameCapture from './hooks/useFrameCapture'; import useSegments from './hooks/useSegments'; import useDirectoryAccess from './hooks/useDirectoryAccess'; -import { UserSettingsContext, SegColorsContext, UserSettingsContextType, AppContext, AppContextType, SegColorsContextType } from './contexts'; +import type { UserSettingsContextType, AppContextType, SegColorsContextType } from './contexts'; +import { UserSettingsContext, SegColorsContext, AppContext } from './contexts'; import NoFileLoaded from './NoFileLoaded'; import MediaSourcePlayer from './MediaSourcePlayer'; @@ -49,6 +51,8 @@ import * as Dialog from './components/Dialog'; import { loadMifiLink, runStartupCheck } from './mifi'; import { darkModeTransition } from './colors'; import { getSegColor } from './util/colors'; +import type { + FileFfprobeMeta } from './ffmpeg'; import { getStreamFps, isCuttingStart, isCuttingEnd, readFileFfprobeMeta, getDefaultOutFormat, @@ -58,7 +62,6 @@ import { RefuseOverwriteError, extractSubtitleTrackToSegments, mapRecommendedDefaultFormat, getFfCommandLine, - FileFfprobeMeta, } from './ffmpeg'; import { shouldCopyStreamByDefault, getAudioStreams, getRealVideoStreams, isAudioDefinitelyNotSupported, willPlayerProperlyHandleVideo, doesPlayerSupportHevcPlayback, getSubtitleStreams, enableVideoTrack, enableAudioTrack, canHtml5PlayerPlayStreams, isMatroska } from './util/streams'; import { exportEdlFile, readEdlFile, loadLlcProject, askForEdlImport } from './edlStore'; @@ -79,16 +82,19 @@ import { import getSwal, { errorToast, showPlaybackFailedMessage } from './swal'; import { adjustRate } from './util/rate-calculator'; import { askExtractFramesAsImages } from './dialogs/extractFrames'; -import { askForOutDir, askForImportChapters, askForFileOpenAction, showDiskFull, showExportFailedDialog, showConcatFailedDialog, openYouTubeChaptersDialog, showRefuseToOverwrite, showOpenDialog, showMuxNotSupported, promptDownloadMediaUrl, CleanupChoicesType, showOutputNotWritable, deleteFiles, mustDisallowVob, toastError } from './dialogs'; +import type { CleanupChoicesType } from './dialogs'; +import { askForOutDir, askForImportChapters, askForFileOpenAction, showDiskFull, showExportFailedDialog, showConcatFailedDialog, openYouTubeChaptersDialog, showRefuseToOverwrite, showOpenDialog, showMuxNotSupported, promptDownloadMediaUrl, showOutputNotWritable, deleteFiles, mustDisallowVob, toastError } from './dialogs'; import { openSendReportDialog } from './reporting'; import { sortSegments, convertSegmentsToChaptersWithGaps, hasAnySegmentOverlap, isDurationValid, getPlaybackAction, getSegmentTags, filterNonMarkers, isInitialSegment } from './segments'; -import { generateCutFileNames as generateCutFileNamesRaw, generateCutMergedFileNames as generateCutMergedFileNamesRaw, generateMergedFileNames as generateMergedFileNamesRaw, defaultCutFileTemplate, defaultCutMergedFileTemplate, defaultMergedFileTemplate, GenerateMergedOutFileNamesParams, GeneratedOutFileNames } from './util/outputNameTemplate'; +import type { GenerateMergedOutFileNamesParams, GeneratedOutFileNames } from './util/outputNameTemplate'; +import { generateCutFileNames as generateCutFileNamesRaw, generateCutMergedFileNames as generateCutMergedFileNamesRaw, generateMergedFileNames as generateMergedFileNamesRaw, defaultCutFileTemplate, defaultCutMergedFileTemplate, defaultMergedFileTemplate } from './util/outputNameTemplate'; import { rightBarWidth, leftBarWidth, ffmpegExtractWindow, zoomMax } from './util/constants'; import BigWaveform from './components/BigWaveform'; -import { BatchFile, Chapter, CustomTagsByFile, EdlExportType, EdlFileType, EdlImportType, FfmpegCommandLog, FilesMeta, FileStats, goToTimecodeDirectArgsSchema, openFilesActionArgsSchema, ParamsByStreamId, PlaybackMode, SegmentBase, SegmentColorIndex, SegmentTags, StateSegment, TunerType } from './types'; -import { CaptureFormat, KeyboardAction, ApiActionRequest } from '../../common/types.js'; -import { FFprobeChapter, FFprobeStream } from '../../common/ffprobe.js'; +import type { BatchFile, Chapter, CustomTagsByFile, EdlExportType, EdlFileType, EdlImportType, FfmpegCommandLog, FilesMeta, FileStats, ParamsByStreamId, PlaybackMode, SegmentBase, SegmentColorIndex, SegmentTags, StateSegment, TunerType } from './types'; +import { goToTimecodeDirectArgsSchema, openFilesActionArgsSchema } from './types'; +import type { CaptureFormat, KeyboardAction, ApiActionRequest } from '../../common/types.js'; +import type { FFprobeChapter, FFprobeStream } from '../../common/ffprobe.js'; import useLoading from './hooks/useLoading'; import useVideo from './hooks/useVideo'; import useTimecode from './hooks/useTimecode'; @@ -107,11 +113,10 @@ import useHtml5ify from './hooks/useHtml5ify'; import WhatsNew from './components/WhatsNew'; const electron = window.require('electron'); -const { exists } = window.require('fs-extra'); const { lstat } = window.require('fs/promises'); const { parse: parsePath, join: pathJoin, basename, dirname } = window.require('path'); -const { focusWindow, hasDisabledNetworking, quitApp, pathToFileURL, setProgressBar, sendOsNotification, lossyMode } = window.require('@electron/remote').require('./index.js'); +const { focusWindow, hasDisabledNetworking, quitApp, pathToFileURL, setProgressBar, sendOsNotification, lossyMode, pathExists } = window.require('@electron/remote').require('./index.js'); const hevcPlaybackSupportedPromise = doesPlayerSupportHevcPlayback(); @@ -1334,7 +1339,7 @@ function App() { const loadMedia = useCallback(async ({ filePath: fp, projectPath }: { filePath: string, projectPath?: string | undefined }) => { async function tryOpenProjectPath(path: string) { - if (!(await exists(path))) return false; + if (!(await pathExists(path))) return false; await loadEdlFile({ path, type: 'llc' }); return true; } @@ -1348,9 +1353,9 @@ function App() { // then try to open project from source file dir const sameDirEdlFilePath = getEdlFilePath(fp); - // MAS only allows fs.access (fs-extra.exists) if we don't have access to input dir yet, so check first if the file exists, + // MAS only allows fs.access (pathExists) if we don't have access to input dir yet, so check first if the file exists, // so we don't need to annoy the user by asking for permission if the project file doesn't exist - if (await exists(sameDirEdlFilePath)) { + if (await pathExists(sameDirEdlFilePath)) { // Ok, the file exists. now we have to ask the user, because we need to read that file await ensureAccessToSourceDir(fp); // Ok, we got access from the user (or already have access), now read the project file @@ -1517,8 +1522,8 @@ function App() { const mediaFilePath = pathJoin(dirname(path), mediaFileName); - // Note: MAS only allows fs.stat (fs-extra.exists) if we don't have access to input dir yet - if (!(await exists(mediaFilePath))) { + // Note: MAS only allows fs.stat (pathExists) if we don't have access to input dir yet + if (!(await pathExists(mediaFilePath))) { errorToast(i18n.t('The media file referenced by the project file you tried to open does not exist in the same directory as the project file: {{mediaFileName}}', { mediaFileName })); return; } diff --git a/src/renderer/src/BottomBar.tsx b/src/renderer/src/BottomBar.tsx index 5e83618d..a9806f6d 100644 --- a/src/renderer/src/BottomBar.tsx +++ b/src/renderer/src/BottomBar.tsx @@ -1,4 +1,5 @@ -import { CSSProperties, ClipboardEvent, Dispatch, FormEvent, SetStateAction, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import type { CSSProperties, ClipboardEvent, Dispatch, FormEvent, SetStateAction } from 'react'; +import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { motion } from 'framer-motion'; import { MdRotate90DegreesCcw } from 'react-icons/md'; import { useTranslation } from 'react-i18next'; @@ -24,9 +25,9 @@ import { useSegColors } from './contexts'; import { isExactDurationMatch } from './util/duration'; import useUserSettings from './hooks/useUserSettings'; import { askForPlaybackRate, checkAppPath } from './dialogs'; -import { FormatTimecode, ParseTimecode, PlaybackMode, SegmentColorIndex, SegmentToExport, StateSegment } from './types'; -import { WaveformMode } from '../../common/types'; -import { Frame } from './ffmpeg'; +import type { FormatTimecode, ParseTimecode, PlaybackMode, SegmentColorIndex, SegmentToExport, StateSegment } from './types'; +import type { WaveformMode } from '../../common/types'; +import type { Frame } from './ffmpeg'; const { clipboard } = window.require('electron'); diff --git a/src/renderer/src/ErrorBoundary.tsx b/src/renderer/src/ErrorBoundary.tsx index 3f89df7b..088d9953 100644 --- a/src/renderer/src/ErrorBoundary.tsx +++ b/src/renderer/src/ErrorBoundary.tsx @@ -1,4 +1,5 @@ -import { Component, ErrorInfo, ReactNode } from 'react'; +import type { ErrorInfo, ReactNode } from 'react'; +import { Component } from 'react'; import { Trans } from 'react-i18next'; import { openSendReportDialog } from './reporting'; diff --git a/src/renderer/src/LastCommands.tsx b/src/renderer/src/LastCommands.tsx index 61b0bef4..f40b91ee 100644 --- a/src/renderer/src/LastCommands.tsx +++ b/src/renderer/src/LastCommands.tsx @@ -1,10 +1,11 @@ -import { Dispatch, memo, SetStateAction } from 'react'; +import type { Dispatch, SetStateAction } from 'react'; +import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { DateTime } from 'luxon'; import sortBy from 'lodash/sortBy.js'; import CopyClipboardButton from './components/CopyClipboardButton'; -import { FfmpegCommandLog } from './types'; +import type { FfmpegCommandLog } from './types'; import Button from './components/Button'; import * as Dialog from './components/Dialog'; diff --git a/src/renderer/src/MediaSourcePlayer.tsx b/src/renderer/src/MediaSourcePlayer.tsx index 05c32ea3..9e8b1277 100644 --- a/src/renderer/src/MediaSourcePlayer.tsx +++ b/src/renderer/src/MediaSourcePlayer.tsx @@ -1,11 +1,12 @@ -import { useEffect, useRef, useState, useCallback, useMemo, memo, CSSProperties, RefObject, ReactEventHandler, FocusEventHandler } from 'react'; +import type { CSSProperties, RefObject, ReactEventHandler, FocusEventHandler } from 'react'; +import { useEffect, useRef, useState, useCallback, useMemo, memo } from 'react'; import invariant from 'tiny-invariant'; import debounce from 'lodash/debounce.js'; import { FaVideo } from 'react-icons/fa'; import isDev from './isDev'; -import { ChromiumHTMLVideoElement } from './types'; -import { FFprobeStream } from '../../common/ffprobe'; +import type { ChromiumHTMLVideoElement } from './types'; +import type { FFprobeStream } from '../../common/ffprobe'; import { getFrameDuration } from './util'; const { compatPlayer: { createMediaSourceStream } } = window.require('@electron/remote').require('./index.js'); diff --git a/src/renderer/src/NoFileLoaded.tsx b/src/renderer/src/NoFileLoaded.tsx index a6e4493f..304fe2cd 100644 --- a/src/renderer/src/NoFileLoaded.tsx +++ b/src/renderer/src/NoFileLoaded.tsx @@ -1,13 +1,14 @@ import { Fragment, memo, useMemo, useState } from 'react'; -import { motion, MotionStyle } from 'framer-motion'; +import type { MotionStyle } from 'framer-motion'; +import { motion } from 'framer-motion'; import { FaMouse } from 'react-icons/fa'; import { useTranslation, Trans } from 'react-i18next'; import SetCutpointButton from './components/SetCutpointButton'; import SimpleModeButton from './components/SimpleModeButton'; import useUserSettings from './hooks/useUserSettings'; -import { StateSegment } from './types'; -import { KeyBinding } from '../../common/types'; +import type { StateSegment } from './types'; +import type { KeyBinding } from '../../common/types'; import { splitKeyboardKeys } from './util'; import { getModifier } from './hooks/useTimelineScroll'; import Kbd from './components/Kbd'; diff --git a/src/renderer/src/SegmentList.tsx b/src/renderer/src/SegmentList.tsx index 65b795a2..85853eae 100644 --- a/src/renderer/src/SegmentList.tsx +++ b/src/renderer/src/SegmentList.tsx @@ -1,9 +1,11 @@ -import { memo, useMemo, useRef, useCallback, useState, SetStateAction, Dispatch, MouseEventHandler, CSSProperties, useEffect } from 'react'; +import type { SetStateAction, Dispatch, MouseEventHandler, CSSProperties } from 'react'; +import { memo, useMemo, useRef, useCallback, useState, useEffect } from 'react'; import { FaYinYang, FaSave, FaPlus, FaMinus, FaTag, FaSortNumericDown, FaRegCheckCircle, FaRegCircle, FaTimes } from 'react-icons/fa'; import { AiOutlineSplitCells } from 'react-icons/ai'; import { motion } from 'framer-motion'; import { useTranslation, Trans } from 'react-i18next'; -import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, DragEndEvent, DragStartEvent, DragOverlay, UniqueIdentifier } from '@dnd-kit/core'; +import type { DragEndEvent, DragStartEvent, UniqueIdentifier } from '@dnd-kit/core'; +import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, DragOverlay } from '@dnd-kit/core'; import { SortableContext, verticalListSortingStrategy, arrayMove, useSortable } from '@dnd-kit/sortable'; import { restrictToVerticalAxis } from '@dnd-kit/modifiers'; import { useVirtualizer } from '@tanstack/react-virtual'; @@ -17,8 +19,8 @@ import { saveColor, controlsBackground, primaryTextColor, darkModeTransition } f import { useSegColors } from './contexts'; import { getSegmentTags } from './segments'; import TagEditor from './components/TagEditor'; -import { ContextMenuTemplate, DefiniteSegmentBase, FormatTimecode, GetFrameCount, InverseCutSegment, SegmentBase, SegmentColorIndex, SegmentTags, StateSegment } from './types'; -import { UseSegments } from './hooks/useSegments'; +import type { ContextMenuTemplate, DefiniteSegmentBase, FormatTimecode, GetFrameCount, InverseCutSegment, SegmentBase, SegmentColorIndex, SegmentTags, StateSegment } from './types'; +import type { UseSegments } from './hooks/useSegments'; import * as Dialog from './components/Dialog'; import { DialogButton } from './components/Button'; import getSwal from './swal'; diff --git a/src/renderer/src/StreamsSelector.tsx b/src/renderer/src/StreamsSelector.tsx index 56e1992d..4a0dade3 100644 --- a/src/renderer/src/StreamsSelector.tsx +++ b/src/renderer/src/StreamsSelector.tsx @@ -1,4 +1,5 @@ -import { memo, useState, useMemo, useCallback, Dispatch, SetStateAction, CSSProperties, ReactNode, ChangeEventHandler, DragEventHandler } from 'react'; +import type { Dispatch, SetStateAction, CSSProperties, ReactNode, ChangeEventHandler, DragEventHandler } from 'react'; +import { memo, useState, useMemo, useCallback } from 'react'; import { FaImage, FaPaperclip, FaVideo, FaVideoSlash, FaFileImport, FaVolumeUp, FaVolumeMute, FaBan, FaFileExport, FaBook, FaInfoCircle, FaFilter, FaEye, FaEdit, FaTrash, FaSortNumericDown, FaSortNumericUp, FaHamburger, FaMap } from 'react-icons/fa'; import { GoFileBinary } from 'react-icons/go'; @@ -10,12 +11,13 @@ import * as DropdownMenu from './components/DropdownMenu'; import * as Dialog from './components/Dialog'; import AutoExportToggler from './components/AutoExportToggler'; import Select from './components/Select'; -import { FileStream, getStreamFps } from './ffmpeg'; +import type { FileStream } from './ffmpeg'; +import { getStreamFps } from './ffmpeg'; import { deleteDispositionValue } from './util'; import { getActiveDisposition, attachedPicDisposition, isGpsStream } from './util/streams'; import TagEditor from './components/TagEditor'; -import { FFprobeChapter, FFprobeFormat, FFprobeStream } from '../../common/ffprobe'; -import { CustomTagsByFile, FilesMeta, FormatTimecode, ParamsByStreamId, StreamParams } from './types'; +import type { FFprobeChapter, FFprobeFormat, FFprobeStream } from '../../common/ffprobe'; +import type { CustomTagsByFile, FilesMeta, FormatTimecode, ParamsByStreamId, StreamParams } from './types'; import Button, { DialogButton } from './components/Button'; import Checkbox from './components/Checkbox'; import styles from './StreamsSelector.module.css'; diff --git a/src/renderer/src/Timeline.tsx b/src/renderer/src/Timeline.tsx index 51622742..dfd4dcd9 100644 --- a/src/renderer/src/Timeline.tsx +++ b/src/renderer/src/Timeline.tsx @@ -1,4 +1,5 @@ -import { memo, useRef, useMemo, useCallback, useEffect, useState, MutableRefObject, CSSProperties, WheelEventHandler, MouseEventHandler } from 'react'; +import type { MutableRefObject, CSSProperties, WheelEventHandler, MouseEventHandler } from 'react'; +import { memo, useRef, useMemo, useCallback, useEffect, useState } from 'react'; import { motion, useMotionValue, useSpring } from 'framer-motion'; import debounce from 'lodash/debounce'; import { useTranslation } from 'react-i18next'; @@ -14,10 +15,10 @@ import styles from './Timeline.module.css'; import { timelineBackground, darkModeTransition } from './colors'; -import { Frame } from './ffmpeg'; -import { FormatTimecode, InverseCutSegment, OverviewWaveform, RenderableWaveform, WaveformSlice, StateSegment, Thumbnail } from './types'; +import type { Frame } from './ffmpeg'; +import type { FormatTimecode, InverseCutSegment, OverviewWaveform, RenderableWaveform, WaveformSlice, StateSegment, Thumbnail } from './types'; import Button from './components/Button'; -import { UseSegments } from './hooks/useSegments'; +import type { UseSegments } from './hooks/useSegments'; import { keyMap } from './hooks/useTimelineScroll'; diff --git a/src/renderer/src/TimelineSeg.tsx b/src/renderer/src/TimelineSeg.tsx index 0f582c2c..aeba0826 100644 --- a/src/renderer/src/TimelineSeg.tsx +++ b/src/renderer/src/TimelineSeg.tsx @@ -1,11 +1,12 @@ import { memo, useCallback, useMemo } from 'react'; -import { motion, AnimatePresence, MotionStyle } from 'framer-motion'; +import type { MotionStyle } from 'framer-motion'; +import { motion, AnimatePresence } from 'framer-motion'; import { FaSave, FaTrashAlt } from 'react-icons/fa'; -import Color from 'color'; +import type Color from 'color'; import useUserSettings from './hooks/useUserSettings'; import { useSegColors } from './contexts'; -import { FormatTimecode, StateSegment } from './types'; +import type { FormatTimecode, StateSegment } from './types'; const markerButtonStyle: React.CSSProperties = { fontSize: 10, minWidth: 0, letterSpacing: '-.1em', color: 'white' }; diff --git a/src/renderer/src/TopMenu.tsx b/src/renderer/src/TopMenu.tsx index 5bfe1b98..f225243e 100644 --- a/src/renderer/src/TopMenu.tsx +++ b/src/renderer/src/TopMenu.tsx @@ -1,4 +1,5 @@ -import { CSSProperties, ReactNode, memo, useCallback, useEffect, useRef } from 'react'; +import type { CSSProperties, ReactNode } from 'react'; +import { memo, useCallback, useEffect, useRef } from 'react'; import { IoIosSettings } from 'react-icons/io'; import { FaFilter, FaList, FaLock, FaMoon, FaSun, FaTimes, FaUnlock } from 'react-icons/fa'; import { useTranslation } from 'react-i18next'; diff --git a/src/renderer/src/components/Action.tsx b/src/renderer/src/components/Action.tsx index e9dd6e6f..afedc842 100644 --- a/src/renderer/src/components/Action.tsx +++ b/src/renderer/src/components/Action.tsx @@ -1,5 +1,5 @@ import { FaBolt } from 'react-icons/fa'; -import { KeyboardAction } from '../../../common/types'; +import type { KeyboardAction } from '../../../common/types'; export default function Action({ name }: { name: KeyboardAction }) { diff --git a/src/renderer/src/components/AnimatedTr.tsx b/src/renderer/src/components/AnimatedTr.tsx index f1634ed6..c13bd532 100644 --- a/src/renderer/src/components/AnimatedTr.tsx +++ b/src/renderer/src/components/AnimatedTr.tsx @@ -1,4 +1,5 @@ -import { motion, HTMLMotionProps } from 'framer-motion'; +import type { HTMLMotionProps } from 'framer-motion'; +import { motion } from 'framer-motion'; export default function AnimatedTr(props: HTMLMotionProps<'tr'>) { return ( diff --git a/src/renderer/src/components/BatchFile.tsx b/src/renderer/src/components/BatchFile.tsx index d5fac44f..33a43aa6 100644 --- a/src/renderer/src/components/BatchFile.tsx +++ b/src/renderer/src/components/BatchFile.tsx @@ -1,4 +1,5 @@ -import { memo, useRef, useMemo, useCallback, CSSProperties, MouseEventHandler } from 'react'; +import type { CSSProperties, MouseEventHandler } from 'react'; +import { memo, useRef, useMemo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { FaFile, FaTimes } from 'react-icons/fa'; import { useSortable } from '@dnd-kit/sortable'; diff --git a/src/renderer/src/components/BatchFilesList.tsx b/src/renderer/src/components/BatchFilesList.tsx index 18259c16..76af2ef0 100644 --- a/src/renderer/src/components/BatchFilesList.tsx +++ b/src/renderer/src/components/BatchFilesList.tsx @@ -1,15 +1,17 @@ -import { DragEventHandler, memo, useCallback, useMemo, useState } from 'react'; +import type { DragEventHandler } from 'react'; +import { memo, useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { motion } from 'framer-motion'; import { FaTimes, FaHatWizard, FaSortAlphaDown, FaSortAlphaUp } from 'react-icons/fa'; import { AiOutlineMergeCells } from 'react-icons/ai'; -import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, DragEndEvent, DragStartEvent, DragOverlay, UniqueIdentifier } from '@dnd-kit/core'; +import type { DragEndEvent, DragStartEvent, UniqueIdentifier } from '@dnd-kit/core'; +import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, DragOverlay } from '@dnd-kit/core'; import { SortableContext, verticalListSortingStrategy, arrayMove } from '@dnd-kit/sortable'; import { restrictToVerticalAxis } from '@dnd-kit/modifiers'; import BatchFile from './BatchFile'; import { controlsBackground, darkModeTransition, primaryColor } from '../colors'; -import { BatchFile as BatchFileType } from '../types'; +import type { BatchFile as BatchFileType } from '../types'; import useUserSettings from '../hooks/useUserSettings'; diff --git a/src/renderer/src/components/BigWaveform.tsx b/src/renderer/src/components/BigWaveform.tsx index 5ec49d4b..910622e3 100644 --- a/src/renderer/src/components/BigWaveform.tsx +++ b/src/renderer/src/components/BigWaveform.tsx @@ -1,7 +1,8 @@ -import { memo, useEffect, useState, useCallback, useRef, CSSProperties, MouseEventHandler, WheelEventHandler, useMemo } from 'react'; +import type { CSSProperties, MouseEventHandler, WheelEventHandler } from 'react'; +import { memo, useEffect, useState, useCallback, useRef, useMemo } from 'react'; import { ffmpegExtractWindow } from '../util/constants'; -import { WaveformSlice } from '../types'; +import type { WaveformSlice } from '../types'; import Spinner from './Spinner'; diff --git a/src/renderer/src/components/Button.tsx b/src/renderer/src/components/Button.tsx index 04be6a7c..459737d5 100644 --- a/src/renderer/src/components/Button.tsx +++ b/src/renderer/src/components/Button.tsx @@ -1,4 +1,5 @@ -import { ButtonHTMLAttributes, DetailedHTMLProps, forwardRef } from 'react'; +import type { ButtonHTMLAttributes, DetailedHTMLProps } from 'react'; +import { forwardRef } from 'react'; import styles from './Button.module.css'; import { primaryColor, primaryTextColor } from '../colors'; diff --git a/src/renderer/src/components/Checkbox.tsx b/src/renderer/src/components/Checkbox.tsx index 60a4ab6f..2e29acce 100644 --- a/src/renderer/src/components/Checkbox.tsx +++ b/src/renderer/src/components/Checkbox.tsx @@ -1,5 +1,6 @@ import { useId } from 'react'; -import { Root, Indicator, CheckboxProps } from '@radix-ui/react-checkbox'; +import type { CheckboxProps } from '@radix-ui/react-checkbox'; +import { Root, Indicator } from '@radix-ui/react-checkbox'; import { FaCheck } from 'react-icons/fa'; import classes from './Checkbox.module.css'; diff --git a/src/renderer/src/components/CloseButton.tsx b/src/renderer/src/components/CloseButton.tsx index 6ad4da2c..37d07e7f 100644 --- a/src/renderer/src/components/CloseButton.tsx +++ b/src/renderer/src/components/CloseButton.tsx @@ -1,5 +1,5 @@ import { FaTimes } from 'react-icons/fa'; -import { DetailedHTMLProps, ButtonHTMLAttributes } from 'react'; +import type { DetailedHTMLProps, ButtonHTMLAttributes } from 'react'; import styles from './CloseButton.module.css'; import i18n from '../i18n'; diff --git a/src/renderer/src/components/ConcatDialog.tsx b/src/renderer/src/components/ConcatDialog.tsx index 38663ea7..8a758f4c 100644 --- a/src/renderer/src/components/ConcatDialog.tsx +++ b/src/renderer/src/components/ConcatDialog.tsx @@ -1,4 +1,5 @@ -import { memo, useState, useCallback, useEffect, useMemo, CSSProperties, Dispatch, SetStateAction } from 'react'; +import type { CSSProperties, Dispatch, SetStateAction } from 'react'; +import { memo, useState, useCallback, useEffect, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { AiOutlineMergeCells } from 'react-icons/ai'; import { FaQuestionCircle, FaExclamationTriangle, FaCog, FaCheck, FaNotEqual } from 'react-icons/fa'; @@ -7,19 +8,21 @@ import invariant from 'tiny-invariant'; import pMap from 'p-map'; import Checkbox from './Checkbox'; -import { readFileFfprobeMeta, getDefaultOutFormat, mapRecommendedDefaultFormat, FileFfprobeMeta } from '../ffmpeg'; +import type { FileFfprobeMeta } from '../ffmpeg'; +import { readFileFfprobeMeta, getDefaultOutFormat, mapRecommendedDefaultFormat } from '../ffmpeg'; import OutputFormatSelect from './OutputFormatSelect'; import useUserSettings from '../hooks/useUserSettings'; import { isMov } from '../util/streams'; import { getOutDir, readFileStats } from '../util'; -import { FFprobeStream } from '../../../common/ffprobe'; +import type { FFprobeStream } from '../../../common/ffprobe'; import Button, { DialogButton } from './Button'; -import { defaultMergedFileTemplate, GeneratedOutFileNames, GenerateMergedOutFileNames } from '../util/outputNameTemplate'; +import type { GeneratedOutFileNames, GenerateMergedOutFileNames } from '../util/outputNameTemplate'; +import { defaultMergedFileTemplate } from '../util/outputNameTemplate'; import { dangerColor, saveColor, warningColor } from '../colors'; import * as Dialog from './Dialog'; import FileNameTemplateEditor from './FileNameTemplateEditor'; import HighlightedText from './HighlightedText'; -import { FileStats } from '../types'; +import type { FileStats } from '../types'; const { basename } = window.require('path'); diff --git a/src/renderer/src/components/CopyClipboardButton.tsx b/src/renderer/src/components/CopyClipboardButton.tsx index 8c7164a2..dbad792b 100644 --- a/src/renderer/src/components/CopyClipboardButton.tsx +++ b/src/renderer/src/components/CopyClipboardButton.tsx @@ -1,6 +1,8 @@ -import { memo, ReactNode, useCallback } from 'react'; +import type { ReactNode } from 'react'; +import { memo, useCallback } from 'react'; import { FaClipboard } from 'react-icons/fa'; -import { MotionStyle, motion, useAnimation } from 'framer-motion'; +import type { MotionStyle } from 'framer-motion'; +import { motion, useAnimation } from 'framer-motion'; import i18n from '../i18n'; const electron = window.require('electron'); diff --git a/src/renderer/src/components/Dialog.tsx b/src/renderer/src/components/Dialog.tsx index 52d50c53..20b14503 100644 --- a/src/renderer/src/components/Dialog.tsx +++ b/src/renderer/src/components/Dialog.tsx @@ -1,5 +1,5 @@ import * as Dialog from '@radix-ui/react-dialog'; -import { ReactNode } from 'react'; +import type { ReactNode } from 'react'; import styles from './Dialog.module.css'; import { withClass } from './util'; diff --git a/src/renderer/src/components/ExportButton.tsx b/src/renderer/src/components/ExportButton.tsx index 6efe8ab3..e8ece5c6 100644 --- a/src/renderer/src/components/ExportButton.tsx +++ b/src/renderer/src/components/ExportButton.tsx @@ -1,11 +1,12 @@ -import { CSSProperties, forwardRef, MouseEventHandler } from 'react'; +import type { CSSProperties, MouseEventHandler } from 'react'; +import { forwardRef } from 'react'; import { FiScissors } from 'react-icons/fi'; import { FaFileExport } from 'react-icons/fa'; import { useTranslation } from 'react-i18next'; import { primaryColor } from '../colors'; import useUserSettings from '../hooks/useUserSettings'; -import { SegmentToExport } from '../types'; +import type { SegmentToExport } from '../types'; import styles from './ExportButton.module.css'; diff --git a/src/renderer/src/components/ExportConfirm.tsx b/src/renderer/src/components/ExportConfirm.tsx index 603aacef..e8989cac 100644 --- a/src/renderer/src/components/ExportConfirm.tsx +++ b/src/renderer/src/components/ExportConfirm.tsx @@ -1,4 +1,5 @@ -import { CSSProperties, Dispatch, ReactNode, SetStateAction, memo, useCallback, useMemo, useState } from 'react'; +import type { CSSProperties, Dispatch, ReactNode, SetStateAction } from 'react'; +import { memo, useCallback, useMemo, useState } from 'react'; import { FaExclamationTriangle, FaInfoCircle, FaRegCheckCircle } from 'react-icons/fa'; import i18n from 'i18next'; import { useTranslation, Trans } from 'react-i18next'; @@ -18,15 +19,16 @@ import getSwal from '../swal'; import { isMov as ffmpegIsMov } from '../util/streams'; import useUserSettings from '../hooks/useUserSettings'; import styles from './ExportConfirm.module.css'; -import { SegmentToExport } from '../types'; -import { defaultCutFileTemplate, defaultCutMergedFileTemplate, GenerateOutFileNames } from '../util/outputNameTemplate'; -import { FFprobeStream } from '../../../common/ffprobe'; -import { AvoidNegativeTs, PreserveMetadata } from '../../../common/types'; +import type { SegmentToExport } from '../types'; +import type { GenerateOutFileNames } from '../util/outputNameTemplate'; +import { defaultCutFileTemplate, defaultCutMergedFileTemplate } from '../util/outputNameTemplate'; +import type { FFprobeStream } from '../../../common/ffprobe'; +import type { AvoidNegativeTs, PreserveMetadata } from '../../../common/types'; import TextInput from './TextInput'; -import { UseSegments } from '../hooks/useSegments'; +import type { UseSegments } from '../hooks/useSegments'; import ExportSheet from './ExportSheet'; import ToggleExportConfirm from './ToggleExportConfirm'; -import { LossyMode } from '../../../main'; +import type { LossyMode } from '../../../main'; import AnimatedTr from './AnimatedTr'; diff --git a/src/renderer/src/components/ExportModeButton.tsx b/src/renderer/src/components/ExportModeButton.tsx index 525ff6bf..df841ffd 100644 --- a/src/renderer/src/components/ExportModeButton.tsx +++ b/src/renderer/src/components/ExportModeButton.tsx @@ -1,10 +1,11 @@ -import { CSSProperties, memo, useMemo } from 'react'; +import type { CSSProperties } from 'react'; +import { memo, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { withBlur } from '../util'; import useUserSettings from '../hooks/useUserSettings'; import Select from './Select'; -import { ExportMode } from '../types'; +import type { ExportMode } from '../types'; function ExportModeButton({ selectedSegments, style }: { selectedSegments: unknown[], style?: CSSProperties }) { diff --git a/src/renderer/src/components/ExportSheet.tsx b/src/renderer/src/components/ExportSheet.tsx index b1e34e2c..e41f6b76 100644 --- a/src/renderer/src/components/ExportSheet.tsx +++ b/src/renderer/src/components/ExportSheet.tsx @@ -1,4 +1,4 @@ -import { CSSProperties, ReactNode } from 'react'; +import type { CSSProperties, ReactNode } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import styles from './ExportSheet.module.css'; diff --git a/src/renderer/src/components/ExpressionDialog.tsx b/src/renderer/src/components/ExpressionDialog.tsx index 821847e6..05fd97a1 100644 --- a/src/renderer/src/components/ExpressionDialog.tsx +++ b/src/renderer/src/components/ExpressionDialog.tsx @@ -1,5 +1,6 @@ import { useTranslation } from 'react-i18next'; -import { FormEventHandler, forwardRef, ReactNode, useCallback, useEffect, useRef, useState } from 'react'; +import type { FormEventHandler, ReactNode } from 'react'; +import { forwardRef, useCallback, useEffect, useRef, useState } from 'react'; import * as AlertDialog from './AlertDialog'; import { DialogButton } from './Button'; diff --git a/src/renderer/src/components/FileNameTemplateEditor.tsx b/src/renderer/src/components/FileNameTemplateEditor.tsx index 731cde46..5272f1f3 100644 --- a/src/renderer/src/components/FileNameTemplateEditor.tsx +++ b/src/renderer/src/components/FileNameTemplateEditor.tsx @@ -1,4 +1,5 @@ -import { memo, useState, useEffect, useCallback, useRef, useMemo, ChangeEventHandler } from 'react'; +import type { ChangeEventHandler } from 'react'; +import { memo, useState, useEffect, useCallback, useRef, useMemo } from 'react'; import { useDebounce } from 'use-debounce'; import i18n from 'i18next'; import { useTranslation } from 'react-i18next'; @@ -7,7 +8,8 @@ import { motion, AnimatePresence } from 'framer-motion'; import { FaCaretUp, FaEdit, FaExclamationTriangle, FaEye, FaFile, FaUndo } from 'react-icons/fa'; import HighlightedText from './HighlightedText'; -import { segNumVariable, segSuffixVariable, GenerateOutFileNames, extVariable, segTagsVariable, segNumIntVariable, selectedSegNumVariable, selectedSegNumIntVariable, GeneratedOutFileNames } from '../util/outputNameTemplate'; +import type { GenerateOutFileNames, GeneratedOutFileNames } from '../util/outputNameTemplate'; +import { segNumVariable, segSuffixVariable, extVariable, segTagsVariable, segNumIntVariable, selectedSegNumVariable, selectedSegNumIntVariable } from '../util/outputNameTemplate'; import useUserSettings from '../hooks/useUserSettings'; import Switch from './Switch'; import Select from './Select'; diff --git a/src/renderer/src/components/GenericDialog.tsx b/src/renderer/src/components/GenericDialog.tsx index a7225d19..93350708 100644 --- a/src/renderer/src/components/GenericDialog.tsx +++ b/src/renderer/src/components/GenericDialog.tsx @@ -1,4 +1,5 @@ -import React, { MouseEventHandler, ReactNode, useCallback, useContext, useMemo, useRef, useState } from 'react'; +import type { MouseEventHandler, ReactNode } from 'react'; +import React, { useCallback, useContext, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import invariant from 'tiny-invariant'; import { FaCheckCircle, FaInfoCircle } from 'react-icons/fa'; @@ -7,7 +8,8 @@ import * as Dialog from './Dialog'; import * as AlertDialog from './AlertDialog'; import { DialogButton } from './Button'; import { showItemInFolder } from '../util'; -import { CleanupChoice, CleanupChoicesType, ListItem, Notices, OutputIncorrectSeeHelpMenu, UnorderedList, Warnings } from '../dialogs'; +import type { CleanupChoice, CleanupChoicesType } from '../dialogs'; +import { ListItem, Notices, OutputIncorrectSeeHelpMenu, UnorderedList, Warnings } from '../dialogs'; import Checkbox from './Checkbox'; import { saveColor, warningColor } from '../colors'; diff --git a/src/renderer/src/components/HighlightedText.tsx b/src/renderer/src/components/HighlightedText.tsx index 508f3fb8..520925b4 100644 --- a/src/renderer/src/components/HighlightedText.tsx +++ b/src/renderer/src/components/HighlightedText.tsx @@ -1,4 +1,5 @@ -import { CSSProperties, HTMLAttributes, memo } from 'react'; +import type { CSSProperties, HTMLAttributes } from 'react'; +import { memo } from 'react'; import { primaryTextColor } from '../colors'; import styles from './HighlightedText.module.css'; diff --git a/src/renderer/src/components/Kbd.tsx b/src/renderer/src/components/Kbd.tsx index 6f1f8fcf..09ca958b 100644 --- a/src/renderer/src/components/Kbd.tsx +++ b/src/renderer/src/components/Kbd.tsx @@ -1,4 +1,5 @@ -import { HTMLAttributes, useMemo } from 'react'; +import type { HTMLAttributes } from 'react'; +import { useMemo } from 'react'; import { useAppContext } from '../contexts'; import { getMetaKeyName } from '../util'; diff --git a/src/renderer/src/components/KeyboardShortcuts.tsx b/src/renderer/src/components/KeyboardShortcuts.tsx index f1e17e09..0dbeccf7 100644 --- a/src/renderer/src/components/KeyboardShortcuts.tsx +++ b/src/renderer/src/components/KeyboardShortcuts.tsx @@ -1,4 +1,5 @@ -import { memo, Fragment, useEffect, useMemo, useCallback, useState, ReactNode, SetStateAction, Dispatch, useRef } from 'react'; +import type { ReactNode, SetStateAction, Dispatch } from 'react'; +import { memo, Fragment, useEffect, useMemo, useCallback, useState, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { FaMouse, FaPlus, FaStepForward, FaStepBackward, FaUndo, FaTrash, FaSave, FaHammer } from 'react-icons/fa'; import groupBy from 'lodash/groupBy'; @@ -10,8 +11,8 @@ import useUserSettings from '../hooks/useUserSettings'; import SetCutpointButton from './SetCutpointButton'; import SegmentCutpointButton from './SegmentCutpointButton'; import { getModifier } from '../hooks/useTimelineScroll'; -import { KeyBinding, KeyboardAction, ModifierKey } from '../../../common/types'; -import { StateSegment } from '../types'; +import type { KeyBinding, KeyboardAction, ModifierKey } from '../../../common/types'; +import type { StateSegment } from '../types'; import { allModifiers, altModifiers, controlModifiers, metaModifiers, shiftModifiers, splitKeyboardKeys } from '../util'; import * as Dialog from './Dialog'; import Warning from './Warning'; diff --git a/src/renderer/src/components/OutputFormatSelect.tsx b/src/renderer/src/components/OutputFormatSelect.tsx index 56d641f7..8bdfa5ba 100644 --- a/src/renderer/src/components/OutputFormatSelect.tsx +++ b/src/renderer/src/components/OutputFormatSelect.tsx @@ -1,7 +1,9 @@ -import { CSSProperties, memo, useMemo } from 'react'; +import type { CSSProperties } from 'react'; +import { memo, useMemo } from 'react'; import i18n from 'i18next'; -import allOutFormats, { FfmpegFormat } from '../outFormats'; +import type { FfmpegFormat } from '../outFormats'; +import allOutFormats from '../outFormats'; import { withBlur } from '../util'; import Select from './Select'; diff --git a/src/renderer/src/components/PlaybackStreamSelector.tsx b/src/renderer/src/components/PlaybackStreamSelector.tsx index 4111c8fe..ea2a8ff4 100644 --- a/src/renderer/src/components/PlaybackStreamSelector.tsx +++ b/src/renderer/src/components/PlaybackStreamSelector.tsx @@ -1,4 +1,5 @@ -import { memo, useState, useCallback, useRef, useEffect, ChangeEventHandler, ChangeEvent } from 'react'; +import type { ChangeEventHandler, ChangeEvent } from 'react'; +import { memo, useState, useCallback, useRef, useEffect } from 'react'; import { MdSubtitles } from 'react-icons/md'; import { useTranslation } from 'react-i18next'; import { motion } from 'framer-motion'; @@ -6,7 +7,7 @@ import { motion } from 'framer-motion'; import Select from './Select'; import Switch from './Switch'; import styles from './PlaybackStreamSelector.module.css'; -import { FFprobeStream } from '../../../common/ffprobe'; +import type { FFprobeStream } from '../../../common/ffprobe'; function PlaybackStreamSelector({ diff --git a/src/renderer/src/components/SegmentCutpointButton.tsx b/src/renderer/src/components/SegmentCutpointButton.tsx index f808d0e3..42904a8f 100644 --- a/src/renderer/src/components/SegmentCutpointButton.tsx +++ b/src/renderer/src/components/SegmentCutpointButton.tsx @@ -1,9 +1,10 @@ -import { CSSProperties, useMemo } from 'react'; -import { FaStepForward } from 'react-icons/fa'; +import type { CSSProperties } from 'react'; +import { useMemo } from 'react'; +import type { FaStepForward } from 'react-icons/fa'; import { useSegColors } from '../contexts'; import useUserSettings from '../hooks/useUserSettings'; -import { SegmentColorIndex } from '../types'; +import type { SegmentColorIndex } from '../types'; const SegmentCutpointButton = ({ currentCutSeg, side, Icon, onClick, title, style }: { currentCutSeg: SegmentColorIndex | undefined, diff --git a/src/renderer/src/components/Select.tsx b/src/renderer/src/components/Select.tsx index c7a4a9a3..d970d99e 100644 --- a/src/renderer/src/components/Select.tsx +++ b/src/renderer/src/components/Select.tsx @@ -1,4 +1,5 @@ -import { SelectHTMLAttributes, memo } from 'react'; +import type { SelectHTMLAttributes } from 'react'; +import { memo } from 'react'; import styles from './Select.module.css'; diff --git a/src/renderer/src/components/SetCutpointButton.tsx b/src/renderer/src/components/SetCutpointButton.tsx index 5f310bd4..94ce0d61 100644 --- a/src/renderer/src/components/SetCutpointButton.tsx +++ b/src/renderer/src/components/SetCutpointButton.tsx @@ -1,9 +1,9 @@ -import { CSSProperties } from 'react'; +import type { CSSProperties } from 'react'; import { FaHandPointUp } from 'react-icons/fa'; import SegmentCutpointButton from './SegmentCutpointButton'; import { mirrorTransform } from '../util'; -import { SegmentColorIndex } from '../types'; +import type { SegmentColorIndex } from '../types'; // constant side because we are mirroring const SetCutpointButton = ({ currentCutSeg, side, title, onClick, style }: { diff --git a/src/renderer/src/components/Settings.tsx b/src/renderer/src/components/Settings.tsx index 5e761a2e..1929ec49 100644 --- a/src/renderer/src/components/Settings.tsx +++ b/src/renderer/src/components/Settings.tsx @@ -1,4 +1,5 @@ -import { CSSProperties, ChangeEventHandler, TdHTMLAttributes, memo, useCallback, useMemo } from 'react'; +import type { CSSProperties, ChangeEventHandler, TdHTMLAttributes } from 'react'; +import { memo, useCallback, useMemo } from 'react'; import { FaYinYang, FaKeyboard, FaGlobe, FaBroom, FaCogs, FaHashtag, FaClock, FaFolder, FaFile, FaTimes } from 'react-icons/fa'; import { useTranslation } from 'react-i18next'; import invariant from 'tiny-invariant'; @@ -10,13 +11,16 @@ import Switch from './Switch'; import useUserSettings from '../hooks/useUserSettings'; import { askForFfPath } from '../dialogs'; import { isMasBuild, isStoreBuild } from '../util'; -import { SupportedLanguage, langNames } from '../../../common/i18n'; -import { Config, ModifierKey, TimecodeFormat } from '../../../common/types.js'; +import type { SupportedLanguage } from '../../../common/i18n'; +import { langNames } from '../../../common/i18n'; +import type { Config, ModifierKey, TimecodeFormat } from '../../../common/types.js'; import styles from './Settings.module.css'; -import SelectRaw, { SelectProps } from './Select'; -import ButtonRaw, { ButtonProps } from './Button'; +import type { SelectProps } from './Select'; +import SelectRaw from './Select'; +import type { ButtonProps } from './Button'; +import ButtonRaw from './Button'; import { getModifierKeyNames } from '../hooks/useTimelineScroll'; -import { TunerType } from '../types'; +import type { TunerType } from '../types'; import Truncated from './Truncated'; import { dangerColor } from '../colors'; diff --git a/src/renderer/src/components/SimpleModeButton.tsx b/src/renderer/src/components/SimpleModeButton.tsx index 219db68a..2456fa67 100644 --- a/src/renderer/src/components/SimpleModeButton.tsx +++ b/src/renderer/src/components/SimpleModeButton.tsx @@ -1,4 +1,5 @@ -import { CSSProperties, memo } from 'react'; +import type { CSSProperties } from 'react'; +import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { FaBaby } from 'react-icons/fa'; diff --git a/src/renderer/src/components/SwalContainer.tsx b/src/renderer/src/components/SwalContainer.tsx index 36451ac0..7c728d22 100644 --- a/src/renderer/src/components/SwalContainer.tsx +++ b/src/renderer/src/components/SwalContainer.tsx @@ -1,4 +1,4 @@ -import { HTMLAttributes } from 'react'; +import type { HTMLAttributes } from 'react'; import { swalContainerWrapperId } from '../swal'; export default function SwalContainer({ darkMode, ...props }: HTMLAttributes & { darkMode: boolean }) { diff --git a/src/renderer/src/components/Switch.tsx b/src/renderer/src/components/Switch.tsx index 1d05690f..6714654f 100644 --- a/src/renderer/src/components/Switch.tsx +++ b/src/renderer/src/components/Switch.tsx @@ -1,4 +1,4 @@ -import { RefAttributes } from 'react'; +import type { RefAttributes } from 'react'; import * as RadixSwitch from '@radix-ui/react-switch'; import classes from './Switch.module.css'; diff --git a/src/renderer/src/components/TagEditor.tsx b/src/renderer/src/components/TagEditor.tsx index d169438c..ab53e63b 100644 --- a/src/renderer/src/components/TagEditor.tsx +++ b/src/renderer/src/components/TagEditor.tsx @@ -1,10 +1,12 @@ -import { memo, useRef, useState, useMemo, useCallback, useEffect, FormEventHandler } from 'react'; +import type { FormEventHandler } from 'react'; +import { memo, useRef, useState, useMemo, useCallback, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import invariant from 'tiny-invariant'; import { motion } from 'framer-motion'; import { FaCheck, FaEdit, FaPlus, FaTrash, FaUndo } from 'react-icons/fa'; -import { SegmentTags, segmentTagsSchema } from '../types'; +import type { SegmentTags } from '../types'; +import { segmentTagsSchema } from '../types'; import CopyClipboardButton from './CopyClipboardButton'; import { errorToast } from '../swal'; import TextInput from './TextInput'; diff --git a/src/renderer/src/components/TextInput.tsx b/src/renderer/src/components/TextInput.tsx index a6fe8414..48de0d3e 100644 --- a/src/renderer/src/components/TextInput.tsx +++ b/src/renderer/src/components/TextInput.tsx @@ -1,4 +1,5 @@ -import { CSSProperties, forwardRef } from 'react'; +import type { CSSProperties } from 'react'; +import { forwardRef } from 'react'; const inputStyle: CSSProperties = { borderRadius: '.4em', flexGrow: 1, fontFamily: 'inherit', fontSize: '.8em', backgroundColor: 'var(--gray-3)', color: 'var(--gray-12)', border: '1px solid var(--gray-7)', appearance: 'none' }; diff --git a/src/renderer/src/components/ToggleExportConfirm.tsx b/src/renderer/src/components/ToggleExportConfirm.tsx index fe524298..8a6e24fa 100644 --- a/src/renderer/src/components/ToggleExportConfirm.tsx +++ b/src/renderer/src/components/ToggleExportConfirm.tsx @@ -1,4 +1,5 @@ -import { CSSProperties, memo } from 'react'; +import type { CSSProperties } from 'react'; +import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { MdEventNote } from 'react-icons/md'; diff --git a/src/renderer/src/components/Truncated.tsx b/src/renderer/src/components/Truncated.tsx index 0783dfd1..be2b023f 100644 --- a/src/renderer/src/components/Truncated.tsx +++ b/src/renderer/src/components/Truncated.tsx @@ -1,4 +1,4 @@ -import { CSSProperties, DetailedHTMLProps, HTMLAttributes } from 'react'; +import type { CSSProperties, DetailedHTMLProps, HTMLAttributes } from 'react'; export default function Truncated({ maxWidth, style, ...props }: DetailedHTMLProps, HTMLDivElement> & { maxWidth: CSSProperties['maxWidth'] }) { return ( diff --git a/src/renderer/src/components/ValueTuner.tsx b/src/renderer/src/components/ValueTuner.tsx index 9435f347..356b0364 100644 --- a/src/renderer/src/components/ValueTuner.tsx +++ b/src/renderer/src/components/ValueTuner.tsx @@ -1,4 +1,5 @@ -import { memo, useState, useCallback, ChangeEventHandler } from 'react'; +import type { ChangeEventHandler } from 'react'; +import { memo, useState, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import styles from './ValueTuner.module.css'; diff --git a/src/renderer/src/components/ValueTuners.tsx b/src/renderer/src/components/ValueTuners.tsx index f6800ee6..5c9c97c7 100644 --- a/src/renderer/src/components/ValueTuners.tsx +++ b/src/renderer/src/components/ValueTuners.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import ValueTuner from './ValueTuner'; import useUserSettings from '../hooks/useUserSettings'; -import { TunerType } from '../types'; +import type { TunerType } from '../types'; function ValueTuners({ type, onFinished }: { type: TunerType, onFinished: () => void }) { diff --git a/src/renderer/src/components/VolumeControl.tsx b/src/renderer/src/components/VolumeControl.tsx index d74b6d4a..89059095 100644 --- a/src/renderer/src/components/VolumeControl.tsx +++ b/src/renderer/src/components/VolumeControl.tsx @@ -1,4 +1,5 @@ -import { memo, useState, useCallback, useRef, useEffect, ChangeEventHandler } from 'react'; +import type { ChangeEventHandler } from 'react'; +import { memo, useState, useCallback, useRef, useEffect } from 'react'; import { FaVolumeMute, FaVolumeUp } from 'react-icons/fa'; import { useTranslation } from 'react-i18next'; diff --git a/src/renderer/src/components/Warning.tsx b/src/renderer/src/components/Warning.tsx index ed44bdde..e20a0fdc 100644 --- a/src/renderer/src/components/Warning.tsx +++ b/src/renderer/src/components/Warning.tsx @@ -1,4 +1,5 @@ -import { DetailedHTMLProps, HTMLAttributes, useMemo } from 'react'; +import type { DetailedHTMLProps, HTMLAttributes } from 'react'; +import { useMemo } from 'react'; import { warningColor } from '../colors'; diff --git a/src/renderer/src/contexts.ts b/src/renderer/src/contexts.ts index 552a8a0c..fba1347d 100644 --- a/src/renderer/src/contexts.ts +++ b/src/renderer/src/contexts.ts @@ -1,12 +1,12 @@ import React, { useContext } from 'react'; -import Color from 'color'; +import type Color from 'color'; import invariant from 'tiny-invariant'; -import { UserSettingsRoot } from './hooks/useUserSettingsRoot'; -import { ExportMode, KeyboardLayoutMap, SegmentColorIndex } from './types'; +import type { UserSettingsRoot } from './hooks/useUserSettingsRoot'; +import type { ExportMode, KeyboardLayoutMap, SegmentColorIndex } from './types'; import type useLoading from './hooks/useLoading'; -import { GenericError } from './components/ErrorDialog'; -import { ConfirmDialog, ShowGenericDialog } from './components/GenericDialog'; +import type { GenericError } from './components/ErrorDialog'; +import type { ConfirmDialog, ShowGenericDialog } from './components/GenericDialog'; export type UserSettingsContextType = Omit & UserSettingsRoot['settings'] & { diff --git a/src/renderer/src/dialogs/index.tsx b/src/renderer/src/dialogs/index.tsx index af062964..1edb0558 100644 --- a/src/renderer/src/dialogs/index.tsx +++ b/src/renderer/src/dialogs/index.tsx @@ -1,4 +1,4 @@ -import { CSSProperties, ReactNode } from 'react'; +import type { CSSProperties, ReactNode } from 'react'; import i18n from 'i18next'; import { Trans } from 'react-i18next'; import invariant from 'tiny-invariant'; @@ -10,8 +10,8 @@ import { formatDuration } from '../util/duration'; import { parseYouTube } from '../edlFormats'; import CopyClipboardButton from '../components/CopyClipboardButton'; import { appPath, isMac, isMasBuild, isWindows, isWindowsStoreBuild, testFailFsOperation, trashFile, unlinkWithRetry } from '../util'; -import { ParseTimecode } from '../types'; -import { FindKeyframeMode } from '../ffmpeg'; +import type { ParseTimecode } from '../types'; +import type { FindKeyframeMode } from '../ffmpeg'; import { dangerColor, primaryColor, warningColor } from '../colors'; import getSwal from '../swal'; import isDev from '../isDev'; diff --git a/src/renderer/src/edlFormats.test.ts b/src/renderer/src/edlFormats.test.ts index 4b8f6c76..5326fdee 100644 --- a/src/renderer/src/edlFormats.test.ts +++ b/src/renderer/src/edlFormats.test.ts @@ -1,6 +1,7 @@ import { it, describe, expect, test } from 'vitest'; -import { parseSrtToSegments, formatSrt, parseYouTube, formatYouTube, parseMplayerEdl, parseXmeml, parseFcpXml, parseCsv, parseCsvTime, getFrameValParser, formatCsvFrames, getFrameCountRaw, parsePbf, parseDvAnalyzerSummaryTxt, parseCutlist, parseDjiGps1, Otio, parseOtio, parseDjiGps2 } from './edlFormats'; +import type { Otio } from './edlFormats'; +import { parseSrtToSegments, formatSrt, parseYouTube, formatYouTube, parseMplayerEdl, parseXmeml, parseFcpXml, parseCsv, parseCsvTime, getFrameValParser, formatCsvFrames, getFrameCountRaw, parsePbf, parseDvAnalyzerSummaryTxt, parseCutlist, parseDjiGps1, parseOtio, parseDjiGps2 } from './edlFormats'; import { readFixture, readFixtureBinary } from './test/util'; import otioFixture from './test/fixtures/otio'; diff --git a/src/renderer/src/edlFormats.ts b/src/renderer/src/edlFormats.ts index 0be1ec32..91f86472 100644 --- a/src/renderer/src/edlFormats.ts +++ b/src/renderer/src/edlFormats.ts @@ -11,7 +11,7 @@ import { z } from 'zod'; import { formatDuration } from './util/duration'; import { invertSegments, sortSegments } from './segments'; -import { GetFrameCount, SegmentBase, SegmentTags } from './types'; +import type { GetFrameCount, SegmentBase, SegmentTags } from './types'; import parseCmx3600 from './cmx3600'; import { UserFacingError } from '../errors'; diff --git a/src/renderer/src/edlStore.ts b/src/renderer/src/edlStore.ts index 7734d50e..e822edd9 100644 --- a/src/renderer/src/edlStore.ts +++ b/src/renderer/src/edlStore.ts @@ -6,7 +6,8 @@ import { ZodError } from 'zod'; import { parseSrtToSegments, formatSrt, parseCuesheet, parseXmeml, parseFcpXml, parseCsv, parseCutlist, parsePbf, parseEdl, formatCsvHuman, formatTsvHuman, formatCsvFrames, formatCsvSeconds, parseCsvTime, getFrameValParser, parseDvAnalyzerSummaryTxt, parseOtio } from './edlFormats'; import { askForYouTubeInput, showOpenDialog } from './dialogs'; import { getOutPath } from './util'; -import { EdlExportType, EdlFileType, EdlImportType, GetFrameCount, LlcProject, llcProjectV1Schema, llcProjectV2Schema, SegmentBase, StateSegment } from './types'; +import type { EdlExportType, EdlFileType, EdlImportType, GetFrameCount, LlcProject, SegmentBase, StateSegment } from './types'; +import { llcProjectV1Schema, llcProjectV2Schema } from './types'; import { mapSaveableSegments } from './segments'; import isDev from './isDev'; diff --git a/src/renderer/src/ffmpeg.ts b/src/renderer/src/ffmpeg.ts index 9c2b84f1..afce7a6c 100644 --- a/src/renderer/src/ffmpeg.ts +++ b/src/renderer/src/ffmpeg.ts @@ -1,18 +1,19 @@ import pMap from 'p-map'; import sortBy from 'lodash/sortBy'; import i18n from 'i18next'; -import Timecode, { FRAMERATE } from 'smpte-timecode'; +import type { FRAMERATE } from 'smpte-timecode'; +import Timecode from 'smpte-timecode'; import minBy from 'lodash/minBy'; import invariant from 'tiny-invariant'; import { pcmAudioCodecs, isMov } from './util/streams'; import { isExecaError } from './util'; import { isDurationValid } from './segments'; -import { FFprobeChapter, FFprobeFormat, FFprobeProbeResult, FFprobeStream } from '../../common/ffprobe'; +import type { FFprobeChapter, FFprobeFormat, FFprobeProbeResult, FFprobeStream } from '../../common/ffprobe'; import { parseSrt, parseSrtToSegments } from './edlFormats'; import { UnsupportedFileError, UserFacingError } from '../errors'; -const { ffmpeg, fileTypePromise } = window.require('@electron/remote').require('./index.js'); +const { ffmpeg, fileTypeFromFile } = window.require('@electron/remote').require('./index.js'); const { renderWaveformPng, mapTimesToSegments, detectSceneChanges, captureFrames, captureFrameToFile, captureFrameToClipboard, getFfCommandLine, runFfmpegConcat, runFfmpegWithProgress, getDuration, abortFfmpegs, runFfmpeg, runFfprobe, getFfmpegPath, setCustomFfPath } = ffmpeg; @@ -267,7 +268,7 @@ async function determineSourceFileFormat(ffprobeFormatsStr: string | undefined, // We need to test mp3 first because ffprobe seems to report the wrong format sometimes https://github.com/mifi/lossless-cut/issues/2129 if (firstFfprobeFormat === 'mp3') { // file-type detects it correctly - const fileTypeResponse = await (await fileTypePromise).fileTypeFromFile(filePath); + const fileTypeResponse = await fileTypeFromFile(filePath); if (fileTypeResponse?.mime === 'audio/mpeg') { return 'mp2'; } @@ -286,7 +287,7 @@ async function determineSourceFileFormat(ffprobeFormatsStr: string | undefined, return firstFfprobeFormat; } - const fileTypeResponse = await (await fileTypePromise).fileTypeFromFile(filePath); + const fileTypeResponse = await fileTypeFromFile(filePath); if (fileTypeResponse == null) { console.warn('file-type failed to detect format, defaulting to first FFprobe detected format', ffprobeFormats); return firstFfprobeFormat; diff --git a/src/renderer/src/ffprobe.ts b/src/renderer/src/ffprobe.ts index 76ee3711..3434c047 100644 --- a/src/renderer/src/ffprobe.ts +++ b/src/renderer/src/ffprobe.ts @@ -1,6 +1,6 @@ // This code is for future use (e.g. creating black video to fill in using same codec parameters) -import { FFprobeStream } from '../../common/ffprobe'; +import type { FFprobeStream } from '../../common/ffprobe'; export function parseLevel(videoStream: FFprobeStream) { const { level: levelNumeric, codec_name: videoCodec } = videoStream; diff --git a/src/renderer/src/hooks/normalizeWheel.ts b/src/renderer/src/hooks/normalizeWheel.ts index a4a97e9b..defa4f8f 100644 --- a/src/renderer/src/hooks/normalizeWheel.ts +++ b/src/renderer/src/hooks/normalizeWheel.ts @@ -1,6 +1,6 @@ // Taken from: https://github.com/facebookarchive/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js -import { WheelEvent } from 'react'; +import type { WheelEvent } from 'react'; /** * Copyright (c) 2015, Facebook, Inc. diff --git a/src/renderer/src/hooks/useContextMenu.ts b/src/renderer/src/hooks/useContextMenu.ts index ce1b9d4f..86c13a15 100644 --- a/src/renderer/src/hooks/useContextMenu.ts +++ b/src/renderer/src/hooks/useContextMenu.ts @@ -1,7 +1,8 @@ -import { RefObject, useEffect } from 'react'; +import type { RefObject } from 'react'; +import { useEffect } from 'react'; import useNativeMenu from './useNativeMenu'; -import { ContextMenuTemplate } from '../types'; +import type { ContextMenuTemplate } from '../types'; // https://github.com/transflow/use-electron-context-menu diff --git a/src/renderer/src/hooks/useErrorHandling.ts b/src/renderer/src/hooks/useErrorHandling.ts index 48ebbbf2..6346423f 100644 --- a/src/renderer/src/hooks/useErrorHandling.ts +++ b/src/renderer/src/hooks/useErrorHandling.ts @@ -3,7 +3,7 @@ import { useCallback, useState } from 'react'; import { DirectoryAccessDeclinedError, UnsupportedFileError } from '../../errors'; import { isAbortedError } from '../util'; -import { GenericError } from '../components/ErrorDialog'; +import type { GenericError } from '../components/ErrorDialog'; export default function useErrorHandling() { diff --git a/src/renderer/src/hooks/useFfmpegOperations.ts b/src/renderer/src/hooks/useFfmpegOperations.ts index cc4e31ec..093bcf52 100644 --- a/src/renderer/src/hooks/useFfmpegOperations.ts +++ b/src/renderer/src/hooks/useFfmpegOperations.ts @@ -10,14 +10,15 @@ import { isCuttingStart, isCuttingEnd, runFfmpegWithProgress, getFfCommandLine, import { getMapStreamsArgs, getStreamIdsToCopy } from '../util/streams'; import { needsSmartCut, getCodecParams } from '../smartcut'; import { getGuaranteedSegments, isDurationValid } from '../segments'; -import { FFprobeStream } from '../../../common/ffprobe'; -import { AvoidNegativeTs, Html5ifyMode, PreserveMetadata } from '../../../common/types'; -import { AllFilesMeta, Chapter, CopyfileStreams, CustomTagsByFile, LiteFFprobeStream, ParamsByStreamId, SegmentToExport } from '../types'; -import { LossyMode } from '../../../main'; +import type { FFprobeStream } from '../../../common/ffprobe'; +import type { AvoidNegativeTs, Html5ifyMode, PreserveMetadata } from '../../../common/types'; +import type { AllFilesMeta, Chapter, CopyfileStreams, CustomTagsByFile, LiteFFprobeStream, ParamsByStreamId, SegmentToExport } from '../types'; +import type { LossyMode } from '../../../main'; import { UserFacingError } from '../../errors'; const { join, resolve, dirname } = window.require('path'); -const { writeFile, mkdir, access, constants: { F_OK, W_OK } } = window.require('fs/promises'); +const { writeFile, mkdir, access, constants: { W_OK } } = window.require('fs/promises'); +const { pathExists } = window.require('@electron/remote').require('./index.js'); export class OutputNotWritableError extends Error { @@ -70,15 +71,6 @@ async function tryDeleteFiles(paths: string[]) { return pMap(paths, (path) => unlinkWithRetry(path).catch((err) => console.error('Failed to delete', path, err)), { concurrency: 5 }); } -async function pathExists(path: string) { - try { - await access(path, F_OK); - return true; - } catch { - return false; - } -} - export async function maybeMkDeepOutDir({ outputDir, fileOutPath }: { outputDir: string, fileOutPath: string }) { // cutFileNames might contain slashes and therefore might have a subdir(tree) that we need to mkdir // https://github.com/mifi/lossless-cut/issues/1532 diff --git a/src/renderer/src/hooks/useFrameCapture.ts b/src/renderer/src/hooks/useFrameCapture.ts index 7393629a..71d4dd3a 100644 --- a/src/renderer/src/hooks/useFrameCapture.ts +++ b/src/renderer/src/hooks/useFrameCapture.ts @@ -6,8 +6,8 @@ import { getSuffixedOutPath, getOutDir, transferTimestamps, getSuffixedFileName, import { getNumDigits, isDurationValid } from '../segments'; import * as ffmpeg from '../ffmpeg'; -import { FormatTimecode } from '../types'; -import { CaptureFormat } from '../../../common/types'; +import type { FormatTimecode } from '../types'; +import type { CaptureFormat } from '../../../common/types'; const mime = window.require('mime-types'); const { rename, readdir, writeFile } = window.require('fs/promises'); diff --git a/src/renderer/src/hooks/useHtml5ify.tsx b/src/renderer/src/hooks/useHtml5ify.tsx index 7381bee5..cb6e19f8 100644 --- a/src/renderer/src/hooks/useHtml5ify.tsx +++ b/src/renderer/src/hooks/useHtml5ify.tsx @@ -1,16 +1,18 @@ -import { useState, useCallback, ChangeEventHandler } from 'react'; +import type { ChangeEventHandler } from 'react'; +import { useState, useCallback } from 'react'; import i18n from 'i18next'; import { useTranslation } from 'react-i18next'; -import { Html5ifyMode } from '../../../common/types'; +import type { Html5ifyMode } from '../../../common/types'; import { DirectoryAccessDeclinedError } from '../../errors'; import getSwal from '../swal'; import Checkbox from '../components/Checkbox'; import { getSuffixedOutPath, html5dummySuffix, html5ifiedPrefix } from '../util'; -import { SetWorking } from './useLoading'; -import { WithErrorHandling } from './useErrorHandling'; -import { FfmpegOperations } from './useFfmpegOperations'; -import { ShowGenericDialog, useGenericDialogContext } from '../components/GenericDialog'; +import type { SetWorking } from './useLoading'; +import type { WithErrorHandling } from './useErrorHandling'; +import type { FfmpegOperations } from './useFfmpegOperations'; +import type { ShowGenericDialog } from '../components/GenericDialog'; +import { useGenericDialogContext } from '../components/GenericDialog'; import * as Dialog from '../components/Dialog'; import { ButtonRow } from '../components/Dialog'; import { DialogButton } from '../components/Button'; diff --git a/src/renderer/src/hooks/useKeyboard.ts b/src/renderer/src/hooks/useKeyboard.ts index 4c55d083..a1598dff 100644 --- a/src/renderer/src/hooks/useKeyboard.ts +++ b/src/renderer/src/hooks/useKeyboard.ts @@ -1,8 +1,8 @@ import { useCallback, useEffect, useRef, useState } from 'react'; -import { KeyBinding, KeyboardAction } from '../../../common/types'; +import type { KeyBinding, KeyboardAction } from '../../../common/types'; import { allModifiers, altModifiers, controlModifiers, metaModifiers, shiftModifiers } from '../util'; -import { KeyboardLayoutMap } from '../types'; +import type { KeyboardLayoutMap } from '../types'; import isDev from '../isDev'; diff --git a/src/renderer/src/hooks/useKeyframes.ts b/src/renderer/src/hooks/useKeyframes.ts index f4a96956..0d555ea6 100644 --- a/src/renderer/src/hooks/useKeyframes.ts +++ b/src/renderer/src/hooks/useKeyframes.ts @@ -3,10 +3,11 @@ import sortBy from 'lodash/sortBy'; import useDebounceOld from 'react-use/lib/useDebounce'; // Want to phase out this import { useTranslation } from 'react-i18next'; -import { readFramesAroundTime, findNearestKeyFrameTime as ffmpegFindNearestKeyFrameTime, Frame, readFrames } from '../ffmpeg'; -import { FFprobeStream } from '../../../common/ffprobe'; +import type { Frame } from '../ffmpeg'; +import { readFramesAroundTime, findNearestKeyFrameTime as ffmpegFindNearestKeyFrameTime, readFrames } from '../ffmpeg'; +import type { FFprobeStream } from '../../../common/ffprobe'; import { getFrameCountRaw } from '../edlFormats'; -import { HandleError } from '../contexts'; +import type { HandleError } from '../contexts'; const toObj = (map: Frame[]) => Object.fromEntries(map.map((frame) => [frame.time, frame])); diff --git a/src/renderer/src/hooks/useSegments.tsx b/src/renderer/src/hooks/useSegments.tsx index 80986736..037acbfd 100644 --- a/src/renderer/src/hooks/useSegments.tsx +++ b/src/renderer/src/hooks/useSegments.tsx @@ -1,4 +1,5 @@ -import { useCallback, useRef, useMemo, useState, MutableRefObject, FormEvent, useEffect } from 'react'; +import type { MutableRefObject, FormEvent } from 'react'; +import { useCallback, useRef, useMemo, useState, useEffect } from 'react'; import { useStateWithHistory } from 'react-use/lib/useStateWithHistory'; import i18n from 'i18next'; import pMap from 'p-map'; @@ -13,20 +14,23 @@ import { getFileSize, shuffleArray } from '../util'; import { errorToast } from '../swal'; import { createNumSegments as createNumSegmentsDialog, createFixedByteSixedSegments as createFixedByteSixedSegmentsDialog, createRandomSegments as createRandomSegmentsDialog, labelSegmentDialog, askForShiftSegments, askForAlignSegments, selectSegmentsByLabelDialog, askForSegmentDuration, toastError } from '../dialogs'; import { createSegment, sortSegments, invertSegments, combineOverlappingSegments as combineOverlappingSegments2, combineSelectedSegments as combineSelectedSegments2, isDurationValid, addSegmentColorIndex, filterNonMarkers, makeDurationSegments, isInitialSegment } from '../segments'; -import { parameters as allFfmpegParameters, FfmpegDialog, getHint, getLabel } from '../ffmpegParameters'; +import type { FfmpegDialog } from '../ffmpegParameters'; +import { parameters as allFfmpegParameters, getHint, getLabel } from '../ffmpegParameters'; import { maxSegmentsAllowed } from '../util/constants'; -import { DefiniteSegmentBase, ParseTimecode, SegmentBase, segmentTagsSchema, SegmentToExport, StateSegment, UpdateSegAtIndex } from '../types'; +import type { DefiniteSegmentBase, ParseTimecode, SegmentBase, SegmentToExport, StateSegment, UpdateSegAtIndex } from '../types'; +import { segmentTagsSchema } from '../types'; import safeishEval from '../worker/eval'; -import { FFprobeFormat, FFprobeStream } from '../../../common/ffprobe'; -import { HandleError } from '../contexts'; -import { ShowGenericDialog, useGenericDialogContext } from '../components/GenericDialog'; +import type { FFprobeFormat, FFprobeStream } from '../../../common/ffprobe'; +import type { HandleError } from '../contexts'; +import type { ShowGenericDialog } from '../components/GenericDialog'; +import { useGenericDialogContext } from '../components/GenericDialog'; import ExpressionDialog from '../components/ExpressionDialog'; import Button, { DialogButton } from '../components/Button'; import { ButtonRow } from '../components/Dialog'; import * as Dialog from '../components/Dialog'; import { UserFacingError } from '../../errors'; import { editSegmentByExpressionHelpUrl, selectSegmentByExpressionHelpUrl } from '../../../common/constants'; -import { Segment as ScopeSegment } from '../../../common/userTypes'; +import type { Segment as ScopeSegment } from '../../../common/userTypes'; const remote = window.require('@electron/remote'); const { shell } = remote; diff --git a/src/renderer/src/hooks/useSegmentsAutoSave.ts b/src/renderer/src/hooks/useSegmentsAutoSave.ts index 1f0dd7a1..3627e83e 100644 --- a/src/renderer/src/hooks/useSegmentsAutoSave.ts +++ b/src/renderer/src/hooks/useSegmentsAutoSave.ts @@ -6,7 +6,7 @@ import isDev from '../isDev'; import { saveLlcProject } from '../edlStore'; import { mapSaveableSegments } from '../segments'; import { getSuffixedOutPath } from '../util'; -import { StateSegment } from '../types'; +import type { StateSegment } from '../types'; import { errorToast } from '../swal'; import i18n from '../i18n'; diff --git a/src/renderer/src/hooks/useStreamsMeta.tsx b/src/renderer/src/hooks/useStreamsMeta.tsx index 23eee50c..deb00300 100644 --- a/src/renderer/src/hooks/useStreamsMeta.tsx +++ b/src/renderer/src/hooks/useStreamsMeta.tsx @@ -4,14 +4,14 @@ import invariant from 'tiny-invariant'; import { Trans, useTranslation } from 'react-i18next'; import { isStreamThumbnail, shouldCopyStreamByDefault } from '../util/streams'; -import StreamsSelector from '../StreamsSelector'; -import { FFprobeStream } from '../../../common/ffprobe'; -import { FilesMeta } from '../types'; +import type StreamsSelector from '../StreamsSelector'; +import type { FFprobeStream } from '../../../common/ffprobe'; +import type { FilesMeta } from '../types'; import safeishEval from '../worker/eval'; import i18n from '../i18n'; import Action from '../components/Action'; import ExpressionDialog from '../components/ExpressionDialog'; -import { ShowGenericDialog } from '../components/GenericDialog'; +import type { ShowGenericDialog } from '../components/GenericDialog'; export default function useStreamsMeta({ mainStreams, externalFilesMeta, filePath, autoExportExtraStreams, showGenericDialog }: { diff --git a/src/renderer/src/hooks/useSubtitles.ts b/src/renderer/src/hooks/useSubtitles.ts index 602e388c..5b1a7e8c 100644 --- a/src/renderer/src/hooks/useSubtitles.ts +++ b/src/renderer/src/hooks/useSubtitles.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { extractSubtitleTrackVtt } from '../ffmpeg'; -import { FFprobeStream } from '../../../common/ffprobe'; +import type { FFprobeStream } from '../../../common/ffprobe'; export default () => { diff --git a/src/renderer/src/hooks/useThumbnails.ts b/src/renderer/src/hooks/useThumbnails.ts index fa378294..ae6d2875 100644 --- a/src/renderer/src/hooks/useThumbnails.ts +++ b/src/renderer/src/hooks/useThumbnails.ts @@ -4,7 +4,7 @@ import invariant from 'tiny-invariant'; import sortBy from 'lodash/sortBy'; import { renderThumbnails as ffmpegRenderThumbnails } from '../ffmpeg'; -import { Thumbnail } from '../types'; +import type { Thumbnail } from '../types'; import { isDurationValid } from '../segments'; import { isExecaError } from '../util'; diff --git a/src/renderer/src/hooks/useTimecode.tsx b/src/renderer/src/hooks/useTimecode.tsx index e9995e2f..5ae69ef9 100644 --- a/src/renderer/src/hooks/useTimecode.tsx +++ b/src/renderer/src/hooks/useTimecode.tsx @@ -1,12 +1,14 @@ -import { FormEventHandler, useCallback, useMemo, useState } from 'react'; +import type { FormEventHandler } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { FormatTimecode, ParseTimecode } from '../types'; +import type { FormatTimecode, ParseTimecode } from '../types'; import { getFrameCountRaw } from '../edlFormats'; import { getFrameDuration } from '../util'; -import { TimecodeFormat } from '../../../common/types'; +import type { TimecodeFormat } from '../../../common/types'; import { formatDuration, parseDuration } from '../util/duration'; -import { ShowGenericDialog, useGenericDialogContext } from '../components/GenericDialog'; +import type { ShowGenericDialog } from '../components/GenericDialog'; +import { useGenericDialogContext } from '../components/GenericDialog'; import * as Dialog from '../components/Dialog'; import TextInput from '../components/TextInput'; import { ButtonRow } from '../components/Dialog'; diff --git a/src/renderer/src/hooks/useTimelineScroll.ts b/src/renderer/src/hooks/useTimelineScroll.ts index 398acf69..58df6ef7 100644 --- a/src/renderer/src/hooks/useTimelineScroll.ts +++ b/src/renderer/src/hooks/useTimelineScroll.ts @@ -1,8 +1,9 @@ -import { WheelEventHandler, useCallback } from 'react'; +import type { WheelEventHandler } from 'react'; +import { useCallback } from 'react'; import { t } from 'i18next'; import normalizeWheel from './normalizeWheel'; -import { ModifierKey } from '../../../common/types'; +import type { ModifierKey } from '../../../common/types'; import { getMetaKeyName } from '../util'; export const keyMap = { diff --git a/src/renderer/src/hooks/useUserSettingsRoot.ts b/src/renderer/src/hooks/useUserSettingsRoot.ts index 37b13fa5..8a8be678 100644 --- a/src/renderer/src/hooks/useUserSettingsRoot.ts +++ b/src/renderer/src/hooks/useUserSettingsRoot.ts @@ -1,8 +1,8 @@ import { useEffect, useState, useRef, useCallback, useMemo } from 'react'; import i18n from 'i18next'; -import { Transition } from 'framer-motion'; +import type { Transition } from 'framer-motion'; -import { Config } from '../../../common/types.js'; +import type { Config } from '../../../common/types.js'; import { errorToast } from '../swal'; import isDev from '../isDev'; diff --git a/src/renderer/src/hooks/useVideo.ts b/src/renderer/src/hooks/useVideo.ts index 3ce91eba..6a964af5 100644 --- a/src/renderer/src/hooks/useVideo.ts +++ b/src/renderer/src/hooks/useVideo.ts @@ -1,5 +1,6 @@ -import { ReactEventHandler, useCallback, useMemo, useRef, useState } from 'react'; -import { ChromiumHTMLVideoElement, PlaybackMode } from '../types'; +import type { ReactEventHandler } from 'react'; +import { useCallback, useMemo, useRef, useState } from 'react'; +import type { ChromiumHTMLVideoElement, PlaybackMode } from '../types'; import { showPlaybackFailedMessage } from '../swal'; export default ({ filePath }: { filePath: string | undefined }) => { diff --git a/src/renderer/src/hooks/useWaveform.ts b/src/renderer/src/hooks/useWaveform.ts index 9dc49cdf..6150b4c8 100644 --- a/src/renderer/src/hooks/useWaveform.ts +++ b/src/renderer/src/hooks/useWaveform.ts @@ -3,8 +3,8 @@ import sortBy from 'lodash/sortBy'; import invariant from 'tiny-invariant'; import { renderWaveformPng, safeCreateBlob } from '../ffmpeg'; -import { OverviewWaveform, WaveformSlice } from '../types'; -import { FFprobeStream } from '../../../common/ffprobe'; +import type { OverviewWaveform, WaveformSlice } from '../types'; +import type { FFprobeStream } from '../../../common/ffprobe'; const maxWaveforms = 100; diff --git a/src/renderer/src/index.tsx b/src/renderer/src/index.tsx index 36fa12de..eb6cddc7 100644 --- a/src/renderer/src/index.tsx +++ b/src/renderer/src/index.tsx @@ -1,11 +1,10 @@ import { Suspense, StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import { enableMapSet } from 'immer'; -import * as Electron from 'electron'; -import Remote from '@electron/remote'; +import type * as Electron from 'electron'; +import type Remote from '@electron/remote'; import type path from 'node:path'; import type fsPromises from 'node:fs/promises'; -import type fsExtraRaw from 'fs-extra'; import type mimeTypes from 'mime-types'; import type i18nextFsBackend from 'i18next-fs-backend'; import type cueParser from 'cue-parser'; @@ -23,23 +22,20 @@ import '@fontsource/open-sans/700-italic.css'; import '@fontsource/open-sans/800.css'; import '@fontsource/open-sans/800-italic.css'; -import type * as main from '../../main/index'; - +import type { KeyboardLayoutMap } from './types'; import App from './App'; import ErrorBoundary from './ErrorBoundary'; import './i18n'; +import { RemoteApi } from '../../main'; + import './main.css'; import './swal2.scss'; -import { KeyboardLayoutMap } from './types'; - -// something wrong with the tyep -type FsExtra = typeof fsExtraRaw & { exists: (p: string) => Promise }; type TypedRemote = Omit & { require: (module: T) => ( - T extends './index.js' ? typeof main : + T extends './index.js' ? RemoteApi : // eslint-disable-next-line @typescript-eslint/no-explicit-any any ); @@ -54,7 +50,6 @@ declare global { T extends 'node:path' ? typeof path : T extends 'fs/promises' ? typeof fsPromises : T extends 'node:fs/promises' ? typeof fsPromises : - T extends 'fs-extra' ? FsExtra : T extends 'mime-types' ? typeof mimeTypes : T extends 'i18next-fs-backend' ? typeof i18nextFsBackend : T extends 'cue-parser' ? typeof cueParser : diff --git a/src/renderer/src/segments.ts b/src/renderer/src/segments.ts index 15e2de88..7631da8d 100644 --- a/src/renderer/src/segments.ts +++ b/src/renderer/src/segments.ts @@ -4,7 +4,7 @@ import minBy from 'lodash/minBy'; import maxBy from 'lodash/maxBy'; import invariant from 'tiny-invariant'; -import { DefiniteSegmentBase, PlaybackMode, SegmentBase, SegmentTags, SegmentToExport, StateSegment } from './types'; +import type { DefiniteSegmentBase, PlaybackMode, SegmentBase, SegmentTags, SegmentToExport, StateSegment } from './types'; export const isDurationValid = (duration?: number): duration is number => duration != null && Number.isFinite(duration) && duration > 0; diff --git a/src/renderer/src/smartcut.ts b/src/renderer/src/smartcut.ts index 0407bc8f..20c02e08 100644 --- a/src/renderer/src/smartcut.ts +++ b/src/renderer/src/smartcut.ts @@ -3,7 +3,7 @@ import i18n from 'i18next'; import { getRealVideoStreams, getVideoTimebase } from './util/streams'; import { readKeyframesAroundTime, findNextKeyframe, findKeyframeAtExactTime } from './ffmpeg'; -import { FFprobeStream } from '../../common/ffprobe'; +import type { FFprobeStream } from '../../common/ffprobe'; import { UserFacingError } from '../errors'; import { readFileSize } from './util'; diff --git a/src/renderer/src/styles.ts b/src/renderer/src/styles.ts index 14570b84..8d043d13 100644 --- a/src/renderer/src/styles.ts +++ b/src/renderer/src/styles.ts @@ -1,4 +1,4 @@ -import { CSSProperties } from 'react'; +import type { CSSProperties } from 'react'; import { controlsBackground, darkModeTransition } from './colors'; diff --git a/src/renderer/src/swal.ts b/src/renderer/src/swal.ts index b109d176..873a269c 100644 --- a/src/renderer/src/swal.ts +++ b/src/renderer/src/swal.ts @@ -1,6 +1,7 @@ import SwalRaw from 'sweetalert2/dist/sweetalert2.js'; import type { SweetAlertOptions } from 'sweetalert2'; -import withReactContent, { ReactSweetAlert, SweetAlert2 } from 'sweetalert2-react-content'; +import type { ReactSweetAlert, SweetAlert2 } from 'sweetalert2-react-content'; +import withReactContent from 'sweetalert2-react-content'; import i18n from './i18n'; import { emitter as animationsEmitter } from './animations'; diff --git a/src/renderer/src/types.ts b/src/renderer/src/types.ts index afaf8481..572ff524 100644 --- a/src/renderer/src/types.ts +++ b/src/renderer/src/types.ts @@ -1,6 +1,6 @@ import type { MenuItem, MenuItemConstructorOptions } from 'electron'; import { z } from 'zod'; -import { FFprobeChapter, FFprobeFormat, FFprobeStream } from '../../common/ffprobe'; +import type { FFprobeChapter, FFprobeFormat, FFprobeStream } from '../../common/ffprobe'; import type { FileStream } from './ffmpeg'; diff --git a/src/renderer/src/util.ts b/src/renderer/src/util.ts index 53c92111..c00df0d6 100644 --- a/src/renderer/src/util.ts +++ b/src/renderer/src/util.ts @@ -2,23 +2,23 @@ import i18n from 'i18next'; import pMap from 'p-map'; import prettyBytes from 'pretty-bytes'; import sortBy from 'lodash/sortBy'; -import pRetry, { Options } from 'p-retry'; -import { ExecaError } from 'execa'; +import type { Options } from 'p-retry'; +import pRetry from 'p-retry'; +import type { ExecaError } from 'execa'; import confetti from 'canvas-confetti'; import invariant from 'tiny-invariant'; import { ffmpegExtractWindow } from './util/constants'; import { appName } from '../../main/common'; -import { Html5ifyMode } from '../../common/types'; +import type { Html5ifyMode } from '../../common/types'; import { UserFacingError } from '../errors'; -import { FFprobeFormat } from '../../common/ffprobe'; +import type { FFprobeFormat } from '../../common/ffprobe'; const { dirname, parse: parsePath, join, extname, isAbsolute, resolve, basename } = window.require('path'); -const fsExtra = window.require('fs-extra'); -const { stat, lstat, readdir, utimes, unlink } = window.require('fs/promises'); +const { stat, lstat, readdir, utimes, unlink, open, access, constants: { R_OK, W_OK } } = window.require('fs/promises'); const { ipcRenderer } = window.require('electron'); const remote = window.require('@electron/remote'); -const { isWindows, isMac } = remote.require('./index.js'); +const { isWindows, isMac, pathExists } = remote.require('./index.js'); const appVersion = remote.app.getVersion(); const appPath = remote.app.getAppPath(); @@ -69,9 +69,9 @@ export function getSuffixedOutPath({ customOutDir, filePath, nameSuffix }: { cus export async function havePermissionToReadFile(filePath: string) { try { - const fd = await fsExtra.open(filePath, 'r'); + const fd = await open(filePath, 'r'); try { - await fsExtra.close(fd); + await fd.close(); } catch (err) { console.error('Failed to close fd', err); } @@ -84,7 +84,7 @@ export async function havePermissionToReadFile(filePath: string) { export async function checkDirWriteAccess(dirPath: string) { try { - await fsExtra.access(dirPath, fsExtra.constants.W_OK); + await access(dirPath, W_OK); } catch (err) { if (err instanceof Error && 'code' in err) { if (err.code === 'EPERM') return false; // Thrown on Mac (MAS build) when user has not yet allowed access @@ -95,13 +95,9 @@ export async function checkDirWriteAccess(dirPath: string) { return true; } -export async function pathExists(pathIn: string) { - return fsExtra.pathExists(pathIn); -} - export async function getPathReadAccessError(pathIn: string) { try { - await fsExtra.access(pathIn, fsExtra.constants.R_OK); + await access(pathIn, R_OK); return undefined; } catch (err) { return err instanceof Error && 'code' in err && typeof err.code === 'string' ? err.code : undefined; diff --git a/src/renderer/src/util/colors.ts b/src/renderer/src/util/colors.ts index a0f99630..8fc94a57 100644 --- a/src/renderer/src/util/colors.ts +++ b/src/renderer/src/util/colors.ts @@ -1,7 +1,7 @@ import color from 'color'; import invariant from 'tiny-invariant'; -import { SegmentColorIndex } from '../types'; +import type { SegmentColorIndex } from '../types'; // http://phrogz.net/css/distinct-colors.html const colorStrings = '#ff5100, #ffc569, #ddffd1, #00ccff, #e9d1ff, #ff0084, #ff6975, #ffe6d1, #ffff69, #69ff96, #008cff, #ae00ff, #ff002b, #ff8c00, #8cff00, #69ffff, #0044ff, #ff00d4, #ffd1d9'.split(',').map((str) => str.trim()); diff --git a/src/renderer/src/util/outputNameTemplate.ts b/src/renderer/src/util/outputNameTemplate.ts index 6a033830..6f2646df 100644 --- a/src/renderer/src/util/outputNameTemplate.ts +++ b/src/renderer/src/util/outputNameTemplate.ts @@ -1,5 +1,5 @@ import i18n from 'i18next'; -import { PlatformPath } from 'node:path'; +import type { PlatformPath } from 'node:path'; import pMap from 'p-map'; import max from 'lodash/max'; import invariant from 'tiny-invariant'; @@ -9,10 +9,10 @@ import type { FileNameTemplateContext } from '../../../common/userTypes.ts'; import { isMac, isWindows, hasDuplicates, filenamify, getOutFileExtension } from '../util'; import isDev from '../isDev'; import { getSegmentTags, formatSegNum, getGuaranteedSegments } from '../segments'; -import { FileStats, FormatTimecode, SegmentToExport } from '../types'; +import type { FileStats, FormatTimecode, SegmentToExport } from '../types'; import safeishEval from '../worker/eval'; import { UserFacingError } from '../../errors'; -import { FileFfprobeMeta } from '../ffmpeg'; +import type { FileFfprobeMeta } from '../ffmpeg'; export const segNumVariable = 'SEG_NUM'; diff --git a/src/renderer/src/util/streams.test.ts b/src/renderer/src/util/streams.test.ts index 69429f20..4b7476b3 100644 --- a/src/renderer/src/util/streams.test.ts +++ b/src/renderer/src/util/streams.test.ts @@ -1,8 +1,8 @@ import { test, expect } from 'vitest'; import { getMapStreamsArgs, getStreamIdsToCopy } from './streams'; -import { FFprobeStreamDisposition } from '../../../common/ffprobe'; -import { LiteFFprobeStream } from '../types'; +import type { FFprobeStreamDisposition } from '../../../common/ffprobe'; +import type { LiteFFprobeStream } from '../types'; const makeDisposition = (override?: Partial): FFprobeStreamDisposition => ({ diff --git a/src/renderer/src/util/streams.ts b/src/renderer/src/util/streams.ts index db60f577..6ed4d19c 100644 --- a/src/renderer/src/util/streams.ts +++ b/src/renderer/src/util/streams.ts @@ -1,6 +1,6 @@ import invariant from 'tiny-invariant'; -import { FFprobeStream, FFprobeStreamDisposition } from '../../../common/ffprobe'; -import { AllFilesMeta, ChromiumHTMLAudioElement, ChromiumHTMLVideoElement, CopyfileStreams, LiteFFprobeStream } from '../types'; +import type { FFprobeStream, FFprobeStreamDisposition } from '../../../common/ffprobe'; +import type { AllFilesMeta, ChromiumHTMLAudioElement, ChromiumHTMLVideoElement, CopyfileStreams, LiteFFprobeStream } from '../types'; import type { FileStream } from '../ffmpeg'; diff --git a/tsconfig.common.json b/tsconfig.common.json index a5f84c35..eda60050 100644 --- a/tsconfig.common.json +++ b/tsconfig.common.json @@ -6,6 +6,12 @@ "outDir": "common-ts-dist", "tsBuildInfoFile": "common-ts-dist/tsconfig.tsbuildinfo", + + // https://nodejs.org/api/typescript.html + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "erasableSyntaxOnly": true, + "verbatimModuleSyntax": true, }, "include": [ "src/common/**/*", diff --git a/tsconfig.main.json b/tsconfig.main.json index 9a68b2a7..f1542940 100644 --- a/tsconfig.main.json +++ b/tsconfig.main.json @@ -11,6 +11,12 @@ "module": "ESNext", "moduleResolution": "Bundler", "types": ["vite/client"], + + // https://nodejs.org/api/typescript.html + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "erasableSyntaxOnly": true, + "verbatimModuleSyntax": true, }, "references": [ { "path": "./tsconfig.common.json" }, diff --git a/tsconfig.node.json b/tsconfig.node.json index d2814bd2..4b807e3f 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -2,6 +2,12 @@ "extends": ["@tsconfig/strictest", "@tsconfig/node22/tsconfig.json"], "compilerOptions": { "noEmit": true, + + // https://nodejs.org/api/typescript.html + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "erasableSyntaxOnly": true, + "verbatimModuleSyntax": true, }, "include": [ "electron.vite.config.ts", diff --git a/yarn.lock b/yarn.lock index 505fd655..9dfe66a9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35,163 +35,160 @@ __metadata: languageName: node linkType: hard -"@ampproject/remapping@npm:^2.2.0": - version: 2.3.0 - resolution: "@ampproject/remapping@npm:2.3.0" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/code-frame@npm:7.27.1" dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10/f3451525379c68a73eb0a1e65247fbf28c0cccd126d93af21c75fceff77773d43c0d4a2d51978fb131aff25b5f2cb41a9fe48cc296e61ae65e679c4f6918b0ab - languageName: node - linkType: hard - -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.26.2": - version: 7.26.2 - resolution: "@babel/code-frame@npm:7.26.2" - dependencies: - "@babel/helper-validator-identifier": "npm:^7.25.9" + "@babel/helper-validator-identifier": "npm:^7.27.1" js-tokens: "npm:^4.0.0" - picocolors: "npm:^1.0.0" - checksum: 10/db2c2122af79d31ca916755331bb4bac96feb2b334cdaca5097a6b467fdd41963b89b14b6836a14f083de7ff887fc78fa1b3c10b14e743d33e12dbfe5ee3d223 + picocolors: "npm:^1.1.1" + checksum: 10/721b8a6e360a1fa0f1c9fe7351ae6c874828e119183688b533c477aa378f1010f37cc9afbfc4722c686d1f5cdd00da02eab4ba7278a0c504fa0d7a321dcd4fdf languageName: node linkType: hard -"@babel/compat-data@npm:^7.26.5": - version: 7.26.8 - resolution: "@babel/compat-data@npm:7.26.8" - checksum: 10/bdddf577f670e0e12996ef37e134856c8061032edb71a13418c3d4dae8135da28910b7cd6dec6e668ab3a41e42089ef7ee9c54ef52fe0860b54cb420b0d14948 +"@babel/compat-data@npm:^7.27.2": + version: 7.28.5 + resolution: "@babel/compat-data@npm:7.28.5" + checksum: 10/5a5ff00b187049e847f04bd02e21fbd8094544e5016195c2b45e56fa2e311eeb925b158f52a85624c9e6bacc1ce0323e26c303513723d918a8034e347e22610d languageName: node linkType: hard -"@babel/core@npm:^7.24.7, @babel/core@npm:^7.26.0": - version: 7.26.10 - resolution: "@babel/core@npm:7.26.10" +"@babel/core@npm:^7.26.0, @babel/core@npm:^7.28.4": + version: 7.28.5 + resolution: "@babel/core@npm:7.28.5" dependencies: - "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.26.2" - "@babel/generator": "npm:^7.26.10" - "@babel/helper-compilation-targets": "npm:^7.26.5" - "@babel/helper-module-transforms": "npm:^7.26.0" - "@babel/helpers": "npm:^7.26.10" - "@babel/parser": "npm:^7.26.10" - "@babel/template": "npm:^7.26.9" - "@babel/traverse": "npm:^7.26.10" - "@babel/types": "npm:^7.26.10" + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.28.5" + "@babel/helper-compilation-targets": "npm:^7.27.2" + "@babel/helper-module-transforms": "npm:^7.28.3" + "@babel/helpers": "npm:^7.28.4" + "@babel/parser": "npm:^7.28.5" + "@babel/template": "npm:^7.27.2" + "@babel/traverse": "npm:^7.28.5" + "@babel/types": "npm:^7.28.5" + "@jridgewell/remapping": "npm:^2.3.5" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10/68f6707eebd6bb8beed7ceccf5153e35b86c323e40d11d796d75c626ac8f1cc4e1f795584c5ab5f886bc64150c22d5088123d68c069c63f29984c4fc054d1dab + checksum: 10/2f1e224125179f423f4300d605a0c5a3ef315003281a63b1744405b2605ee2a2ffc5b1a8349aa4f262c72eca31c7e1802377ee04ad2b852a2c88f8ace6cac324 languageName: node linkType: hard -"@babel/generator@npm:^7.26.10": - version: 7.26.10 - resolution: "@babel/generator@npm:7.26.10" +"@babel/generator@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/generator@npm:7.28.5" dependencies: - "@babel/parser": "npm:^7.26.10" - "@babel/types": "npm:^7.26.10" - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.25" + "@babel/parser": "npm:^7.28.5" + "@babel/types": "npm:^7.28.5" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" jsesc: "npm:^3.0.2" - checksum: 10/acf5e6544ee672810b598add2451302146cc79e1974fa5d87c5f70d5a51cab140abb628e36c434d01616af3747fd42378379e4b828f3eb9672e84c14f21db46b + checksum: 10/ae618f0a17a6d76c3983e1fd5d9c2f5fdc07703a119efdb813a7d9b8ad4be0a07d4c6f0d718440d2de01a68e321f64e2d63c77fc5d43ae47ae143746ef28ac1f languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.26.5": - version: 7.26.5 - resolution: "@babel/helper-compilation-targets@npm:7.26.5" +"@babel/helper-compilation-targets@npm:^7.27.2": + version: 7.27.2 + resolution: "@babel/helper-compilation-targets@npm:7.27.2" dependencies: - "@babel/compat-data": "npm:^7.26.5" - "@babel/helper-validator-option": "npm:^7.25.9" + "@babel/compat-data": "npm:^7.27.2" + "@babel/helper-validator-option": "npm:^7.27.1" browserslist: "npm:^4.24.0" lru-cache: "npm:^5.1.1" semver: "npm:^6.3.1" - checksum: 10/f3b5f0bfcd7b6adf03be1a494b269782531c6e415afab2b958c077d570371cf1bfe001c442508092c50ed3711475f244c05b8f04457d8dea9c34df2b741522bf + checksum: 10/bd53c30a7477049db04b655d11f4c3500aea3bcbc2497cf02161de2ecf994fec7c098aabbcebe210ffabc2ecbdb1e3ffad23fb4d3f18723b814f423ea1749fe8 languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-module-imports@npm:7.25.9" +"@babel/helper-globals@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/helper-globals@npm:7.28.0" + checksum: 10/91445f7edfde9b65dcac47f4f858f68dc1661bf73332060ab67ad7cc7b313421099a2bfc4bda30c3db3842cfa1e86fffbb0d7b2c5205a177d91b22c8d7d9cb47 + languageName: node + linkType: hard + +"@babel/helper-module-imports@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-module-imports@npm:7.27.1" dependencies: - "@babel/traverse": "npm:^7.25.9" - "@babel/types": "npm:^7.25.9" - checksum: 10/e090be5dee94dda6cd769972231b21ddfae988acd76b703a480ac0c96f3334557d70a965bf41245d6ee43891e7571a8b400ccf2b2be5803351375d0f4e5bcf08 + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10/58e792ea5d4ae71676e0d03d9fef33e886a09602addc3bd01388a98d87df9fcfd192968feb40ac4aedb7e287ec3d0c17b33e3ecefe002592041a91d8a1998a8d languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/helper-module-transforms@npm:7.26.0" +"@babel/helper-module-transforms@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/helper-module-transforms@npm:7.28.3" dependencies: - "@babel/helper-module-imports": "npm:^7.25.9" - "@babel/helper-validator-identifier": "npm:^7.25.9" - "@babel/traverse": "npm:^7.25.9" + "@babel/helper-module-imports": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.3" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10/9841d2a62f61ad52b66a72d08264f23052d533afc4ce07aec2a6202adac0bfe43014c312f94feacb3291f4c5aafe681955610041ece2c276271adce3f570f2f5 + checksum: 10/598fdd8aa5b91f08542d0ba62a737847d0e752c8b95ae2566bc9d11d371856d6867d93e50db870fb836a6c44cfe481c189d8a2b35ca025a224f070624be9fa87 languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.25.9": - version: 7.26.5 - resolution: "@babel/helper-plugin-utils@npm:7.26.5" - checksum: 10/1cc0fd8514da3bb249bed6c27227696ab5e84289749d7258098701cffc0c599b7f61ec40dd332f8613030564b79899d9826813c96f966330bcfc7145a8377857 +"@babel/helper-plugin-utils@npm:^7.25.9, @babel/helper-plugin-utils@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-plugin-utils@npm:7.27.1" + checksum: 10/96136c2428888e620e2ec493c25888f9ceb4a21099dcf3dd4508ea64b58cdedbd5a9fb6c7b352546de84d6c24edafe482318646932a22c449ebd16d16c22d864 languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-string-parser@npm:7.25.9" - checksum: 10/c28656c52bd48e8c1d9f3e8e68ecafd09d949c57755b0d353739eb4eae7ba4f7e67e92e4036f1cd43378cc1397a2c943ed7bcaf5949b04ab48607def0258b775 +"@babel/helper-string-parser@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-string-parser@npm:7.27.1" + checksum: 10/0ae29cc2005084abdae2966afdb86ed14d41c9c37db02c3693d5022fba9f5d59b011d039380b8e537c34daf117c549f52b452398f576e908fb9db3c7abbb3a00 languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.20, @babel/helper-validator-identifier@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-validator-identifier@npm:7.25.9" - checksum: 10/3f9b649be0c2fd457fa1957b694b4e69532a668866b8a0d81eabfa34ba16dbf3107b39e0e7144c55c3c652bf773ec816af8df4a61273a2bb4eb3145ca9cf478e +"@babel/helper-validator-identifier@npm:^7.22.20, @babel/helper-validator-identifier@npm:^7.27.1, @babel/helper-validator-identifier@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-validator-identifier@npm:7.28.5" + checksum: 10/8e5d9b0133702cfacc7f368bf792f0f8ac0483794877c6dca5fcb73810ee138e27527701826fb58a40a004f3a5ec0a2f3c3dd5e326d262530b119918f3132ba7 languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-validator-option@npm:7.25.9" - checksum: 10/9491b2755948ebbdd68f87da907283698e663b5af2d2b1b02a2765761974b1120d5d8d49e9175b167f16f72748ffceec8c9cf62acfbee73f4904507b246e2b3d +"@babel/helper-validator-option@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-option@npm:7.27.1" + checksum: 10/db73e6a308092531c629ee5de7f0d04390835b21a263be2644276cb27da2384b64676cab9f22cd8d8dbd854c92b1d7d56fc8517cf0070c35d1c14a8c828b0903 languageName: node linkType: hard -"@babel/helpers@npm:^7.26.10": - version: 7.26.10 - resolution: "@babel/helpers@npm:7.26.10" +"@babel/helpers@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/helpers@npm:7.28.4" dependencies: - "@babel/template": "npm:^7.26.9" - "@babel/types": "npm:^7.26.10" - checksum: 10/664146257974ccf064b42bd99b1b85717cce2bcebc5068273e13b230ee8bd98d87187c3783706758d76b678ebe0d2f48150eaa6cffc4f77af1342a78ec1cf57a + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.28.4" + checksum: 10/5a70a82e196cf8808f8a449cc4780c34d02edda2bb136d39ce9d26e63b615f18e89a95472230c3ce7695db0d33e7026efeee56f6454ed43480f223007ed205eb languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.26.10, @babel/parser@npm:^7.26.9": - version: 7.26.10 - resolution: "@babel/parser@npm:7.26.10" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/parser@npm:7.28.5" dependencies: - "@babel/types": "npm:^7.26.10" + "@babel/types": "npm:^7.28.5" bin: parser: ./bin/babel-parser.js - checksum: 10/3f87781f46795ba72448168061d9e99c394fdf9cd4aa3ddf053a06334247da4d25d0923ccc89195937d3360d384cee181e99711763c1e8fe81d4f17ee22541fc + checksum: 10/8d9bfb437af6c97a7f6351840b9ac06b4529ba79d6d3def24d6c2996ab38ff7f1f9d301e868ca84a93a3050fadb3d09dbc5105b24634cd281671ac11eebe8df7 languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.24.7" +"@babel/plugin-transform-arrow-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/6720173645826046878015c579c2ca9d93cdba79a2832f0180f5cf147d9817c85bf9c8338b16d6bdaa71f87809b7a194a6902e6c82ec00b6354aca6b40abe5e6 + checksum: 10/62c2cc0ae2093336b1aa1376741c5ed245c0987d9e4b4c5313da4a38155509a7098b5acce582b6781cc0699381420010da2e3086353344abe0a6a0ec38961eb7 languageName: node linkType: hard @@ -224,39 +221,39 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.26.9": - version: 7.26.9 - resolution: "@babel/template@npm:7.26.9" +"@babel/template@npm:^7.27.2": + version: 7.27.2 + resolution: "@babel/template@npm:7.27.2" dependencies: - "@babel/code-frame": "npm:^7.26.2" - "@babel/parser": "npm:^7.26.9" - "@babel/types": "npm:^7.26.9" - checksum: 10/240288cebac95b1cc1cb045ad143365643da0470e905e11731e63280e43480785bd259924f4aea83898ef68e9fa7c176f5f2d1e8b0a059b27966e8ca0b41a1b6 + "@babel/code-frame": "npm:^7.27.1" + "@babel/parser": "npm:^7.27.2" + "@babel/types": "npm:^7.27.1" + checksum: 10/fed15a84beb0b9340e5f81566600dbee5eccd92e4b9cc42a944359b1aa1082373391d9d5fc3656981dff27233ec935d0bc96453cf507f60a4b079463999244d8 languageName: node linkType: hard -"@babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.26.10": - version: 7.26.10 - resolution: "@babel/traverse@npm:7.26.10" +"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/traverse@npm:7.28.5" dependencies: - "@babel/code-frame": "npm:^7.26.2" - "@babel/generator": "npm:^7.26.10" - "@babel/parser": "npm:^7.26.10" - "@babel/template": "npm:^7.26.9" - "@babel/types": "npm:^7.26.10" + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.28.5" + "@babel/helper-globals": "npm:^7.28.0" + "@babel/parser": "npm:^7.28.5" + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.28.5" debug: "npm:^4.3.1" - globals: "npm:^11.1.0" - checksum: 10/e9c77390ce93d1f79fb0d83fc7c67282314ba73fa746ec3cf78e999b2dcda340e200a4fc9d8c5c4ca08f183e1aea2a5c0eb6e4ce802e43c4b10124dbc7d4e748 + checksum: 10/1fce426f5ea494913c40f33298ce219708e703f71cac7ac045ebde64b5a7b17b9275dfa4e05fb92c3f123136913dff62c8113172f4a5de66dab566123dbe7437 languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.10, @babel/types@npm:^7.26.9": - version: 7.26.10 - resolution: "@babel/types@npm:7.26.10" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/types@npm:7.28.5" dependencies: - "@babel/helper-string-parser": "npm:^7.25.9" - "@babel/helper-validator-identifier": "npm:^7.25.9" - checksum: 10/6b4f24ee77af853c2126eaabb65328cd44a7d6f439685131cf929c30567e01b6ea2e5d5653b2c304a09c63a5a6199968f0e27228a007acf35032036d79a9dee6 + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.28.5" + checksum: 10/4256bb9fb2298c4f9b320bde56e625b7091ea8d2433d98dcf524d4086150da0b6555aabd7d0725162670614a9ac5bf036d1134ca13dedc9707f988670f1362d7 languageName: node linkType: hard @@ -521,13 +518,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/aix-ppc64@npm:0.19.12" - conditions: os=aix & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/aix-ppc64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/aix-ppc64@npm:0.20.2" @@ -535,27 +525,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/aix-ppc64@npm:0.21.5" +"@esbuild/aix-ppc64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/aix-ppc64@npm:0.25.12" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/aix-ppc64@npm:0.25.1" +"@esbuild/aix-ppc64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/aix-ppc64@npm:0.27.2" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm64@npm:0.19.12" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/android-arm64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/android-arm64@npm:0.20.2" @@ -563,27 +546,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/android-arm64@npm:0.21.5" +"@esbuild/android-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-arm64@npm:0.25.12" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/android-arm64@npm:0.25.1" +"@esbuild/android-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/android-arm64@npm:0.27.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm@npm:0.19.12" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - "@esbuild/android-arm@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/android-arm@npm:0.20.2" @@ -591,27 +567,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/android-arm@npm:0.21.5" +"@esbuild/android-arm@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-arm@npm:0.25.12" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-arm@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/android-arm@npm:0.25.1" +"@esbuild/android-arm@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/android-arm@npm:0.27.2" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-x64@npm:0.19.12" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - "@esbuild/android-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/android-x64@npm:0.20.2" @@ -619,27 +588,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/android-x64@npm:0.21.5" +"@esbuild/android-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-x64@npm:0.25.12" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/android-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/android-x64@npm:0.25.1" +"@esbuild/android-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/android-x64@npm:0.27.2" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-arm64@npm:0.19.12" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/darwin-arm64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/darwin-arm64@npm:0.20.2" @@ -647,27 +609,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/darwin-arm64@npm:0.21.5" +"@esbuild/darwin-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/darwin-arm64@npm:0.25.12" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/darwin-arm64@npm:0.25.1" +"@esbuild/darwin-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/darwin-arm64@npm:0.27.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-x64@npm:0.19.12" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - "@esbuild/darwin-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/darwin-x64@npm:0.20.2" @@ -675,27 +630,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/darwin-x64@npm:0.21.5" +"@esbuild/darwin-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/darwin-x64@npm:0.25.12" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/darwin-x64@npm:0.25.1" +"@esbuild/darwin-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/darwin-x64@npm:0.27.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-arm64@npm:0.19.12" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/freebsd-arm64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/freebsd-arm64@npm:0.20.2" @@ -703,27 +651,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/freebsd-arm64@npm:0.21.5" +"@esbuild/freebsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/freebsd-arm64@npm:0.25.12" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/freebsd-arm64@npm:0.25.1" +"@esbuild/freebsd-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/freebsd-arm64@npm:0.27.2" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-x64@npm:0.19.12" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/freebsd-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/freebsd-x64@npm:0.20.2" @@ -731,27 +672,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/freebsd-x64@npm:0.21.5" +"@esbuild/freebsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/freebsd-x64@npm:0.25.12" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/freebsd-x64@npm:0.25.1" +"@esbuild/freebsd-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/freebsd-x64@npm:0.27.2" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm64@npm:0.19.12" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/linux-arm64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-arm64@npm:0.20.2" @@ -759,27 +693,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-arm64@npm:0.21.5" +"@esbuild/linux-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-arm64@npm:0.25.12" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-arm64@npm:0.25.1" +"@esbuild/linux-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-arm64@npm:0.27.2" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm@npm:0.19.12" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - "@esbuild/linux-arm@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-arm@npm:0.20.2" @@ -787,27 +714,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-arm@npm:0.21.5" +"@esbuild/linux-arm@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-arm@npm:0.25.12" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-arm@npm:0.25.1" +"@esbuild/linux-arm@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-arm@npm:0.27.2" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ia32@npm:0.19.12" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/linux-ia32@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-ia32@npm:0.20.2" @@ -815,27 +735,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-ia32@npm:0.21.5" +"@esbuild/linux-ia32@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-ia32@npm:0.25.12" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-ia32@npm:0.25.1" +"@esbuild/linux-ia32@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-ia32@npm:0.27.2" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-loong64@npm:0.19.12" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - "@esbuild/linux-loong64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-loong64@npm:0.20.2" @@ -843,27 +756,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-loong64@npm:0.21.5" +"@esbuild/linux-loong64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-loong64@npm:0.25.12" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-loong64@npm:0.25.1" +"@esbuild/linux-loong64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-loong64@npm:0.27.2" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-mips64el@npm:0.19.12" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - "@esbuild/linux-mips64el@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-mips64el@npm:0.20.2" @@ -871,27 +777,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-mips64el@npm:0.21.5" +"@esbuild/linux-mips64el@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-mips64el@npm:0.25.12" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-mips64el@npm:0.25.1" +"@esbuild/linux-mips64el@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-mips64el@npm:0.27.2" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ppc64@npm:0.19.12" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/linux-ppc64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-ppc64@npm:0.20.2" @@ -899,27 +798,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-ppc64@npm:0.21.5" +"@esbuild/linux-ppc64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-ppc64@npm:0.25.12" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-ppc64@npm:0.25.1" +"@esbuild/linux-ppc64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-ppc64@npm:0.27.2" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-riscv64@npm:0.19.12" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - "@esbuild/linux-riscv64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-riscv64@npm:0.20.2" @@ -927,27 +819,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-riscv64@npm:0.21.5" +"@esbuild/linux-riscv64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-riscv64@npm:0.25.12" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-riscv64@npm:0.25.1" +"@esbuild/linux-riscv64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-riscv64@npm:0.27.2" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-s390x@npm:0.19.12" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - "@esbuild/linux-s390x@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-s390x@npm:0.20.2" @@ -955,27 +840,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-s390x@npm:0.21.5" +"@esbuild/linux-s390x@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-s390x@npm:0.25.12" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-s390x@npm:0.25.1" +"@esbuild/linux-s390x@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-s390x@npm:0.27.2" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-x64@npm:0.19.12" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - "@esbuild/linux-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-x64@npm:0.20.2" @@ -983,31 +861,31 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-x64@npm:0.21.5" +"@esbuild/linux-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-x64@npm:0.25.12" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-x64@npm:0.25.1" +"@esbuild/linux-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-x64@npm:0.27.2" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/netbsd-arm64@npm:0.25.1" +"@esbuild/netbsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/netbsd-arm64@npm:0.25.12" conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/netbsd-x64@npm:0.19.12" - conditions: os=netbsd & cpu=x64 +"@esbuild/netbsd-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/netbsd-arm64@npm:0.27.2" + conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard @@ -1018,31 +896,31 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/netbsd-x64@npm:0.21.5" +"@esbuild/netbsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/netbsd-x64@npm:0.25.12" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/netbsd-x64@npm:0.25.1" +"@esbuild/netbsd-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/netbsd-x64@npm:0.27.2" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/openbsd-arm64@npm:0.25.1" +"@esbuild/openbsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openbsd-arm64@npm:0.25.12" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/openbsd-x64@npm:0.19.12" - conditions: os=openbsd & cpu=x64 +"@esbuild/openbsd-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/openbsd-arm64@npm:0.27.2" + conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard @@ -1053,24 +931,31 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/openbsd-x64@npm:0.21.5" +"@esbuild/openbsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openbsd-x64@npm:0.25.12" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/openbsd-x64@npm:0.25.1" +"@esbuild/openbsd-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/openbsd-x64@npm:0.27.2" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/sunos-x64@npm:0.19.12" - conditions: os=sunos & cpu=x64 +"@esbuild/openharmony-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openharmony-arm64@npm:0.25.12" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/openharmony-arm64@npm:0.27.2" + conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard @@ -1081,27 +966,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/sunos-x64@npm:0.21.5" +"@esbuild/sunos-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/sunos-x64@npm:0.25.12" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/sunos-x64@npm:0.25.1" +"@esbuild/sunos-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/sunos-x64@npm:0.27.2" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-arm64@npm:0.19.12" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/win32-arm64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/win32-arm64@npm:0.20.2" @@ -1109,27 +987,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/win32-arm64@npm:0.21.5" +"@esbuild/win32-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-arm64@npm:0.25.12" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/win32-arm64@npm:0.25.1" +"@esbuild/win32-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/win32-arm64@npm:0.27.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-ia32@npm:0.19.12" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/win32-ia32@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/win32-ia32@npm:0.20.2" @@ -1137,27 +1008,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/win32-ia32@npm:0.21.5" +"@esbuild/win32-ia32@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-ia32@npm:0.25.12" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/win32-ia32@npm:0.25.1" +"@esbuild/win32-ia32@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/win32-ia32@npm:0.27.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-x64@npm:0.19.12" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@esbuild/win32-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/win32-x64@npm:0.20.2" @@ -1165,16 +1029,16 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/win32-x64@npm:0.21.5" +"@esbuild/win32-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-x64@npm:0.25.12" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/win32-x64@npm:0.25.1" +"@esbuild/win32-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/win32-x64@npm:0.27.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1584,14 +1448,23 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.5": - version: 0.3.5 - resolution: "@jridgewell/gen-mapping@npm:0.3.5" +"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.13 + resolution: "@jridgewell/gen-mapping@npm:0.3.13" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10/902f8261dcf450b4af7b93f9656918e02eec80a2169e155000cb2059f90113dd98f3ccf6efc6072cee1dd84cac48cade51da236972d942babc40e4c23da4d62a + languageName: node + linkType: hard + +"@jridgewell/remapping@npm:^2.3.5": + version: 2.3.5 + resolution: "@jridgewell/remapping@npm:2.3.5" dependencies: - "@jridgewell/set-array": "npm:^1.2.1" - "@jridgewell/sourcemap-codec": "npm:^1.4.10" + "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10/81587b3c4dd8e6c60252122937cea0c637486311f4ed208b52b62aae2e7a87598f63ec330e6cd0984af494bfb16d3f0d60d3b21d7e5b4aedd2602ff3fe9d32e2 + checksum: 10/c2bb01856e65b506d439455f28aceacf130d6c023d1d4e3b48705e88def3571753e1a887daa04b078b562316c92d26ce36408a60534bceca3f830aec88a339ad languageName: node linkType: hard @@ -1602,27 +1475,20 @@ __metadata: languageName: node linkType: hard -"@jridgewell/set-array@npm:^1.2.1": - version: 1.2.1 - resolution: "@jridgewell/set-array@npm:1.2.1" - checksum: 10/832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 - languageName: node - linkType: hard - -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0": - version: 1.5.0 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" - checksum: 10/4ed6123217569a1484419ac53f6ea0d9f3b57e5b57ab30d7c267bdb27792a27eb0e4b08e84a2680aa55cc2f2b411ffd6ec3db01c44fdc6dc43aca4b55f8374fd +"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10/5d9d207b462c11e322d71911e55e21a4e2772f71ffe8d6f1221b8eb5ae6774458c1d242f897fb0814e8714ca9a6b498abfa74dfe4f434493342902b1a48b33a5 languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": - version: 0.3.25 - resolution: "@jridgewell/trace-mapping@npm:0.3.25" +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.28": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" dependencies: "@jridgewell/resolve-uri": "npm:^3.1.0" "@jridgewell/sourcemap-codec": "npm:^1.4.14" - checksum: 10/dced32160a44b49d531b80a4a2159dceab6b3ddf0c8e95a0deae4b0e894b172defa63d5ac52a19c2068e1fe7d31ea4ba931fbeec103233ecb4208953967120fc + checksum: 10/da0283270e691bdb5543806077548532791608e52386cfbbf3b9e8fb00457859d1bd01d512851161c886eb3a2f3ce6fd9bcf25db8edf3bddedd275bd4a88d606 languageName: node linkType: hard @@ -2521,142 +2387,156 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.40.1" +"@rollup/rollup-android-arm-eabi@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.54.0" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-android-arm64@npm:4.40.1" +"@rollup/rollup-android-arm64@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-android-arm64@npm:4.54.0" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-darwin-arm64@npm:4.40.1" +"@rollup/rollup-darwin-arm64@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.54.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-darwin-x64@npm:4.40.1" +"@rollup/rollup-darwin-x64@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.54.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.40.1" +"@rollup/rollup-freebsd-arm64@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.54.0" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-freebsd-x64@npm:4.40.1" +"@rollup/rollup-freebsd-x64@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-freebsd-x64@npm:4.54.0" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.40.1" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.54.0" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.40.1" +"@rollup/rollup-linux-arm-musleabihf@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.54.0" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.40.1" +"@rollup/rollup-linux-arm64-gnu@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.54.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.40.1" +"@rollup/rollup-linux-arm64-musl@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.54.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loongarch64-gnu@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.40.1" +"@rollup/rollup-linux-loong64-gnu@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.54.0" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.1" +"@rollup/rollup-linux-ppc64-gnu@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.54.0" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.40.1" +"@rollup/rollup-linux-riscv64-gnu@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.54.0" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-musl@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.40.1" +"@rollup/rollup-linux-riscv64-musl@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.54.0" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.40.1" +"@rollup/rollup-linux-s390x-gnu@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.54.0" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.40.1" +"@rollup/rollup-linux-x64-gnu@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.54.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.40.1" +"@rollup/rollup-linux-x64-musl@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.54.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.40.1" +"@rollup/rollup-openharmony-arm64@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.54.0" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.54.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.40.1" +"@rollup/rollup-win32-ia32-msvc@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.54.0" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.40.1": - version: 4.40.1 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.40.1" +"@rollup/rollup-win32-x64-gnu@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-win32-x64-gnu@npm:4.54.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.54.0": + version: 4.54.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.54.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -2682,6 +2562,13 @@ __metadata: languageName: node linkType: hard +"@standard-schema/spec@npm:^1.0.0": + version: 1.1.0 + resolution: "@standard-schema/spec@npm:1.1.0" + checksum: 10/a209615c9e8b2ea535d7db0a5f6aa0f962fd4ab73ee86a46c100fb78116964af1f55a27c1794d4801e534a196794223daa25ff5135021e03c7828aa3d95e1763 + languageName: node + linkType: hard + "@swc/core-darwin-arm64@npm:1.13.19": version: 1.13.19 resolution: "@swc/core-darwin-arm64@npm:1.13.19" @@ -2965,6 +2852,16 @@ __metadata: languageName: node linkType: hard +"@types/chai@npm:^5.2.2": + version: 5.2.3 + resolution: "@types/chai@npm:5.2.3" + dependencies: + "@types/deep-eql": "npm:*" + assertion-error: "npm:^2.0.1" + checksum: 10/e79947307dc235953622e65f83d2683835212357ca261389116ab90bed369ac862ba28b146b4fed08b503ae1e1a12cb93ce783f24bb8d562950469f4320e1c7c + languageName: node + linkType: hard + "@types/color-convert@npm:*": version: 2.0.3 resolution: "@types/color-convert@npm:2.0.3" @@ -3015,6 +2912,13 @@ __metadata: languageName: node linkType: hard +"@types/deep-eql@npm:*": + version: 4.0.2 + resolution: "@types/deep-eql@npm:4.0.2" + checksum: 10/249a27b0bb22f6aa28461db56afa21ec044fa0e303221a62dff81831b20c8530502175f1a49060f7099e7be06181078548ac47c668de79ff9880241968d43d0c + languageName: node + linkType: hard + "@types/eslint@npm:^8": version: 8.56.2 resolution: "@types/eslint@npm:8.56.2" @@ -3034,10 +2938,10 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:1.0.7, @types/estree@npm:^1.0.0": - version: 1.0.7 - resolution: "@types/estree@npm:1.0.7" - checksum: 10/419c845ece767ad4b21171e6e5b63dabb2eb46b9c0d97361edcd9cabbf6a95fcadb91d89b5fa098d1336fa0b8fceaea82fca97a2ef3971f5c86e53031e157b21 +"@types/estree@npm:*, @types/estree@npm:1.0.8, @types/estree@npm:^1.0.0": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: 10/25a4c16a6752538ffde2826c2cc0c6491d90e69cd6187bef4a006dd2c3c45469f049e643d7e516c515f21484dc3d48fd5c870be158a5beb72f5baf3dc43e4099 languageName: node linkType: hard @@ -3635,84 +3539,83 @@ __metadata: languageName: node linkType: hard -"@vitest/expect@npm:3.0.8": - version: 3.0.8 - resolution: "@vitest/expect@npm:3.0.8" +"@vitest/expect@npm:4.0.16": + version: 4.0.16 + resolution: "@vitest/expect@npm:4.0.16" dependencies: - "@vitest/spy": "npm:3.0.8" - "@vitest/utils": "npm:3.0.8" - chai: "npm:^5.2.0" - tinyrainbow: "npm:^2.0.0" - checksum: 10/6cb8a707ff8be140f5d1a5f61a9b0622b2783af1cb591b286e20ebeab9d04081567ef0f9bd697e60b08bc5be0008ea4687b78fb1134e7f3956f2fb06c74c59f8 + "@standard-schema/spec": "npm:^1.0.0" + "@types/chai": "npm:^5.2.2" + "@vitest/spy": "npm:4.0.16" + "@vitest/utils": "npm:4.0.16" + chai: "npm:^6.2.1" + tinyrainbow: "npm:^3.0.3" + checksum: 10/1da98c86d394a4955bef381ac2c63a52d2eec0086f55e18858083da928cfdf51e7a30bfd88b1814e861906dae44d089aeab0fcc67b2597a4a8073c70cd14bdf7 languageName: node linkType: hard -"@vitest/mocker@npm:3.0.8": - version: 3.0.8 - resolution: "@vitest/mocker@npm:3.0.8" +"@vitest/mocker@npm:4.0.16": + version: 4.0.16 + resolution: "@vitest/mocker@npm:4.0.16" dependencies: - "@vitest/spy": "npm:3.0.8" + "@vitest/spy": "npm:4.0.16" estree-walker: "npm:^3.0.3" - magic-string: "npm:^0.30.17" + magic-string: "npm:^0.30.21" peerDependencies: msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 + vite: ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: msw: optional: true vite: optional: true - checksum: 10/456cafc5c2701a3cfffd7549e3bef0313f96672aea1c3f3da449b0d28744b69d466e510afdf6d5ad08beb7126954c75468c8408e099a2faea8733b364c5523fd + checksum: 10/3a34c6571ef278b80d33feabb8389d6cf7cfd248fe592b8b2a373650ab460b95805fde65e6bd76aebc75729fc0c94b4d8b9bba25fa55e21c2745ae03c10316bf languageName: node linkType: hard -"@vitest/pretty-format@npm:3.0.8, @vitest/pretty-format@npm:^3.0.8": - version: 3.0.8 - resolution: "@vitest/pretty-format@npm:3.0.8" +"@vitest/pretty-format@npm:4.0.16": + version: 4.0.16 + resolution: "@vitest/pretty-format@npm:4.0.16" dependencies: - tinyrainbow: "npm:^2.0.0" - checksum: 10/255a7929e814fd8cfd8978ae6342479a8f453ccca97a0a968efbe45b5d39d2c56e1bfa3a5400816f54d3a82c944c8407f7fe2426ec57499a9210bdccf06dbc78 + tinyrainbow: "npm:^3.0.3" + checksum: 10/914d5d35fb3b0aa67f8e6065ac3d1f1798b7774e1ad9d1e873e7c6efdc7925c98e0f8188bb13c4f3feb4d80b756c337f7a55cd4f78c50fe786330d0aaede7cfd languageName: node linkType: hard -"@vitest/runner@npm:3.0.8": - version: 3.0.8 - resolution: "@vitest/runner@npm:3.0.8" +"@vitest/runner@npm:4.0.16": + version: 4.0.16 + resolution: "@vitest/runner@npm:4.0.16" dependencies: - "@vitest/utils": "npm:3.0.8" + "@vitest/utils": "npm:4.0.16" pathe: "npm:^2.0.3" - checksum: 10/d1c3661ed1a5b2ffc3b90b99eac6133b318b2f32ff49e805e153d7128b3a824ff7906eced8d08d7a43b9f34a280432b060c59b2fcede942cde2de4c5684ae003 + checksum: 10/2aed39bb46ba747bd4fd5acf081e9e500192fec19c1887399f6a1701bbfdab05f3d3b45c00e4af5b90a0832853c959a0f64e676b05c67f5457b7c6984f844aa2 languageName: node linkType: hard -"@vitest/snapshot@npm:3.0.8": - version: 3.0.8 - resolution: "@vitest/snapshot@npm:3.0.8" +"@vitest/snapshot@npm:4.0.16": + version: 4.0.16 + resolution: "@vitest/snapshot@npm:4.0.16" dependencies: - "@vitest/pretty-format": "npm:3.0.8" - magic-string: "npm:^0.30.17" + "@vitest/pretty-format": "npm:4.0.16" + magic-string: "npm:^0.30.21" pathe: "npm:^2.0.3" - checksum: 10/61b66ca6a3362de8724fd7cfa17b27a1d59d884693e5c1a2b4edfbcdc75621a7d3314ecb207c88aabff6e6360e7d4ed08c1997ecf3f71e28c485bd590a98919e + checksum: 10/30f2977c96645c018b9d1f658e758f4f886ac63966dca909e9f736d6c9d6d0a6dabdeaedf9abcc13e1000458e4069283632c0140033972847dc1f4b4ac38e076 languageName: node linkType: hard -"@vitest/spy@npm:3.0.8": - version: 3.0.8 - resolution: "@vitest/spy@npm:3.0.8" - dependencies: - tinyspy: "npm:^3.0.2" - checksum: 10/a6be428cedd4052d44ffd90ebd0c422d389f313996e08c5a655148b7d1c5695a94a321c66acc8331e20a3988e3946d4231722a8c5040afe1fe41035e3d390297 +"@vitest/spy@npm:4.0.16": + version: 4.0.16 + resolution: "@vitest/spy@npm:4.0.16" + checksum: 10/76cbabfdd77adf16904d5c128de67abca650bbc2ed36acc68fca548dc51844c7fc1ac516e384d07341b25ae39318c7c2feb499ffa7283a1a838f762cb0cda6ab languageName: node linkType: hard -"@vitest/utils@npm:3.0.8": - version: 3.0.8 - resolution: "@vitest/utils@npm:3.0.8" +"@vitest/utils@npm:4.0.16": + version: 4.0.16 + resolution: "@vitest/utils@npm:4.0.16" dependencies: - "@vitest/pretty-format": "npm:3.0.8" - loupe: "npm:^3.1.3" - tinyrainbow: "npm:^2.0.0" - checksum: 10/207281dc59cd37e4aabb56db4b9bd66d281b4ef314cbed7f9642e61dfcd65bb12d29600291d676f56c3eb82b9831722a59b13f0d65b1a7af4e3ed2a5c18e98b7 + "@vitest/pretty-format": "npm:4.0.16" + tinyrainbow: "npm:^3.0.3" + checksum: 10/07fb3c96867656ff080df7ae6056a8dc23931d0f8bc16e15994c576c580dc6e2dcf71af0964fee197ea7eea4f4ad72c256f56cd3b81599f9e0ba63a228968d50 languageName: node linkType: hard @@ -4566,16 +4469,10 @@ __metadata: languageName: node linkType: hard -"chai@npm:^5.2.0": - version: 5.2.0 - resolution: "chai@npm:5.2.0" - dependencies: - assertion-error: "npm:^2.0.1" - check-error: "npm:^2.1.1" - deep-eql: "npm:^5.0.1" - loupe: "npm:^3.1.0" - pathval: "npm:^2.0.0" - checksum: 10/2ce03671c159c6a567bf1912756daabdbb7c075f3c0078f1b59d61da8d276936367ee696dfe093b49e1479d9ba93a6074c8e55d49791dddd8061728cdcad249e +"chai@npm:^6.2.1": + version: 6.2.2 + resolution: "chai@npm:6.2.2" + checksum: 10/13cda42cc40aa46da04a41cf7e5c61df6b6ae0b4e8a8c8b40e04d6947e4d7951377ea8c14f9fa7fe5aaa9e8bd9ba414f11288dc958d4cee6f5221b9436f2778f languageName: node linkType: hard @@ -4659,13 +4556,6 @@ __metadata: languageName: node linkType: hard -"check-error@npm:^2.1.1": - version: 2.1.1 - resolution: "check-error@npm:2.1.1" - checksum: 10/d785ed17b1d4a4796b6e75c765a9a290098cf52ff9728ce0756e8ffd4293d2e419dd30c67200aee34202463b474306913f2fcfaf1890641026d9fc6966fea27a - languageName: node - linkType: hard - "cheerio-select@npm:^2.1.0": version: 2.1.0 resolution: "cheerio-select@npm:2.1.0" @@ -5318,7 +5208,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.4.0": +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -5357,13 +5247,6 @@ __metadata: languageName: node linkType: hard -"deep-eql@npm:^5.0.1": - version: 5.0.2 - resolution: "deep-eql@npm:5.0.2" - checksum: 10/a529b81e2ef8821621d20a36959a0328873a3e49d393ad11f8efe8559f31239494c2eb889b80342808674c475802ba95b9d6c4c27641b9a029405104c1b59fcf - languageName: node - linkType: hard - "deep-extend@npm:^0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -5750,25 +5633,25 @@ __metadata: languageName: node linkType: hard -"electron-vite@npm:^2.3.0": - version: 2.3.0 - resolution: "electron-vite@npm:2.3.0" +"electron-vite@npm:^5.0.0": + version: 5.0.0 + resolution: "electron-vite@npm:5.0.0" dependencies: - "@babel/core": "npm:^7.24.7" - "@babel/plugin-transform-arrow-functions": "npm:^7.24.7" + "@babel/core": "npm:^7.28.4" + "@babel/plugin-transform-arrow-functions": "npm:^7.27.1" cac: "npm:^6.7.14" - esbuild: "npm:^0.21.5" - magic-string: "npm:^0.30.10" - picocolors: "npm:^1.0.1" + esbuild: "npm:^0.25.11" + magic-string: "npm:^0.30.19" + picocolors: "npm:^1.1.1" peerDependencies: "@swc/core": ^1.0.0 - vite: ^4.0.0 || ^5.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 peerDependenciesMeta: "@swc/core": optional: true bin: electron-vite: bin/electron-vite.js - checksum: 10/893af6745a33f2a6fc0bfa4b933c30a48e7f93472a76ef6bc6f9a10e159e884a352aca2145ad40f8dc082a0e19ab3aec2720ff48fb69d51552e2c87169367c72 + checksum: 10/a64a07c4bd0f2619d04c08fd59e1596c1fa8a437fdb1f7b60be2a025ed0629c4b2ede194501c410e62938bb810136c72e101f7e3407abd91105c9f2011ac4dac languageName: node linkType: hard @@ -5991,10 +5874,10 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^1.6.0": - version: 1.6.0 - resolution: "es-module-lexer@npm:1.6.0" - checksum: 10/807ee7020cc46a9c970c78cad1f2f3fc139877e5ebad7f66dbfbb124d451189ba1c48c1c632bd5f8ce1b8af2caef3fca340ba044a410fa890d17b080a59024bb +"es-module-lexer@npm:^1.7.0": + version: 1.7.0 + resolution: "es-module-lexer@npm:1.7.0" + checksum: 10/b6f3e576a3fed4d82b0d0ad4bbf6b3a5ad694d2e7ce8c4a069560da3db6399381eaba703616a182b16dde50ce998af64e07dcf49f2ae48153b9e07be3f107087 languageName: node linkType: hard @@ -6126,33 +6009,36 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.21.5": - version: 0.21.5 - resolution: "esbuild@npm:0.21.5" - dependencies: - "@esbuild/aix-ppc64": "npm:0.21.5" - "@esbuild/android-arm": "npm:0.21.5" - "@esbuild/android-arm64": "npm:0.21.5" - "@esbuild/android-x64": "npm:0.21.5" - "@esbuild/darwin-arm64": "npm:0.21.5" - "@esbuild/darwin-x64": "npm:0.21.5" - "@esbuild/freebsd-arm64": "npm:0.21.5" - "@esbuild/freebsd-x64": "npm:0.21.5" - "@esbuild/linux-arm": "npm:0.21.5" - "@esbuild/linux-arm64": "npm:0.21.5" - "@esbuild/linux-ia32": "npm:0.21.5" - "@esbuild/linux-loong64": "npm:0.21.5" - "@esbuild/linux-mips64el": "npm:0.21.5" - "@esbuild/linux-ppc64": "npm:0.21.5" - "@esbuild/linux-riscv64": "npm:0.21.5" - "@esbuild/linux-s390x": "npm:0.21.5" - "@esbuild/linux-x64": "npm:0.21.5" - "@esbuild/netbsd-x64": "npm:0.21.5" - "@esbuild/openbsd-x64": "npm:0.21.5" - "@esbuild/sunos-x64": "npm:0.21.5" - "@esbuild/win32-arm64": "npm:0.21.5" - "@esbuild/win32-ia32": "npm:0.21.5" - "@esbuild/win32-x64": "npm:0.21.5" +"esbuild@npm:^0.25.11": + version: 0.25.12 + resolution: "esbuild@npm:0.25.12" + dependencies: + "@esbuild/aix-ppc64": "npm:0.25.12" + "@esbuild/android-arm": "npm:0.25.12" + "@esbuild/android-arm64": "npm:0.25.12" + "@esbuild/android-x64": "npm:0.25.12" + "@esbuild/darwin-arm64": "npm:0.25.12" + "@esbuild/darwin-x64": "npm:0.25.12" + "@esbuild/freebsd-arm64": "npm:0.25.12" + "@esbuild/freebsd-x64": "npm:0.25.12" + "@esbuild/linux-arm": "npm:0.25.12" + "@esbuild/linux-arm64": "npm:0.25.12" + "@esbuild/linux-ia32": "npm:0.25.12" + "@esbuild/linux-loong64": "npm:0.25.12" + "@esbuild/linux-mips64el": "npm:0.25.12" + "@esbuild/linux-ppc64": "npm:0.25.12" + "@esbuild/linux-riscv64": "npm:0.25.12" + "@esbuild/linux-s390x": "npm:0.25.12" + "@esbuild/linux-x64": "npm:0.25.12" + "@esbuild/netbsd-arm64": "npm:0.25.12" + "@esbuild/netbsd-x64": "npm:0.25.12" + "@esbuild/openbsd-arm64": "npm:0.25.12" + "@esbuild/openbsd-x64": "npm:0.25.12" + "@esbuild/openharmony-arm64": "npm:0.25.12" + "@esbuild/sunos-x64": "npm:0.25.12" + "@esbuild/win32-arm64": "npm:0.25.12" + "@esbuild/win32-ia32": "npm:0.25.12" + "@esbuild/win32-x64": "npm:0.25.12" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -6188,10 +6074,16 @@ __metadata: optional: true "@esbuild/linux-x64": optional: true + "@esbuild/netbsd-arm64": + optional: true "@esbuild/netbsd-x64": optional: true + "@esbuild/openbsd-arm64": + optional: true "@esbuild/openbsd-x64": optional: true + "@esbuild/openharmony-arm64": + optional: true "@esbuild/sunos-x64": optional: true "@esbuild/win32-arm64": @@ -6202,39 +6094,40 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10/d2ff2ca84d30cce8e871517374d6c2290835380dc7cd413b2d49189ed170d45e407be14de2cb4794cf76f75cf89955c4714726ebd3de7444b3046f5cab23ab6b - languageName: node - linkType: hard - -"esbuild@npm:^0.25.0": - version: 0.25.1 - resolution: "esbuild@npm:0.25.1" - dependencies: - "@esbuild/aix-ppc64": "npm:0.25.1" - "@esbuild/android-arm": "npm:0.25.1" - "@esbuild/android-arm64": "npm:0.25.1" - "@esbuild/android-x64": "npm:0.25.1" - "@esbuild/darwin-arm64": "npm:0.25.1" - "@esbuild/darwin-x64": "npm:0.25.1" - "@esbuild/freebsd-arm64": "npm:0.25.1" - "@esbuild/freebsd-x64": "npm:0.25.1" - "@esbuild/linux-arm": "npm:0.25.1" - "@esbuild/linux-arm64": "npm:0.25.1" - "@esbuild/linux-ia32": "npm:0.25.1" - "@esbuild/linux-loong64": "npm:0.25.1" - "@esbuild/linux-mips64el": "npm:0.25.1" - "@esbuild/linux-ppc64": "npm:0.25.1" - "@esbuild/linux-riscv64": "npm:0.25.1" - "@esbuild/linux-s390x": "npm:0.25.1" - "@esbuild/linux-x64": "npm:0.25.1" - "@esbuild/netbsd-arm64": "npm:0.25.1" - "@esbuild/netbsd-x64": "npm:0.25.1" - "@esbuild/openbsd-arm64": "npm:0.25.1" - "@esbuild/openbsd-x64": "npm:0.25.1" - "@esbuild/sunos-x64": "npm:0.25.1" - "@esbuild/win32-arm64": "npm:0.25.1" - "@esbuild/win32-ia32": "npm:0.25.1" - "@esbuild/win32-x64": "npm:0.25.1" + checksum: 10/bc9c03d64e96a0632a926662c9d29decafb13a40e5c91790f632f02939bc568edc9abe0ee5d8055085a2819a00139eb12e223cfb8126dbf89bbc569f125d91fd + languageName: node + linkType: hard + +"esbuild@npm:^0.27.0": + version: 0.27.2 + resolution: "esbuild@npm:0.27.2" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.2" + "@esbuild/android-arm": "npm:0.27.2" + "@esbuild/android-arm64": "npm:0.27.2" + "@esbuild/android-x64": "npm:0.27.2" + "@esbuild/darwin-arm64": "npm:0.27.2" + "@esbuild/darwin-x64": "npm:0.27.2" + "@esbuild/freebsd-arm64": "npm:0.27.2" + "@esbuild/freebsd-x64": "npm:0.27.2" + "@esbuild/linux-arm": "npm:0.27.2" + "@esbuild/linux-arm64": "npm:0.27.2" + "@esbuild/linux-ia32": "npm:0.27.2" + "@esbuild/linux-loong64": "npm:0.27.2" + "@esbuild/linux-mips64el": "npm:0.27.2" + "@esbuild/linux-ppc64": "npm:0.27.2" + "@esbuild/linux-riscv64": "npm:0.27.2" + "@esbuild/linux-s390x": "npm:0.27.2" + "@esbuild/linux-x64": "npm:0.27.2" + "@esbuild/netbsd-arm64": "npm:0.27.2" + "@esbuild/netbsd-x64": "npm:0.27.2" + "@esbuild/openbsd-arm64": "npm:0.27.2" + "@esbuild/openbsd-x64": "npm:0.27.2" + "@esbuild/openharmony-arm64": "npm:0.27.2" + "@esbuild/sunos-x64": "npm:0.27.2" + "@esbuild/win32-arm64": "npm:0.27.2" + "@esbuild/win32-ia32": "npm:0.27.2" + "@esbuild/win32-x64": "npm:0.27.2" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -6278,85 +6171,7 @@ __metadata: optional: true "@esbuild/openbsd-x64": optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 10/f1dcaa7c72133c4e130dc7a6c05158d48d7ccf6643efb12fd0c5a9727226a9249d3ea4a4ea34f879c4559819d9dd706a968fd34d5c180ae019ea0403246c5564 - languageName: node - linkType: hard - -"esbuild@npm:~0.19.10": - version: 0.19.12 - resolution: "esbuild@npm:0.19.12" - dependencies: - "@esbuild/aix-ppc64": "npm:0.19.12" - "@esbuild/android-arm": "npm:0.19.12" - "@esbuild/android-arm64": "npm:0.19.12" - "@esbuild/android-x64": "npm:0.19.12" - "@esbuild/darwin-arm64": "npm:0.19.12" - "@esbuild/darwin-x64": "npm:0.19.12" - "@esbuild/freebsd-arm64": "npm:0.19.12" - "@esbuild/freebsd-x64": "npm:0.19.12" - "@esbuild/linux-arm": "npm:0.19.12" - "@esbuild/linux-arm64": "npm:0.19.12" - "@esbuild/linux-ia32": "npm:0.19.12" - "@esbuild/linux-loong64": "npm:0.19.12" - "@esbuild/linux-mips64el": "npm:0.19.12" - "@esbuild/linux-ppc64": "npm:0.19.12" - "@esbuild/linux-riscv64": "npm:0.19.12" - "@esbuild/linux-s390x": "npm:0.19.12" - "@esbuild/linux-x64": "npm:0.19.12" - "@esbuild/netbsd-x64": "npm:0.19.12" - "@esbuild/openbsd-x64": "npm:0.19.12" - "@esbuild/sunos-x64": "npm:0.19.12" - "@esbuild/win32-arm64": "npm:0.19.12" - "@esbuild/win32-ia32": "npm:0.19.12" - "@esbuild/win32-x64": "npm:0.19.12" - dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": + "@esbuild/openharmony-arm64": optional: true "@esbuild/sunos-x64": optional: true @@ -6368,7 +6183,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10/861fa8eb2428e8d6521a4b7c7930139e3f45e8d51a86985cc29408172a41f6b18df7b3401e7e5e2d528cdf83742da601ddfdc77043ddc4f1c715a8ddb2d8a255 + checksum: 10/7f1229328b0efc63c4184a61a7eb303df1e99818cc1d9e309fb92600703008e69821e8e984e9e9f54a627da14e0960d561db3a93029482ef96dc82dd267a60c2 languageName: node linkType: hard @@ -6733,7 +6548,7 @@ __metadata: languageName: node linkType: hard -"execa@npm:9.6.0, execa@npm:^9.5.1": +"execa@npm:9.6.0": version: 9.6.0 resolution: "execa@npm:9.6.0" dependencies: @@ -6753,6 +6568,26 @@ __metadata: languageName: node linkType: hard +"execa@npm:^9.5.1": + version: 9.6.1 + resolution: "execa@npm:9.6.1" + dependencies: + "@sindresorhus/merge-streams": "npm:^4.0.0" + cross-spawn: "npm:^7.0.6" + figures: "npm:^6.1.0" + get-stream: "npm:^9.0.0" + human-signals: "npm:^8.0.1" + is-plain-obj: "npm:^4.1.0" + is-stream: "npm:^4.0.1" + npm-run-path: "npm:^6.0.0" + pretty-ms: "npm:^9.2.0" + signal-exit: "npm:^4.1.0" + strip-final-newline: "npm:^4.0.0" + yoctocolors: "npm:^2.1.1" + checksum: 10/d0f7a2185152379f8772f6d780b188f2728a95b9a68d1a897f58805d7ba6bd55eaa5e128cb66a274251a6b5e4d9388332b1417bd7d46c25e020e4e55725cf79e + languageName: node + linkType: hard + "expand-template@npm:^2.0.3": version: 2.0.3 resolution: "expand-template@npm:2.0.3" @@ -6760,10 +6595,10 @@ __metadata: languageName: node linkType: hard -"expect-type@npm:^1.1.0": - version: 1.1.0 - resolution: "expect-type@npm:1.1.0" - checksum: 10/05fca80ddc7d493a89361f783c6b000750fa04a8226bc24701f3b90adb0efc2fb467f2a0baaed4015a02d8b9034ef5bb87521df9dba980f50b1105bd596ef833 +"expect-type@npm:^1.2.2": + version: 1.3.0 + resolution: "expect-type@npm:1.3.0" + checksum: 10/a5fada3d0c621649261f886e7d93e6bf80ce26d8a86e5d517e38301b8baec8450ab2cb94ba6e7a0a6bf2fc9ee55f54e1b06938ef1efa52ddcfeffbfa01acbbcc languageName: node linkType: hard @@ -6944,7 +6779,7 @@ __metadata: languageName: node linkType: hard -"fdir@npm:^6.4.4, fdir@npm:^6.5.0": +"fdir@npm:^6.5.0": version: 6.5.0 resolution: "fdir@npm:6.5.0" peerDependencies: @@ -7414,15 +7249,6 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:^4.7.2": - version: 4.7.3 - resolution: "get-tsconfig@npm:4.7.3" - dependencies: - resolve-pkg-maps: "npm:^1.0.0" - checksum: 10/7397bb4f8aef936df4d9016555b662dcf5279f3c46428b7c7c1ff5e94ab2b87d018b3dda0f4bc1a28b154d5affd0eac5d014511172c085fd8a9cdff9ea7fe043 - languageName: node - linkType: hard - "github-from-package@npm:0.0.0": version: 0.0.0 resolution: "github-from-package@npm:0.0.0" @@ -7537,13 +7363,6 @@ __metadata: languageName: node linkType: hard -"globals@npm:^11.1.0": - version: 11.12.0 - resolution: "globals@npm:11.12.0" - checksum: 10/9f054fa38ff8de8fa356502eb9d2dae0c928217b8b5c8de1f09f5c9b6c8a96d8b9bd3afc49acbcd384a98a81fea713c859e1b09e214c60509517bb8fc2bc13c2 - languageName: node - linkType: hard - "globals@npm:^13.19.0": version: 13.24.0 resolution: "globals@npm:13.24.0" @@ -9136,7 +8955,7 @@ __metadata: electron-devtools-installer: "npm:^4.0.0" electron-store: "npm:5.1.1" electron-unhandled: "npm:^5.0.0" - electron-vite: "npm:^2.3.0" + electron-vite: "npm:^5.0.0" eslint: "npm:^8.2.0" eslint-config-mifi: "npm:^0.0.3" eslint-plugin-import: "npm:^2.25.3" @@ -9150,7 +8969,6 @@ __metadata: fast-xml-parser: "npm:^4.4.1" file-type: "patch:file-type@npm%3A19.4.1#~/.yarn/patches/file-type-npm-19.4.1-d18086444c.patch" framer-motion: "npm:^9.0.3" - fs-extra: "npm:^8.1.0" i18next: "npm:^25.6.1" i18next-cli: "npm:^1.23.7" i18next-fs-backend: "npm:^2.3.2" @@ -9193,13 +9011,12 @@ __metadata: sweetalert2-react-content: "npm:^5.0.7" tiny-invariant: "npm:^1.3.3" ts-morph: "npm:^27.0.2" - tsx: "npm:^4.7.1" type-fest: "npm:^4.23.0" typescript: "npm:^5.9.3" use-debounce: "npm:^5.1.0" use-trace-update: "npm:^1.3.0" - vite: "npm:^6.4.1" - vitest: "npm:^3.0.8" + vite: "npm:^7.3.0" + vitest: "npm:^4.0.16" winston: "npm:^3.8.1" yargs-parser: "npm:^21.1.1" zod: "npm:^3.22.5" @@ -9213,13 +9030,6 @@ __metadata: languageName: node linkType: hard -"loupe@npm:^3.1.0, loupe@npm:^3.1.3": - version: 3.1.3 - resolution: "loupe@npm:3.1.3" - checksum: 10/9e98c34daf0eba48ccc603595e51f2ae002110982d84879cf78c51de2c632f0c571dfe82ce4210af60c32203d06b443465c269bda925076fe6d9b612cc65c321 - languageName: node - linkType: hard - "lowercase-keys@npm:^2.0.0": version: 2.0.0 resolution: "lowercase-keys@npm:2.0.0" @@ -9283,12 +9093,12 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.10, magic-string@npm:^0.30.17": - version: 0.30.17 - resolution: "magic-string@npm:0.30.17" +"magic-string@npm:^0.30.19, magic-string@npm:^0.30.21": + version: 0.30.21 + resolution: "magic-string@npm:0.30.21" dependencies: - "@jridgewell/sourcemap-codec": "npm:^1.5.0" - checksum: 10/2f71af2b0afd78c2e9012a29b066d2c8ba45a9cd0c8070f7fd72de982fb1c403b4e3afdb1dae00691d56885ede66b772ef6bedf765e02e3a7066208fe2fec4aa + "@jridgewell/sourcemap-codec": "npm:^1.5.5" + checksum: 10/57d5691f41ed40d962d8bd300148114f53db67fadbff336207db10a99f2bdf4a1be9cac3a68ee85dba575912ee1d4402e4396408196ec2d3afd043b076156221 languageName: node linkType: hard @@ -10052,12 +9862,12 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.8": - version: 3.3.9 - resolution: "nanoid@npm:3.3.9" +"nanoid@npm:^3.3.11": + version: 3.3.11 + resolution: "nanoid@npm:3.3.11" bin: nanoid: bin/nanoid.cjs - checksum: 10/80ec0f2f7fe0f472f459fbeab6afd88f6739e3da94cf2c2307bc83ef0203ec3b72e6113a9e3196ac4be79540440184136ee96e77c10a965e37d8347f43b265fa + checksum: 10/73b5afe5975a307aaa3c95dfe3334c52cdf9ae71518176895229b8d65ab0d1c0417dd081426134eb7571c055720428ea5d57c645138161e7d10df80815527c48 languageName: node linkType: hard @@ -10320,6 +10130,13 @@ __metadata: languageName: node linkType: hard +"obug@npm:^2.1.1": + version: 2.1.1 + resolution: "obug@npm:2.1.1" + checksum: 10/bdcf9213361786688019345f3452b95a1dc73710e4b403c82a1994b98bad6abc31b26cb72a482128c5fd53ea9daf6fbb7d0e0e7b2b7e9c8be6d779deeccee07f + languageName: node + linkType: hard + "on-finished@npm:2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" @@ -10711,13 +10528,6 @@ __metadata: languageName: node linkType: hard -"pathval@npm:^2.0.0": - version: 2.0.0 - resolution: "pathval@npm:2.0.0" - checksum: 10/b91575bf9cdf01757afd7b5e521eb8a0b874a49bc972d08e0047cfea0cd3c019f5614521d4bc83d2855e3fcc331db6817dfd533dd8f3d90b16bc76fad2450fc1 - languageName: node - linkType: hard - "pe-library@npm:^0.4.1": version: 0.4.1 resolution: "pe-library@npm:0.4.1" @@ -10739,7 +10549,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.1": +"picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 @@ -10753,7 +10563,7 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3": +"picomatch@npm:^4.0.3": version: 4.0.3 resolution: "picomatch@npm:4.0.3" checksum: 10/57b99055f40b16798f2802916d9c17e9744e620a0db136554af01d19598b96e45e2f00014c91d1b8b13874b80caa8c295b3d589a3f72373ec4aaf54baa5962d5 @@ -10801,14 +10611,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.5.3": - version: 8.5.3 - resolution: "postcss@npm:8.5.3" +"postcss@npm:^8.5.6": + version: 8.5.6 + resolution: "postcss@npm:8.5.6" dependencies: - nanoid: "npm:^3.3.8" + nanoid: "npm:^3.3.11" picocolors: "npm:^1.1.1" source-map-js: "npm:^1.2.1" - checksum: 10/6d7e21a772e8b05bf102636918654dac097bac013f0dc8346b72ac3604fc16829646f94ea862acccd8f82e910b00e2c11c1f0ea276543565d278c7ca35516a7c + checksum: 10/9e4fbe97574091e9736d0e82a591e29aa100a0bf60276a926308f8c57249698935f35c5d2f4e80de778d0cbb8dcffab4f383d85fd50c5649aca421c3df729b86 languageName: node linkType: hard @@ -11495,13 +11305,6 @@ __metadata: languageName: node linkType: hard -"resolve-pkg-maps@npm:^1.0.0": - version: 1.0.0 - resolution: "resolve-pkg-maps@npm:1.0.0" - checksum: 10/0763150adf303040c304009231314d1e84c6e5ebfa2d82b7d94e96a6e82bacd1dcc0b58ae257315f3c8adb89a91d8d0f12928241cba2df1680fbe6f60bf99b0e - languageName: node - linkType: hard - "resolve@npm:^1.10.0, resolve@npm:^1.22.4": version: 1.22.8 resolution: "resolve@npm:1.22.8" @@ -11658,31 +11461,33 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^4.34.9": - version: 4.40.1 - resolution: "rollup@npm:4.40.1" - dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.40.1" - "@rollup/rollup-android-arm64": "npm:4.40.1" - "@rollup/rollup-darwin-arm64": "npm:4.40.1" - "@rollup/rollup-darwin-x64": "npm:4.40.1" - "@rollup/rollup-freebsd-arm64": "npm:4.40.1" - "@rollup/rollup-freebsd-x64": "npm:4.40.1" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.40.1" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.40.1" - "@rollup/rollup-linux-arm64-gnu": "npm:4.40.1" - "@rollup/rollup-linux-arm64-musl": "npm:4.40.1" - "@rollup/rollup-linux-loongarch64-gnu": "npm:4.40.1" - "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.40.1" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.40.1" - "@rollup/rollup-linux-riscv64-musl": "npm:4.40.1" - "@rollup/rollup-linux-s390x-gnu": "npm:4.40.1" - "@rollup/rollup-linux-x64-gnu": "npm:4.40.1" - "@rollup/rollup-linux-x64-musl": "npm:4.40.1" - "@rollup/rollup-win32-arm64-msvc": "npm:4.40.1" - "@rollup/rollup-win32-ia32-msvc": "npm:4.40.1" - "@rollup/rollup-win32-x64-msvc": "npm:4.40.1" - "@types/estree": "npm:1.0.7" +"rollup@npm:^4.43.0": + version: 4.54.0 + resolution: "rollup@npm:4.54.0" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.54.0" + "@rollup/rollup-android-arm64": "npm:4.54.0" + "@rollup/rollup-darwin-arm64": "npm:4.54.0" + "@rollup/rollup-darwin-x64": "npm:4.54.0" + "@rollup/rollup-freebsd-arm64": "npm:4.54.0" + "@rollup/rollup-freebsd-x64": "npm:4.54.0" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.54.0" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.54.0" + "@rollup/rollup-linux-arm64-gnu": "npm:4.54.0" + "@rollup/rollup-linux-arm64-musl": "npm:4.54.0" + "@rollup/rollup-linux-loong64-gnu": "npm:4.54.0" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.54.0" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.54.0" + "@rollup/rollup-linux-riscv64-musl": "npm:4.54.0" + "@rollup/rollup-linux-s390x-gnu": "npm:4.54.0" + "@rollup/rollup-linux-x64-gnu": "npm:4.54.0" + "@rollup/rollup-linux-x64-musl": "npm:4.54.0" + "@rollup/rollup-openharmony-arm64": "npm:4.54.0" + "@rollup/rollup-win32-arm64-msvc": "npm:4.54.0" + "@rollup/rollup-win32-ia32-msvc": "npm:4.54.0" + "@rollup/rollup-win32-x64-gnu": "npm:4.54.0" + "@rollup/rollup-win32-x64-msvc": "npm:4.54.0" + "@types/estree": "npm:1.0.8" fsevents: "npm:~2.3.2" dependenciesMeta: "@rollup/rollup-android-arm-eabi": @@ -11705,9 +11510,9 @@ __metadata: optional: true "@rollup/rollup-linux-arm64-musl": optional: true - "@rollup/rollup-linux-loongarch64-gnu": + "@rollup/rollup-linux-loong64-gnu": optional: true - "@rollup/rollup-linux-powerpc64le-gnu": + "@rollup/rollup-linux-ppc64-gnu": optional: true "@rollup/rollup-linux-riscv64-gnu": optional: true @@ -11719,17 +11524,21 @@ __metadata: optional: true "@rollup/rollup-linux-x64-musl": optional: true + "@rollup/rollup-openharmony-arm64": + optional: true "@rollup/rollup-win32-arm64-msvc": optional: true "@rollup/rollup-win32-ia32-msvc": optional: true + "@rollup/rollup-win32-x64-gnu": + optional: true "@rollup/rollup-win32-x64-msvc": optional: true fsevents: optional: true bin: rollup: dist/bin/rollup - checksum: 10/35d5e83a69000ddd6c087015eb5f862943c53b6e20702575ef50aeb99ce99b864fa74cca630815eb97cdfe1f278f5602f782e55f227b32ac2301f2a5f1fc5373 + checksum: 10/f6e07128386965863073fd5a5cf03b1b6fd917b2e53c5df8bfa68bf8e69d3da907d0bf73e35b1702bc774e4a8b7d830b90f929930a0fab8e72594c0db8b4a6b7 languageName: node linkType: hard @@ -12388,10 +12197,10 @@ __metadata: languageName: node linkType: hard -"std-env@npm:^3.8.0": - version: 3.8.0 - resolution: "std-env@npm:3.8.0" - checksum: 10/034176196cfcaaab16dbdd96fc9e925a9544799fb6dc5a3e36fe43270f3a287c7f779d785b89edaf22cef2b5f1dcada2aae67430b8602e785ee74bdb3f671768 +"std-env@npm:^3.10.0": + version: 3.10.0 + resolution: "std-env@npm:3.10.0" + checksum: 10/19c9cda4f370b1ffae2b8b08c72167d8c3e5cfa972aaf5c6873f85d0ed2faa729407f5abb194dc33380708c00315002febb6f1e1b484736bfcf9361ad366013a languageName: node linkType: hard @@ -12853,14 +12662,14 @@ __metadata: languageName: node linkType: hard -"tinyexec@npm:^0.3.2": - version: 0.3.2 - resolution: "tinyexec@npm:0.3.2" - checksum: 10/b9d5fed3166fb1acd1e7f9a89afcd97ccbe18b9c1af0278e429455f6976d69271ba2d21797e7c36d57d6b05025e525d2882d88c2ab435b60d1ddf2fea361de57 +"tinyexec@npm:^1.0.2": + version: 1.0.2 + resolution: "tinyexec@npm:1.0.2" + checksum: 10/cb709ed4240e873d3816e67f851d445f5676e0ae3a52931a60ff571d93d388da09108c8057b62351766133ee05ff3159dd56c3a0fbd39a5933c6639ce8771405 languageName: node linkType: hard -"tinyglobby@npm:^0.2.13, tinyglobby@npm:^0.2.14": +"tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" dependencies: @@ -12870,24 +12679,10 @@ __metadata: languageName: node linkType: hard -"tinypool@npm:^1.0.2": - version: 1.0.2 - resolution: "tinypool@npm:1.0.2" - checksum: 10/6109322f14b3763f65c8fa49fddab72cd3edd96b82dd50e05e63de74867329ff5353bff4377281ec963213d9314f37f4a353e9ee34bbac85fd4c1e4a568d6076 - languageName: node - linkType: hard - -"tinyrainbow@npm:^2.0.0": - version: 2.0.0 - resolution: "tinyrainbow@npm:2.0.0" - checksum: 10/94d4e16246972614a5601eeb169ba94f1d49752426312d3cf8cc4f2cc663a2e354ffc653aa4de4eebccbf9eeebdd0caef52d1150271fdfde65d7ae7f3dcb9eb5 - languageName: node - linkType: hard - -"tinyspy@npm:^3.0.2": - version: 3.0.2 - resolution: "tinyspy@npm:3.0.2" - checksum: 10/5db671b2ff5cd309de650c8c4761ca945459d7204afb1776db9a04fb4efa28a75f08517a8620c01ee32a577748802231ad92f7d5b194dc003ee7f987a2a06337 +"tinyrainbow@npm:^3.0.3": + version: 3.0.3 + resolution: "tinyrainbow@npm:3.0.3" + checksum: 10/169cc63c15e1378674180f3207c82c05bfa58fc79992e48792e8d97b4b759012f48e95297900ede24a81f0087cf329a0d85bb81109739eacf03c650127b3f6c1 languageName: node linkType: hard @@ -13049,22 +12844,6 @@ __metadata: languageName: node linkType: hard -"tsx@npm:^4.7.1": - version: 4.7.1 - resolution: "tsx@npm:4.7.1" - dependencies: - esbuild: "npm:~0.19.10" - fsevents: "npm:~2.3.3" - get-tsconfig: "npm:^4.7.2" - dependenciesMeta: - fsevents: - optional: true - bin: - tsx: dist/cli.mjs - checksum: 10/3a462b595f31ae58b31f9c6e8c450577dc87660b1225012bd972b6b58d7d2f6c4034728763ebc53bb731acff68de8b0fa50586e4c1ec4c086226f1788ccf9b7d - languageName: node - linkType: hard - "tunnel-agent@npm:^0.6.0": version: 0.6.0 resolution: "tunnel-agent@npm:0.6.0" @@ -13596,41 +13375,26 @@ __metadata: languageName: node linkType: hard -"vite-node@npm:3.0.8": - version: 3.0.8 - resolution: "vite-node@npm:3.0.8" - dependencies: - cac: "npm:^6.7.14" - debug: "npm:^4.4.0" - es-module-lexer: "npm:^1.6.0" - pathe: "npm:^2.0.3" - vite: "npm:^5.0.0 || ^6.0.0" - bin: - vite-node: vite-node.mjs - checksum: 10/9a06d27d9f56f17cf9586cd36f19e4c275227f55f0d9b71c0002d7dbe1a76398cac836b639e2c2537be67f16adb33c40d6d64d3640a97696ebfdfd731e5ea13f - languageName: node - linkType: hard - -"vite@npm:^5.0.0 || ^6.0.0, vite@npm:^6.4.1": - version: 6.4.1 - resolution: "vite@npm:6.4.1" +"vite@npm:^6.0.0 || ^7.0.0, vite@npm:^7.3.0": + version: 7.3.0 + resolution: "vite@npm:7.3.0" dependencies: - esbuild: "npm:^0.25.0" - fdir: "npm:^6.4.4" + esbuild: "npm:^0.27.0" + fdir: "npm:^6.5.0" fsevents: "npm:~2.3.3" - picomatch: "npm:^4.0.2" - postcss: "npm:^8.5.3" - rollup: "npm:^4.34.9" - tinyglobby: "npm:^0.2.13" + picomatch: "npm:^4.0.3" + postcss: "npm:^8.5.6" + rollup: "npm:^4.43.0" + tinyglobby: "npm:^0.2.15" peerDependencies: - "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + "@types/node": ^20.19.0 || >=22.12.0 jiti: ">=1.21.0" - less: "*" + less: ^4.0.0 lightningcss: ^1.21.0 - sass: "*" - sass-embedded: "*" - stylus: "*" - sugarss: "*" + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 @@ -13662,50 +13426,56 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/ea2083b6b1d1c9e85a13d6797ae989aa1dbc27a5c054319c71141934bf3f8dba8d54b510618040f95751148da63787f28f043df7458a194c81f8b6d8a2d32844 + checksum: 10/044490133aaf4cc024700995edaac10ff182262c721a44a8ac7839207b3e5af435c8b9dd8ee4658dc0f47147fa4211632cca3120177aa4bab99a7cb095e5149e languageName: node linkType: hard -"vitest@npm:^3.0.8": - version: 3.0.8 - resolution: "vitest@npm:3.0.8" +"vitest@npm:^4.0.16": + version: 4.0.16 + resolution: "vitest@npm:4.0.16" dependencies: - "@vitest/expect": "npm:3.0.8" - "@vitest/mocker": "npm:3.0.8" - "@vitest/pretty-format": "npm:^3.0.8" - "@vitest/runner": "npm:3.0.8" - "@vitest/snapshot": "npm:3.0.8" - "@vitest/spy": "npm:3.0.8" - "@vitest/utils": "npm:3.0.8" - chai: "npm:^5.2.0" - debug: "npm:^4.4.0" - expect-type: "npm:^1.1.0" - magic-string: "npm:^0.30.17" + "@vitest/expect": "npm:4.0.16" + "@vitest/mocker": "npm:4.0.16" + "@vitest/pretty-format": "npm:4.0.16" + "@vitest/runner": "npm:4.0.16" + "@vitest/snapshot": "npm:4.0.16" + "@vitest/spy": "npm:4.0.16" + "@vitest/utils": "npm:4.0.16" + es-module-lexer: "npm:^1.7.0" + expect-type: "npm:^1.2.2" + magic-string: "npm:^0.30.21" + obug: "npm:^2.1.1" pathe: "npm:^2.0.3" - std-env: "npm:^3.8.0" + picomatch: "npm:^4.0.3" + std-env: "npm:^3.10.0" tinybench: "npm:^2.9.0" - tinyexec: "npm:^0.3.2" - tinypool: "npm:^1.0.2" - tinyrainbow: "npm:^2.0.0" - vite: "npm:^5.0.0 || ^6.0.0" - vite-node: "npm:3.0.8" + tinyexec: "npm:^1.0.2" + tinyglobby: "npm:^0.2.15" + tinyrainbow: "npm:^3.0.3" + vite: "npm:^6.0.0 || ^7.0.0" why-is-node-running: "npm:^2.3.0" peerDependencies: "@edge-runtime/vm": "*" - "@types/debug": ^4.1.12 - "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 - "@vitest/browser": 3.0.8 - "@vitest/ui": 3.0.8 + "@opentelemetry/api": ^1.9.0 + "@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0 + "@vitest/browser-playwright": 4.0.16 + "@vitest/browser-preview": 4.0.16 + "@vitest/browser-webdriverio": 4.0.16 + "@vitest/ui": 4.0.16 happy-dom: "*" jsdom: "*" peerDependenciesMeta: "@edge-runtime/vm": optional: true - "@types/debug": + "@opentelemetry/api": optional: true "@types/node": optional: true - "@vitest/browser": + "@vitest/browser-playwright": + optional: true + "@vitest/browser-preview": + optional: true + "@vitest/browser-webdriverio": optional: true "@vitest/ui": optional: true @@ -13715,7 +13485,7 @@ __metadata: optional: true bin: vitest: vitest.mjs - checksum: 10/83b246ded7dab20db40a0dfa93a45a7a4de3d41f1860889b53d2896761db48ca42b88d1a5d8920681d6f5b96b76a46d5ab27456affb89be7ea2138d95531c87e + checksum: 10/22b3806988ab186be4a6a133903a70c62835198e8e749f6ed751957d23bc1e3f0466e310a1a79d0b70a354b2e308e574486191eb39711257b3fe61e4fe00d1c8 languageName: node linkType: hard