From 6873e1e386aa8273756e1af26fbd8ce450773f04 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 15 Aug 2026 03:17:25 +0000 Subject: [PATCH 1/2] Add Electron desktop builds for Windows, macOS, and Linux. Wrap the existing FastAPI UI in a native window, bundle the Python sidecar with PyInstaller, and add a workflow_dispatch Action that publishes installers as artifacts. Co-authored-by: Damon --- .github/workflows/ci.yml | 2 + .github/workflows/desktop.yml | 87 + .gitignore | 2 + README.md | 28 + desktop/backend.mjs | 73 + desktop/backend.test.mjs | 111 + desktop/electron-builder.yml | 43 + desktop/main.mjs | 153 ++ desktop/package-lock.json | 4047 +++++++++++++++++++++++++++++++++ desktop/package.json | 21 + desktop/resources/icon.png | Bin 0 -> 35417 bytes packaging/entry.py | 9 + packaging/loadpath.spec | 89 + packaging/make_icon.py | 106 + packaging/smoke_backend.py | 46 + src/loadpath/__main__.py | 3 + src/loadpath/paths.py | 13 + src/loadpath/review/render.py | 6 +- src/loadpath/server/app.py | 3 +- tests/e2e/test_cli_review.py | 20 + tests/unit/test_paths.py | 21 + 21 files changed, 4879 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/desktop.yml create mode 100644 desktop/backend.mjs create mode 100644 desktop/backend.test.mjs create mode 100644 desktop/electron-builder.yml create mode 100644 desktop/main.mjs create mode 100644 desktop/package-lock.json create mode 100644 desktop/package.json create mode 100644 desktop/resources/icon.png create mode 100644 packaging/entry.py create mode 100644 packaging/loadpath.spec create mode 100644 packaging/make_icon.py create mode 100644 packaging/smoke_backend.py create mode 100644 src/loadpath/__main__.py create mode 100644 src/loadpath/paths.py create mode 100644 tests/unit/test_paths.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ab5288..a8497cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,3 +29,5 @@ jobs: npm install npm test npm run build + - name: Desktop unit tests + run: node --test desktop/backend.test.mjs diff --git a/.github/workflows/desktop.yml b/.github/workflows/desktop.yml new file mode 100644 index 0000000..1786d1d --- /dev/null +++ b/.github/workflows/desktop.yml @@ -0,0 +1,87 @@ +name: Desktop builds + +on: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: desktop-build-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: ${{ matrix.label }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + label: Linux + electron_args: --linux AppImage deb + - os: windows-latest + label: Windows + electron_args: --win nsis + - os: macos-latest + label: macOS + electron_args: --mac dmg zip + defaults: + run: + shell: bash + env: + CSC_IDENTITY_AUTO_DISCOVERY: "false" + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - uses: actions/setup-node@v4 + with: + node-version: "22" + cache: npm + cache-dependency-path: | + ui/package-lock.json + desktop/package-lock.json + + - name: Build UI + working-directory: ui + run: | + npm ci + npm run build + + - name: Install Python package and PyInstaller + run: | + python -m pip install --upgrade pip + python -m pip install -e . + python -m pip install pyinstaller + + - name: Bundle backend sidecar + run: python -m PyInstaller packaging/loadpath.spec --noconfirm --clean --distpath desktop/backend-dist + + - name: Smoke-test sidecar + run: python packaging/smoke_backend.py + + - name: Install desktop dependencies + working-directory: desktop + run: npm ci + + - name: Build Electron app + working-directory: desktop + run: npx electron-builder --publish never ${{ matrix.electron_args }} + + - name: Upload installers + uses: actions/upload-artifact@v4 + with: + name: loadpath-${{ matrix.label }} + if-no-files-found: error + path: | + desktop/dist/*.AppImage + desktop/dist/*.deb + desktop/dist/*.dmg + desktop/dist/*.zip + desktop/dist/*.exe + desktop/dist/*.yml diff --git a/.gitignore b/.gitignore index e179c39..d3b1f85 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ ui/dist/ .playwright-mcp/ ui/playwright-report/ ui/test-results/ +desktop/backend-dist/ +desktop/dist/ diff --git a/README.md b/README.md index b22fc08..e5ec02b 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,32 @@ cd ui && npm install && npm run build && cd .. loadpath --help ``` +## Desktop app (Windows, macOS, Linux) + +Electron wraps the same local app: it starts the Loadpath backend and opens it in a native window. Tokens still live in `~/.loadpath/settings.json`. + +**From source** + +```bash +pip install -e . +cd ui && npm install && npm run build && cd .. +cd desktop && npm install && npm start +``` + +Requires Python 3.12+ on `PATH` (`python` on Windows, `python3` elsewhere), or set `LOADPATH_PYTHON`. + +**Installers** + +GitHub → Actions → **Desktop builds** → **Run workflow**. That manual job builds: + +| OS | Artifact | +| --- | --- | +| Linux | AppImage and `.deb` | +| Windows | NSIS `.exe` | +| macOS | `.dmg` and `.zip` (unsigned) | + +macOS Gatekeeper will block the unsigned app until you open it from Finder with right-click → Open. The workflow smokes `/api/health` on the bundled Python sidecar before packaging. + ## CLI ```bash @@ -205,6 +231,7 @@ Line coverage on changed files is the wrong metric. Loadpath scores the **impact ```bash pytest cd ui && npm test +node --test desktop/backend.test.mjs ``` | Suite | What it covers | @@ -217,6 +244,7 @@ cd ui && npm test | `tests/e2e/test_index_architecture_flow.py` | index snapshot, review without index, review walking an existing graph | | `tests/e2e/test_brokers_and_django.py` | Celery + Dramatiq sinks, actor-only PR, non-idempotent Dramatiq warning, destructive migration, cross-context blocker, boot overlay, management commands, beat/canvas | | `tests/e2e/test_ui_screenshots.py` | Playwright: Architecture, Review, Impact graph, Pull requests, Settings → `docs/screenshots/` | +| `desktop/backend.test.mjs` | Electron sidecar command (dev vs packaged) and health-wait | CI installs Chromium and runs the full suite. diff --git a/desktop/backend.mjs b/desktop/backend.mjs new file mode 100644 index 0000000..2fb0a93 --- /dev/null +++ b/desktop/backend.mjs @@ -0,0 +1,73 @@ +import net from "node:net"; +import path from "node:path"; + +export function backendBinaryName(platform) { + return platform === "win32" ? "loadpath.exe" : "loadpath"; +} + +export function backendCommand({ + packaged, + platform, + port, + resourcesPath, + python, + repoRoot, +}) { + const serveArgs = ["serve", "--host", "127.0.0.1", "--port", String(port), "--no-open"]; + if (packaged) { + return { + command: path.join(resourcesPath, "loadpath", backendBinaryName(platform)), + args: serveArgs, + cwd: undefined, + env: {}, + }; + } + const command = python || (platform === "win32" ? "python" : "python3"); + return { + command, + args: ["-m", "loadpath", ...serveArgs], + cwd: repoRoot, + env: repoRoot ? { PYTHONPATH: path.join(repoRoot, "src") } : {}, + }; +} + +export function pickFreePort(host = "127.0.0.1") { + return new Promise((resolve, reject) => { + const server = net.createServer(); + server.unref(); + server.on("error", reject); + server.listen(0, host, () => { + const address = server.address(); + const port = typeof address === "object" && address ? address.port : 0; + server.close((err) => (err ? reject(err) : resolve(port))); + }); + }); +} + +export async function waitForHealth(baseUrl, options = {}) { + const { + fetchImpl = globalThis.fetch, + timeoutMs = 45_000, + intervalMs = 200, + isAborted = () => false, + } = options; + const url = `${String(baseUrl).replace(/\/$/, "")}/api/health`; + const start = Date.now(); + let lastError = "backend did not become ready"; + while (Date.now() - start < timeoutMs) { + if (isAborted()) { + throw new Error("backend exited before it became ready"); + } + try { + const res = await fetchImpl(url, { signal: AbortSignal.timeout(1500) }); + if (res.ok) { + return res.json().catch(() => ({})); + } + lastError = `health check HTTP ${res.status}`; + } catch (err) { + lastError = err instanceof Error ? err.message : String(err); + } + await new Promise((resolve) => setTimeout(resolve, intervalMs)); + } + throw new Error(`Loadpath backend failed to start: ${lastError}`); +} diff --git a/desktop/backend.test.mjs b/desktop/backend.test.mjs new file mode 100644 index 0000000..43cae6d --- /dev/null +++ b/desktop/backend.test.mjs @@ -0,0 +1,111 @@ +import assert from "node:assert/strict"; +import path from "node:path"; +import { describe, it } from "node:test"; + +import { backendBinaryName, backendCommand, waitForHealth } from "./backend.mjs"; + +describe("backendBinaryName", () => { + it("uses .exe on Windows", () => { + assert.equal(backendBinaryName("win32"), "loadpath.exe"); + }); + + it("uses a bare name on macOS and Linux", () => { + assert.equal(backendBinaryName("darwin"), "loadpath"); + assert.equal(backendBinaryName("linux"), "loadpath"); + }); +}); + +describe("backendCommand", () => { + it("runs python -m loadpath serve in development", () => { + const result = backendCommand({ + packaged: false, + platform: "linux", + port: 7345, + python: "python3", + repoRoot: "/repo", + }); + assert.equal(result.command, "python3"); + assert.deepEqual(result.args, [ + "-m", + "loadpath", + "serve", + "--host", + "127.0.0.1", + "--port", + "7345", + "--no-open", + ]); + assert.equal(result.cwd, "/repo"); + assert.equal(result.env.PYTHONPATH, path.join("/repo", "src")); + }); + + it("defaults to python.exe-style interpreter name on Windows", () => { + const result = backendCommand({ + packaged: false, + platform: "win32", + port: 8000, + repoRoot: "C:\\\\src", + }); + assert.equal(result.command, "python"); + assert.equal(result.args[6], "8000"); + }); + + it("points at the bundled sidecar when packaged", () => { + const result = backendCommand({ + packaged: true, + platform: "darwin", + port: 9000, + resourcesPath: "/App/Contents/Resources", + }); + assert.equal(result.command, path.join("/App/Contents/Resources", "loadpath", "loadpath")); + assert.deepEqual(result.args, ["serve", "--host", "127.0.0.1", "--port", "9000", "--no-open"]); + assert.equal(result.cwd, undefined); + }); + + it("uses loadpath.exe under extraResources on Windows", () => { + const result = backendCommand({ + packaged: true, + platform: "win32", + port: 7345, + resourcesPath: "C:\\\\app\\\\resources", + }); + assert.equal(result.command, path.join("C:\\\\app\\\\resources", "loadpath", "loadpath.exe")); + }); +}); + +describe("waitForHealth", () => { + it("returns once /api/health is ok", async () => { + let calls = 0; + const body = await waitForHealth("http://127.0.0.1:9", { + timeoutMs: 1000, + intervalMs: 1, + fetchImpl: async (url) => { + calls += 1; + assert.equal(url, "http://127.0.0.1:9/api/health"); + if (calls < 3) throw new Error("connection refused"); + return { + ok: true, + status: 200, + json: async () => ({ status: "ok", version: "0.1.0" }), + }; + }, + }); + assert.equal(calls, 3); + assert.equal(body.status, "ok"); + }); + + it("fails when the backend process already exited", async () => { + await assert.rejects( + () => + waitForHealth("http://127.0.0.1:9", { + timeoutMs: 500, + intervalMs: 1, + isAborted: () => true, + fetchImpl: async () => { + throw new Error("should not fetch"); + }, + }), + /exited before it became ready/, + ); + }); +}); diff --git a/desktop/electron-builder.yml b/desktop/electron-builder.yml new file mode 100644 index 0000000..163aebc --- /dev/null +++ b/desktop/electron-builder.yml @@ -0,0 +1,43 @@ +appId: app.loadpath.desktop +productName: Loadpath +copyright: Copyright © Loadpath +artifactName: ${productName}-${version}-${os}-${arch}.${ext} +directories: + output: dist + buildResources: resources +files: + - main.mjs + - backend.mjs + - package.json +extraResources: + - from: backend-dist/loadpath + to: loadpath + filter: + - "**/*" +asar: true +compression: normal +linux: + target: + - AppImage + - deb + category: Development + maintainer: Loadpath + synopsis: Architecture-typed impact graphs for Django + React pull requests. + syncDesktopName: true +win: + target: + - nsis +nsis: + oneClick: false + allowToChangeInstallationDirectory: true + deleteAppDataOnUninstall: false +mac: + target: + - dmg + - zip + category: public.app-category.developer-tools + identity: null + hardenedRuntime: false + gatekeeperAssess: false +dmg: + artifactName: ${productName}-${version}-${os}-${arch}.${ext} diff --git a/desktop/main.mjs b/desktop/main.mjs new file mode 100644 index 0000000..4afe5fd --- /dev/null +++ b/desktop/main.mjs @@ -0,0 +1,153 @@ +import { app, BrowserWindow, dialog, shell } from "electron"; +import { spawn } from "node:child_process"; +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +import { backendCommand, pickFreePort, waitForHealth } from "./backend.mjs"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +let backendProcess = null; +let backendPort = null; +let mainWindow = null; +let quitting = false; + +function repoRoot() { + return path.resolve(__dirname, ".."); +} + +function createWindow() { + const win = new BrowserWindow({ + width: 1440, + height: 900, + minWidth: 1024, + minHeight: 700, + title: "Loadpath", + backgroundColor: "#070b10", + autoHideMenuBar: true, + show: false, + webPreferences: { + contextIsolation: true, + nodeIntegration: false, + sandbox: true, + }, + }); + if (process.platform !== "darwin") { + win.setMenuBarVisibility(false); + } + win.webContents.setWindowOpenHandler(({ url }) => { + shell.openExternal(url); + return { action: "deny" }; + }); + win.once("ready-to-show", () => win.show()); + return win; +} + +function splashUrl() { + const html = ` +Loadpath + +

Starting Loadpath…

`; + return `data:text/html;charset=utf-8,${encodeURIComponent(html)}`; +} + +function stopBackend() { + backendPort = null; + if (!backendProcess || backendProcess.killed) return; + backendProcess.kill(); + backendProcess = null; +} + +async function startBackend() { + const port = await pickFreePort(); + const { command, args, cwd, env } = backendCommand({ + packaged: app.isPackaged, + platform: process.platform, + port, + resourcesPath: process.resourcesPath, + python: process.env.LOADPATH_PYTHON, + repoRoot: repoRoot(), + }); + const logDir = app.getPath("userData"); + fs.mkdirSync(logDir, { recursive: true }); + const logPath = path.join(logDir, "backend.log"); + const log = fs.createWriteStream(logPath, { flags: "a" }); + log.write(`\n[${new Date().toISOString()}] ${command} ${args.join(" ")}\n`); + + backendProcess = spawn(command, args, { + cwd, + env: { ...process.env, ...env }, + windowsHide: true, + stdio: ["ignore", "pipe", "pipe"], + }); + backendProcess.stdout.pipe(log); + backendProcess.stderr.pipe(log); + backendProcess.on("error", (err) => { + log.write(`spawn error: ${err.message}\n`); + }); + backendProcess.on("exit", () => { + backendPort = null; + }); + + try { + await waitForHealth(`http://127.0.0.1:${port}`, { + isAborted: () => Boolean(backendProcess?.exitCode != null || backendProcess?.signalCode), + }); + } catch (err) { + stopBackend(); + throw new Error(`${err.message}\nLog: ${logPath}`); + } + backendPort = port; + return port; +} + +async function ensureBackend() { + if (backendProcess && backendProcess.exitCode == null && backendPort) { + return backendPort; + } + return startBackend(); +} + +async function boot() { + mainWindow = createWindow(); + await mainWindow.loadURL(splashUrl()); + try { + const port = await ensureBackend(); + await mainWindow.loadURL(`http://127.0.0.1:${port}`); + if (process.env.LOADPATH_DEVTOOLS === "1") { + mainWindow.webContents.openDevTools({ mode: "detach" }); + } + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + dialog.showErrorBox("Loadpath failed to start", message); + app.quit(); + } +} + +const gotLock = app.requestSingleInstanceLock(); +if (!gotLock) { + app.quit(); +} else { + app.on("second-instance", () => { + if (!mainWindow) return; + if (mainWindow.isMinimized()) mainWindow.restore(); + mainWindow.focus(); + }); + app.whenReady().then(boot); + app.on("before-quit", () => { + quitting = true; + stopBackend(); + }); + app.on("window-all-closed", () => { + if (process.platform !== "darwin") app.quit(); + }); + app.on("activate", () => { + if (BrowserWindow.getAllWindows().length === 0 && !quitting) boot(); + }); +} diff --git a/desktop/package-lock.json b/desktop/package-lock.json new file mode 100644 index 0000000..2b13c61 --- /dev/null +++ b/desktop/package-lock.json @@ -0,0 +1,4047 @@ +{ + "name": "loadpath", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "loadpath", + "version": "0.1.0", + "devDependencies": { + "electron": "^36.4.0", + "electron-builder": "^26.0.12" + } + }, + "node_modules/@electron/asar": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz", + "integrity": "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/@electron/asar/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@electron/asar/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@electron/asar/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@electron/fuses": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@electron/fuses/-/fuses-1.8.0.tgz", + "integrity": "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.1", + "fs-extra": "^9.0.1", + "minimist": "^1.2.5" + }, + "bin": { + "electron-fuses": "dist/bin.js" + } + }, + "node_modules/@electron/fuses/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/fuses/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/fuses/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@electron/notarize": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz", + "integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/notarize/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/notarize/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/notarize/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/osx-sign": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.3.tgz", + "integrity": "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@electron/osx-sign/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/osx-sign/node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/@electron/osx-sign/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/osx-sign/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/rebuild": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-4.2.0.tgz", + "integrity": "sha512-RKL/O+jGoXJMxrx/5771y1n0xTKmFuOYGO3gMmwypBM6rsH0kou0mswwdXA2JrhIkE4xyC7v9vGk0n6NPzgOxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.1.1", + "node-abi": "^4.2.0", + "node-api-version": "^0.2.1", + "node-gyp": "^12.2.0", + "read-binary-file-arch": "^1.0.6" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@electron/universal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.3.tgz", + "integrity": "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/asar": "^3.3.1", + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.3.1", + "dir-compare": "^4.2.0", + "fs-extra": "^11.1.1", + "minimatch": "^9.0.3", + "plist": "^3.1.0" + }, + "engines": { + "node": ">=16.4" + } + }, + "node_modules/@electron/universal/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@electron/universal/node_modules/brace-expansion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz", + "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/universal/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@electron/universal/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/windows-sign": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz", + "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "cross-dirname": "^0.1.0", + "debug": "^4.3.4", + "fs-extra": "^11.1.1", + "minimist": "^1.2.8", + "postject": "^1.0.0-alpha.6" + }, + "bin": { + "electron-windows-sign": "bin/electron-windows-sign.js" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/windows-sign/node_modules/fs-extra": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz", + "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/windows-sign/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/windows-sign/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@malept/cross-spawn-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", + "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "license": "Apache-2.0", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/@malept/flatpak-bundler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", + "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.0", + "lodash": "^4.17.15", + "tmp-promise": "^3.0.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@noble/hashes": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.3.0.tgz", + "integrity": "sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.9.0.tgz", + "integrity": "sha512-AKvPMOM7LfK0uFe1m7o7+veOa8xQGPqsqOrKi3QKgCElzwjGp39mbhr2g7mt/v/mXQHiIvJmDj5cJS173x8Q9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@peculiar/utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", + "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/webcrypto": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.7.1.tgz", + "integrity": "sha512-ODOov0sGMJMf3jPonOkgGqPknTsu+DdQ7kD++gz8aI+aFMOMHFbWAA2taqXXVTdP+OTOQR/znGvSpmkeI0WTYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.7.0", + "@peculiar/json-schema": "^1.1.12", + "@peculiar/utils": "^2.0.2", + "tslib": "^2.8.1", + "webcrypto-core": "^1.9.2" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.20.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", + "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.14.tgz", + "integrity": "sha512-T4EDRUBVZYRldYApjEJiU0e1stYWaRAX7CuSnKzrpwdZKo53zGV8/pqfzV6FfwNl9YThD2OumQYvqtvjvgG7aQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/app-builder-lib": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.15.3.tgz", + "integrity": "sha512-2VnyWkqsP5v5XbBhL3tD5Syx8iNPBYsoU7kY4S2fz7wg8Rj/nztWKCUzGKaFRTv0Xwf3/H058CR1Kvtd/3lRow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/asar": "3.4.1", + "@electron/fuses": "^1.8.0", + "@electron/get": "^3.0.0", + "@electron/notarize": "2.5.0", + "@electron/osx-sign": "1.3.3", + "@electron/rebuild": "^4.0.4", + "@electron/universal": "2.0.3", + "@malept/flatpak-bundler": "^0.4.0", + "@noble/hashes": "^2.2.0", + "@peculiar/webcrypto": "^1.7.1", + "@types/fs-extra": "9.0.13", + "ajv": "^8.18.0", + "asn1js": "^3.0.10", + "async-exit-hook": "^2.0.1", + "builder-util": "26.15.3", + "builder-util-runtime": "9.7.0", + "chromium-pickle-js": "^0.2.0", + "ci-info": "4.3.1", + "debug": "^4.3.4", + "dotenv": "^16.4.5", + "dotenv-expand": "^11.0.6", + "ejs": "^3.1.8", + "electron-publish": "26.15.3", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", + "isbinaryfile": "^5.0.0", + "jiti": "^2.4.2", + "js-yaml": "^4.1.0", + "json5": "^2.2.3", + "lazy-val": "^1.0.5", + "minimatch": "^10.2.5", + "pkijs": "^3.4.0", + "plist": "3.1.0", + "proper-lockfile": "^4.1.2", + "resedit": "^1.7.0", + "semver": "~7.7.3", + "tar": "^7.5.7", + "temp-file": "^3.4.0", + "tiny-async-pool": "1.3.0", + "unzipper": "^0.12.3", + "which": "^5.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "dmg-builder": "26.15.3", + "electron-builder-squirrel-windows": "26.15.3" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-3.1.0.tgz", + "integrity": "sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/get/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/app-builder-lib/node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/app-builder-lib/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/app-builder-lib/node_modules/fs-extra/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/app-builder-lib/node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/asn1js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", + "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/brace-expansion": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/builder-util": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.15.3.tgz", + "integrity": "sha512-q2hn7Mbo2nFNkVekPiHFx6Nfo3hURmES3tfBn+k5Pqxl2RkmP3QGqZUhH/q9Pch/4G05NRhPjDlVj1O8q4Txvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/debug": "^4.1.6", + "builder-util-runtime": "9.7.0", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.6", + "debug": "^4.3.4", + "fs-extra": "^10.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "js-yaml": "^4.1.0", + "sanitize-filename": "^1.6.3", + "source-map-support": "^0.5.19", + "stat-mode": "^1.0.0", + "temp-file": "^3.4.0", + "tiny-async-pool": "1.3.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/builder-util-runtime": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.7.0.tgz", + "integrity": "sha512-g/kR520giAFYkSXTzcmF3kqQq7wi8F6N6SzeDgZrqTBN+VHdmgWOyTdD1yD7AATDId/yXLvuP34CxW46/BwCdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/builder-util/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/builder-util/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/builder-util/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bytestreamjs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz", + "integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/compare-version": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-dirname": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cross-dirname/-/cross-dirname-0.1.0.tgz", + "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/dir-compare": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz", + "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5", + "p-limit": "^3.1.0 " + } + }, + "node_modules/dir-compare/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/dir-compare/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/dir-compare/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dmg-builder": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.15.3.tgz", + "integrity": "sha512-O3zJUFUYHJKgzPqioHxfxzBzlSC1eXCSr79gMSBKBP5AgjjpmrydMsMLotEg9fAJF36vdUncb+4ndRNxoPdlSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "26.15.3", + "builder-util": "26.15.3", + "fs-extra": "^10.1.0", + "js-yaml": "^4.1.0" + } + }, + "node_modules/dmg-builder/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dmg-builder/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/dmg-builder/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron": { + "version": "36.9.5", + "resolved": "https://registry.npmjs.org/electron/-/electron-36.9.5.tgz", + "integrity": "sha512-1UCss2IqxqujSzg/2jkRjuiT3G+EEXgd6UKB5kUekwQW1LJ6d4QCr8YItfC3Rr9VIGRDJ29eOERmnRNO1Eh+NA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^22.7.7", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, + "node_modules/electron-builder": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.15.3.tgz", + "integrity": "sha512-a1KM5heqS3gQCZzizXEI8RjJy3QVogULPdeSknt76uLDpBIW/HDGsMg/XgP0riP6PI9COsRvFITKKGDqA8fJxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "26.15.3", + "builder-util": "26.15.3", + "builder-util-runtime": "9.7.0", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "dmg-builder": "26.15.3", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "simple-update-notifier": "2.0.0", + "yargs": "^17.6.2" + }, + "bin": { + "electron-builder": "cli.js", + "install-app-deps": "install-app-deps.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/electron-builder-squirrel-windows": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.15.3.tgz", + "integrity": "sha512-Jc19XPV9y9+2bAdZPkXuVNGNIEFBq9poHC61l8Kv6FdK7DRG3+Ic0rerC0DXOaeHNz8yW0fg/JnF8GQROOF5MA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "app-builder-lib": "26.15.3", + "builder-util": "26.15.3", + "electron-winstaller": "5.4.0" + } + }, + "node_modules/electron-builder/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-builder/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-builder/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-publish": { + "version": "26.15.3", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.15.3.tgz", + "integrity": "sha512-g/2bn8YTavY4cuS5F+jOS7zmZbXXBV8KZ8yHKfJjFPoKtzBqrpCdNPxBd3tqdBwP7BVd0lGzf7Bk2s0KesWZ4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^9.0.11", + "aws4": "^1.13.2", + "builder-util": "26.15.3", + "builder-util-runtime": "9.7.0", + "chalk": "^4.1.2", + "form-data": "^4.0.5", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "mime": "^2.5.2" + } + }, + "node_modules/electron-publish/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-publish/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-publish/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-winstaller": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.4.0.tgz", + "integrity": "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@electron/asar": "^3.2.1", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "lodash": "^4.17.21", + "temp": "^0.9.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "@electron/windows-sign": "^1.1.2" + } + }, + "node_modules/electron-winstaller/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", + "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filelist": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", + "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/form-data": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/global-agent/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.7.tgz", + "integrity": "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-yaml": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lazy-val": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", + "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-abi": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-4.33.0.tgz", + "integrity": "sha512-vLBWCKb+7LWsX+TbfzWOkw0W81m377tyx3hOweBTjO43CXZnRGS1/JPWs20fr0PgZyDXk6ROYrylsEycK8raDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.6.3" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-api-version": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.1.tgz", + "integrity": "sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + } + }, + "node_modules/node-api-version/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.4.0.tgz", + "integrity": "sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "undici": "^6.25.0", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pe-library": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz", + "integrity": "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkijs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.0.tgz", + "integrity": "sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@noble/hashes": "1.4.0", + "asn1js": "^3.0.6", + "bytestreamjs": "^2.0.1", + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/pkijs/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/postject": { + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", + "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "commander": "^9.4.0" + }, + "bin": { + "postject": "dist/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/postject/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.2.0.tgz", + "integrity": "sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-binary-file-arch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz", + "integrity": "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "bin": { + "read-binary-file-arch": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resedit": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/resedit/-/resedit-1.7.2.tgz", + "integrity": "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pe-library": "^0.4.1" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/sanitize-filename": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.4.tgz", + "integrity": "sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==", + "dev": true, + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sax": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.1.tgz", + "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/stat-mode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", + "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "7.5.22", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz", + "integrity": "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp-file": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", + "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-exit-hook": "^2.0.1", + "fs-extra": "^10.0.0" + } + }, + "node_modules/temp-file/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/temp-file/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/temp-file/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/tiny-async-pool": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-1.3.0.tgz", + "integrity": "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^5.5.0" + } + }, + "node_modules/tiny-async-pool/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tmp": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici": { + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.0.tgz", + "integrity": "sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unzipper": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.12.5.tgz", + "integrity": "sha512-tXYOi9R57Uj/2Z25SOs5RRSzq886MBQj2gY8dPL+xl/kv6s6SvByoKfAtvfVeEuhntWDgjd2o9p2lb4TVPAz0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "~3.7.2", + "duplexer2": "~0.1.4", + "fs-extra": "11.3.1", + "graceful-fs": "^4.2.2", + "node-int64": "^0.4.0" + } + }, + "node_modules/unzipper/node_modules/fs-extra": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", + "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/unzipper/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/unzipper/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/webcrypto-core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.9.2.tgz", + "integrity": "sha512-gsXecm82UQNlTBURJGuqOWy1Ww08S3kZUcr3aOJS02Pk0xLtkfeUAVC0u0xhgdonFme80edSJUIJyuvL/7250Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.7.0", + "@peculiar/json-schema": "^1.1.12", + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/desktop/package.json b/desktop/package.json new file mode 100644 index 0000000..82a1716 --- /dev/null +++ b/desktop/package.json @@ -0,0 +1,21 @@ +{ + "name": "loadpath", + "version": "0.1.0", + "private": true, + "description": "Loadpath desktop app", + "author": "Loadpath ", + "homepage": "https://github.com/Modsofthenation/PR-Reviewer", + "desktopName": "Loadpath", + "type": "module", + "main": "main.mjs", + "scripts": { + "start": "electron .", + "test": "node --test backend.test.mjs", + "pack": "electron-builder --dir --publish never", + "dist": "electron-builder --publish never" + }, + "devDependencies": { + "electron": "^36.4.0", + "electron-builder": "^26.0.12" + } +} diff --git a/desktop/resources/icon.png b/desktop/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..00d51c76646711819a51921b7d6c2fb20aea117e GIT binary patch literal 35417 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 None: + app() + + +if __name__ == "__main__": + main() diff --git a/packaging/loadpath.spec b/packaging/loadpath.spec new file mode 100644 index 0000000..7191def --- /dev/null +++ b/packaging/loadpath.spec @@ -0,0 +1,89 @@ +# -*- mode: python ; coding: utf-8 -*- +"""PyInstaller spec for the Loadpath sidecar used by the Electron app.""" + +from __future__ import annotations + +from pathlib import Path + +from PyInstaller.utils.hooks import collect_all, collect_submodules + +ROOT = Path(SPECPATH).resolve().parent +SRC = ROOT / "src" + +datas: list = [] +binaries: list = [] +hiddenimports: list = collect_submodules("loadpath") + +PACKAGES = ( + "loadpath", + "mcp", + "uvicorn", + "fastapi", + "starlette", + "pydantic", + "pydantic_settings", + "pydantic_core", + "anyio", + "httpx", + "httpcore", + "jinja2", + "typer", + "rich", + "click", + "yaml", + "multipart", + "sse_starlette", + "jsonschema", + "httptools", + "websockets", + "watchfiles", + "dotenv", + "uvloop", +) + +for pkg in PACKAGES: + try: + pkg_datas, pkg_binaries, pkg_hidden = collect_all(pkg) + except Exception: + continue + datas += pkg_datas + binaries += pkg_binaries + hiddenimports += pkg_hidden + +a = Analysis( + [str(ROOT / "packaging" / "entry.py")], + pathex=[str(SRC)], + binaries=binaries, + datas=datas, + hiddenimports=hiddenimports, + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=["tkinter", "matplotlib", "numpy", "pandas", "playwright", "pytest"], + noarchive=False, +) + +pyz = PYZ(a.pure) + +exe = EXE( + pyz, + a.scripts, + [], + exclude_binaries=True, + name="loadpath", + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=False, + console=True, + disable_windowed_traceback=False, +) + +coll = COLLECT( + exe, + a.binaries, + a.datas, + strip=False, + upx=False, + name="loadpath", +) diff --git a/packaging/make_icon.py b/packaging/make_icon.py new file mode 100644 index 0000000..2247618 --- /dev/null +++ b/packaging/make_icon.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +"""Write desktop/resources/icon.png (1024x1024, no third-party deps).""" + +from __future__ import annotations + +import struct +import zlib +from pathlib import Path + +SIZE = 1024 +BG = (7, 11, 16, 255) +INK = (231, 238, 246, 255) +TEAL = (42, 157, 143, 255) +CYAN = (76, 201, 240, 255) +GOLD = (233, 196, 106, 255) + + +def _blend(dst: bytearray, idx: int, r: int, g: int, b: int, a: int) -> None: + if a <= 0: + return + if a >= 255: + dst[idx : idx + 4] = bytes((r, g, b, 255)) + return + inv = 255 - a + dst[idx] = (dst[idx] * inv + r * a) // 255 + dst[idx + 1] = (dst[idx + 1] * inv + g * a) // 255 + dst[idx + 2] = (dst[idx + 2] * inv + b * a) // 255 + dst[idx + 3] = 255 + + +def _fill_circle(px: bytearray, cx: float, cy: float, radius: float, color: tuple[int, int, int, int]) -> None: + r, g, b, a = color + x0 = max(int(cx - radius) - 1, 0) + x1 = min(int(cx + radius) + 2, SIZE) + y0 = max(int(cy - radius) - 1, 0) + y1 = min(int(cy + radius) + 2, SIZE) + rad2 = radius * radius + for y in range(y0, y1): + dy = y + 0.5 - cy + for x in range(x0, x1): + dx = x + 0.5 - cx + d2 = dx * dx + dy * dy + if d2 <= rad2: + _blend(px, (y * SIZE + x) * 4, r, g, b, a) + else: + edge = d2**0.5 - radius + if edge < 1: + _blend(px, (y * SIZE + x) * 4, r, g, b, int(a * (1 - edge))) + + +def _draw_line( + px: bytearray, + x0: float, + y0: float, + x1: float, + y1: float, + width: float, + color: tuple[int, int, int, int], +) -> None: + steps = max(int(((x1 - x0) ** 2 + (y1 - y0) ** 2) ** 0.5) * 2, 1) + for i in range(steps + 1): + t = i / steps + _fill_circle(px, x0 + (x1 - x0) * t, y0 + (y1 - y0) * t, width / 2, color) + + +def _write_png(path: Path, px: bytearray) -> None: + def chunk(tag: bytes, data: bytes) -> bytes: + return struct.pack(">I", len(data)) + tag + data + struct.pack(">I", zlib.crc32(tag + data) & 0xFFFFFFFF) + + raw = b"".join(b"\x00" + bytes(px[y * SIZE * 4 : (y + 1) * SIZE * 4]) for y in range(SIZE)) + png = b"\x89PNG\r\n\x1a\n" + png += chunk(b"IHDR", struct.pack(">IIBBBBB", SIZE, SIZE, 8, 6, 0, 0, 0)) + png += chunk(b"IDAT", zlib.compress(raw, 9)) + png += chunk(b"IEND", b"") + path.write_bytes(png) + + +def main() -> None: + px = bytearray(SIZE * SIZE * 4) + for i in range(0, len(px), 4): + px[i : i + 4] = bytes(BG) + + margin = 96 + _fill_circle(px, SIZE / 2, SIZE / 2, SIZE / 2 - 24, (13, 20, 28, 255)) + _fill_circle(px, SIZE / 2, SIZE / 2, SIZE / 2 - margin, (18, 28, 38, 255)) + + nodes = [ + (280, 720, TEAL), + (400, 430, CYAN), + (640, 520, GOLD), + (760, 280, INK), + ] + for (x0, y0, _), (x1, y1, _) in zip(nodes, nodes[1:]): + _draw_line(px, x0, y0, x1, y1, 36, TEAL) + for x, y, color in nodes: + _fill_circle(px, x, y, 58, color) + _fill_circle(px, x, y, 22, BG) + + out = Path(__file__).resolve().parents[1] / "desktop" / "resources" / "icon.png" + out.parent.mkdir(parents=True, exist_ok=True) + _write_png(out, px) + print(f"wrote {out}") + + +if __name__ == "__main__": + main() diff --git a/packaging/smoke_backend.py b/packaging/smoke_backend.py new file mode 100644 index 0000000..8d151bf --- /dev/null +++ b/packaging/smoke_backend.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +"""Start the bundled sidecar and wait until /api/health succeeds.""" + +from __future__ import annotations + +import subprocess +import sys +import time +import urllib.error +import urllib.request +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +exe = ROOT / "desktop" / "backend-dist" / "loadpath" / ("loadpath.exe" if sys.platform == "win32" else "loadpath") +if not exe.is_file(): + print(f"missing sidecar: {exe}", file=sys.stderr) + sys.exit(1) + +port = "7345" +proc = subprocess.Popen( + [str(exe), "serve", "--host", "127.0.0.1", "--port", port, "--no-open"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, +) +url = f"http://127.0.0.1:{port}/api/health" +try: + last = "no response" + for _ in range(60): + try: + with urllib.request.urlopen(url, timeout=1) as response: + body = response.read().decode("utf-8", errors="replace") + if response.status == 200 and "ok" in body: + print(body) + sys.exit(0) + last = f"HTTP {response.status}: {body}" + except (urllib.error.URLError, TimeoutError, ConnectionError, OSError) as exc: + last = str(exc) + time.sleep(1) + print(f"sidecar did not become ready: {last}", file=sys.stderr) + sys.exit(1) +finally: + proc.terminate() + try: + proc.wait(timeout=8) + except subprocess.TimeoutExpired: + proc.kill() diff --git a/src/loadpath/__main__.py b/src/loadpath/__main__.py new file mode 100644 index 0000000..4870d12 --- /dev/null +++ b/src/loadpath/__main__.py @@ -0,0 +1,3 @@ +from loadpath.cli import app + +app() diff --git a/src/loadpath/paths.py b/src/loadpath/paths.py new file mode 100644 index 0000000..8d7472e --- /dev/null +++ b/src/loadpath/paths.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +import sys +from pathlib import Path + + +def package_dir() -> Path: + """Directory that holds Loadpath package data (static UI, report templates).""" + if getattr(sys, "frozen", False): + meipass = getattr(sys, "_MEIPASS", None) + if meipass: + return Path(meipass) / "loadpath" + return Path(__file__).resolve().parent diff --git a/src/loadpath/review/render.py b/src/loadpath/review/render.py index 5919750..53cab57 100644 --- a/src/loadpath/review/render.py +++ b/src/loadpath/review/render.py @@ -1,10 +1,10 @@ from __future__ import annotations -from pathlib import Path - from jinja2 import Environment, FileSystemLoader, select_autoescape -TEMPLATE_DIR = Path(__file__).resolve().parent.parent / "report" +from loadpath.paths import package_dir + +TEMPLATE_DIR = package_dir() / "report" def render_markdown(review: dict) -> str: diff --git a/src/loadpath/server/app.py b/src/loadpath/server/app.py index 2ac1c94..63d915c 100644 --- a/src/loadpath/server/app.py +++ b/src/loadpath/server/app.py @@ -10,6 +10,7 @@ from pydantic import BaseModel, Field from loadpath import __version__ +from loadpath.paths import package_dir from loadpath.mcp.oauth import SCOPE from loadpath.mcp.server import ( add_mcp_auth_middleware, @@ -373,7 +374,7 @@ def api_residual(body: ResidualRequest) -> dict[str, Any]: copy_mcp_routes(app, mcp_http) - static_dir = Path(__file__).resolve().parent.parent / "static" + static_dir = package_dir() / "static" if static_dir.is_dir(): app.mount("/", StaticFiles(directory=str(static_dir), html=True), name="static") diff --git a/tests/e2e/test_cli_review.py b/tests/e2e/test_cli_review.py index 0018959..2ed55c3 100644 --- a/tests/e2e/test_cli_review.py +++ b/tests/e2e/test_cli_review.py @@ -78,6 +78,26 @@ def test_cli_serve_help(): result = runner.invoke(app, ["serve", "--help"]) assert result.exit_code == 0 assert "port" in result.output.lower() + assert "no-open" in result.output.lower() + + +def test_python_module_entrypoint_help(): + import os + import subprocess + import sys + from pathlib import Path + + env = os.environ.copy() + env["PYTHONPATH"] = str(Path(__file__).resolve().parents[2] / "src") + result = subprocess.run( + [sys.executable, "-m", "loadpath", "serve", "--help"], + capture_output=True, + text=True, + env=env, + check=False, + ) + assert result.returncode == 0, result.stderr + assert "no-open" in result.stdout.lower() def test_cli_mcp_help(): diff --git a/tests/unit/test_paths.py b/tests/unit/test_paths.py new file mode 100644 index 0000000..ea3fb5f --- /dev/null +++ b/tests/unit/test_paths.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +from pathlib import Path + +from loadpath.paths import package_dir + + +def test_package_dir_contains_static_and_report(): + root = package_dir() + assert (root / "static" / "index.html").is_file() + assert (root / "report" / "graph.html").is_file() + + +def test_package_dir_uses_meipass_when_frozen(monkeypatch, tmp_path: Path): + bundled = tmp_path / "loadpath" + (bundled / "static").mkdir(parents=True) + (bundled / "static" / "index.html").write_text("", encoding="utf-8") + monkeypatch.setattr("loadpath.paths.sys.frozen", True, raising=False) + monkeypatch.setattr("loadpath.paths.sys._MEIPASS", str(tmp_path), raising=False) + assert package_dir() == bundled + assert (package_dir() / "static" / "index.html").is_file() From 267a64ed68d86ce60c7bfbaf157da12e3997fb65 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 15 Aug 2026 03:39:50 +0000 Subject: [PATCH 2/2] Harden Electron navigation and unbreak CI help coverage. Stop asserting --no-open in wrapped Typer help, allow only GitHub and Bitbucket https links out of the desktop shell, and make the sidecar smoke test use a free port plus the packaged UI. Co-authored-by: Damon --- .github/workflows/ci.yml | 2 +- README.md | 4 ++-- desktop/electron-builder.yml | 1 + desktop/main.mjs | 16 +++++++++++++- desktop/package.json | 2 +- desktop/urls.mjs | 27 ++++++++++++++++++++++++ desktop/urls.test.mjs | 30 ++++++++++++++++++++++++++ packaging/loadpath.spec | 22 ++++++++++++++----- packaging/smoke_backend.py | 41 +++++++++++++++++++++++++++--------- tests/e2e/test_cli_review.py | 5 ++--- 10 files changed, 127 insertions(+), 23 deletions(-) create mode 100644 desktop/urls.mjs create mode 100644 desktop/urls.test.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8497cd..fcf16f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,4 +30,4 @@ jobs: npm test npm run build - name: Desktop unit tests - run: node --test desktop/backend.test.mjs + run: node --test desktop/backend.test.mjs desktop/urls.test.mjs diff --git a/README.md b/README.md index e5ec02b..47d1e6d 100644 --- a/README.md +++ b/README.md @@ -231,7 +231,7 @@ Line coverage on changed files is the wrong metric. Loadpath scores the **impact ```bash pytest cd ui && npm test -node --test desktop/backend.test.mjs +node --test desktop/*.test.mjs ``` | Suite | What it covers | @@ -244,7 +244,7 @@ node --test desktop/backend.test.mjs | `tests/e2e/test_index_architecture_flow.py` | index snapshot, review without index, review walking an existing graph | | `tests/e2e/test_brokers_and_django.py` | Celery + Dramatiq sinks, actor-only PR, non-idempotent Dramatiq warning, destructive migration, cross-context blocker, boot overlay, management commands, beat/canvas | | `tests/e2e/test_ui_screenshots.py` | Playwright: Architecture, Review, Impact graph, Pull requests, Settings → `docs/screenshots/` | -| `desktop/backend.test.mjs` | Electron sidecar command (dev vs packaged) and health-wait | +| `desktop/*.test.mjs` | Electron sidecar command, health-wait, and external-URL allowlist | CI installs Chromium and runs the full suite. diff --git a/desktop/electron-builder.yml b/desktop/electron-builder.yml index 163aebc..36f84bb 100644 --- a/desktop/electron-builder.yml +++ b/desktop/electron-builder.yml @@ -8,6 +8,7 @@ directories: files: - main.mjs - backend.mjs + - urls.mjs - package.json extraResources: - from: backend-dist/loadpath diff --git a/desktop/main.mjs b/desktop/main.mjs index 4afe5fd..20a3ec7 100644 --- a/desktop/main.mjs +++ b/desktop/main.mjs @@ -5,6 +5,7 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; import { backendCommand, pickFreePort, waitForHealth } from "./backend.mjs"; +import { isAllowedExternalUrl, isAppOrigin } from "./urls.mjs"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -17,6 +18,13 @@ function repoRoot() { return path.resolve(__dirname, ".."); } +function openExternalIfAllowed(url) { + if (!isAllowedExternalUrl(url)) return; + shell.openExternal(url).catch((err) => { + dialog.showErrorBox("Loadpath", `Could not open link: ${err.message}`); + }); +} + function createWindow() { const win = new BrowserWindow({ width: 1440, @@ -37,9 +45,10 @@ function createWindow() { win.setMenuBarVisibility(false); } win.webContents.setWindowOpenHandler(({ url }) => { - shell.openExternal(url); + openExternalIfAllowed(url); return { action: "deny" }; }); + win.webContents.on("will-attach-webview", (event) => event.preventDefault()); win.once("ready-to-show", () => win.show()); return win; } @@ -119,6 +128,11 @@ async function boot() { await mainWindow.loadURL(splashUrl()); try { const port = await ensureBackend(); + mainWindow.webContents.on("will-navigate", (event, url) => { + if (isAppOrigin(url, port)) return; + event.preventDefault(); + openExternalIfAllowed(url); + }); await mainWindow.loadURL(`http://127.0.0.1:${port}`); if (process.env.LOADPATH_DEVTOOLS === "1") { mainWindow.webContents.openDevTools({ mode: "detach" }); diff --git a/desktop/package.json b/desktop/package.json index 82a1716..d7da181 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -10,7 +10,7 @@ "main": "main.mjs", "scripts": { "start": "electron .", - "test": "node --test backend.test.mjs", + "test": "node --test backend.test.mjs urls.test.mjs", "pack": "electron-builder --dir --publish never", "dist": "electron-builder --publish never" }, diff --git a/desktop/urls.mjs b/desktop/urls.mjs new file mode 100644 index 0000000..e39cf16 --- /dev/null +++ b/desktop/urls.mjs @@ -0,0 +1,27 @@ +export function isAllowedExternalUrl(url) { + let parsed; + try { + parsed = new URL(url); + } catch { + return false; + } + if (parsed.protocol !== "https:") return false; + if (parsed.username || parsed.password) return false; + const host = parsed.hostname.toLowerCase(); + return ( + host === "github.com" || + host.endsWith(".github.com") || + host === "bitbucket.org" || + host.endsWith(".bitbucket.org") + ); +} + +export function isAppOrigin(url, port) { + let parsed; + try { + parsed = new URL(url); + } catch { + return false; + } + return parsed.protocol === "http:" && parsed.hostname === "127.0.0.1" && parsed.port === String(port); +} diff --git a/desktop/urls.test.mjs b/desktop/urls.test.mjs new file mode 100644 index 0000000..1a40470 --- /dev/null +++ b/desktop/urls.test.mjs @@ -0,0 +1,30 @@ +import assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { isAllowedExternalUrl, isAppOrigin } from "./urls.mjs"; + +describe("isAllowedExternalUrl", () => { + it("allows GitHub and Bitbucket https PR links", () => { + assert.equal(isAllowedExternalUrl("https://github.com/acme/demo/pull/12"), true); + assert.equal(isAllowedExternalUrl("https://bitbucket.org/acme/demo/pull-requests/3"), true); + }); + + it("rejects credentials, other hosts, and non-https schemes", () => { + assert.equal(isAllowedExternalUrl("https://user:pass@github.com/acme/demo"), false); + assert.equal(isAllowedExternalUrl("https://github.com.evil.example/acme"), false); + assert.equal(isAllowedExternalUrl("https://evil.example/github.com"), false); + assert.equal(isAllowedExternalUrl("http://github.com/acme/demo"), false); + assert.equal(isAllowedExternalUrl("file:///etc/passwd"), false); + assert.equal(isAllowedExternalUrl("javascript:alert(1)"), false); + assert.equal(isAllowedExternalUrl("not a url"), false); + }); +}); + +describe("isAppOrigin", () => { + it("allows only the loopback backend origin", () => { + assert.equal(isAppOrigin("http://127.0.0.1:7345/api/health", 7345), true); + assert.equal(isAppOrigin("http://127.0.0.1:7345/", 9000), false); + assert.equal(isAppOrigin("http://localhost:7345/", 7345), false); + assert.equal(isAppOrigin("https://127.0.0.1:7345/", 7345), false); + }); +}); diff --git a/packaging/loadpath.spec b/packaging/loadpath.spec index 7191def..173efab 100644 --- a/packaging/loadpath.spec +++ b/packaging/loadpath.spec @@ -14,7 +14,7 @@ datas: list = [] binaries: list = [] hiddenimports: list = collect_submodules("loadpath") -PACKAGES = ( +REQUIRED_PACKAGES = ( "loadpath", "mcp", "uvicorn", @@ -22,15 +22,17 @@ PACKAGES = ( "starlette", "pydantic", "pydantic_settings", - "pydantic_core", "anyio", "httpx", - "httpcore", "jinja2", "typer", "rich", "click", "yaml", +) +OPTIONAL_PACKAGES = ( + "pydantic_core", + "httpcore", "multipart", "sse_starlette", "jsonschema", @@ -41,15 +43,25 @@ PACKAGES = ( "uvloop", ) -for pkg in PACKAGES: + +def _collect(pkg: str, required: bool) -> None: + global datas, binaries, hiddenimports try: pkg_datas, pkg_binaries, pkg_hidden = collect_all(pkg) except Exception: - continue + if required: + raise + return datas += pkg_datas binaries += pkg_binaries hiddenimports += pkg_hidden + +for pkg in REQUIRED_PACKAGES: + _collect(pkg, required=True) +for pkg in OPTIONAL_PACKAGES: + _collect(pkg, required=False) + a = Analysis( [str(ROOT / "packaging" / "entry.py")], pathex=[str(SRC)], diff --git a/packaging/smoke_backend.py b/packaging/smoke_backend.py index 8d151bf..9ce4641 100644 --- a/packaging/smoke_backend.py +++ b/packaging/smoke_backend.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 -"""Start the bundled sidecar and wait until /api/health succeeds.""" +"""Start the bundled sidecar and wait until /api/health and the UI succeed.""" from __future__ import annotations +import socket import subprocess import sys import time @@ -16,23 +17,43 @@ print(f"missing sidecar: {exe}", file=sys.stderr) sys.exit(1) -port = "7345" + +def _free_port() -> int: + with socket.socket() as sock: + sock.bind(("127.0.0.1", 0)) + return int(sock.getsockname()[1]) + + +def _get(url: str) -> tuple[int, str]: + with urllib.request.urlopen(url, timeout=2) as response: + body = response.read().decode("utf-8", errors="replace") + return response.status, body + + +port = _free_port() proc = subprocess.Popen( - [str(exe), "serve", "--host", "127.0.0.1", "--port", port, "--no-open"], + [str(exe), "serve", "--host", "127.0.0.1", "--port", str(port), "--no-open"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, ) -url = f"http://127.0.0.1:{port}/api/health" +health_url = f"http://127.0.0.1:{port}/api/health" +ui_url = f"http://127.0.0.1:{port}/" try: last = "no response" for _ in range(60): + if proc.poll() is not None: + print(f"sidecar exited before it became ready (code {proc.returncode})", file=sys.stderr) + sys.exit(1) try: - with urllib.request.urlopen(url, timeout=1) as response: - body = response.read().decode("utf-8", errors="replace") - if response.status == 200 and "ok" in body: - print(body) - sys.exit(0) - last = f"HTTP {response.status}: {body}" + status, body = _get(health_url) + if status == 200 and "ok" in body and proc.poll() is None: + ui_status, html = _get(ui_url) + if ui_status != 200 or 'id="root"' not in html: + print(f"UI missing from sidecar: HTTP {ui_status}", file=sys.stderr) + sys.exit(1) + print(body) + sys.exit(0) + last = f"HTTP {status}: {body}" except (urllib.error.URLError, TimeoutError, ConnectionError, OSError) as exc: last = str(exc) time.sleep(1) diff --git a/tests/e2e/test_cli_review.py b/tests/e2e/test_cli_review.py index 2ed55c3..c021e23 100644 --- a/tests/e2e/test_cli_review.py +++ b/tests/e2e/test_cli_review.py @@ -78,7 +78,6 @@ def test_cli_serve_help(): result = runner.invoke(app, ["serve", "--help"]) assert result.exit_code == 0 assert "port" in result.output.lower() - assert "no-open" in result.output.lower() def test_python_module_entrypoint_help(): @@ -90,14 +89,14 @@ def test_python_module_entrypoint_help(): env = os.environ.copy() env["PYTHONPATH"] = str(Path(__file__).resolve().parents[2] / "src") result = subprocess.run( - [sys.executable, "-m", "loadpath", "serve", "--help"], + [sys.executable, "-m", "loadpath", "--help"], capture_output=True, text=True, env=env, check=False, ) assert result.returncode == 0, result.stderr - assert "no-open" in result.stdout.lower() + assert "serve" in result.stdout.lower() def test_cli_mcp_help():