diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ce0e08b --- /dev/null +++ b/.env.example @@ -0,0 +1,10 @@ +APP_NAME=Openscreen +BUNDLE_ID=com.siddharthvaddem.openscreen + +APPLE_ID= +TEAM_ID= +SIGN_IDENTITY="Developer ID Application: Samir Patil ()" +CSC_NAME="Samir Patil ()" + +NOTARY_PROFILE=OpenScreen-notary +APPLE_APP_SPECIFIC_PASSWORD= diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..cfee36d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @siddharthvaddem diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4cc446f..f42a92d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,6 +3,16 @@ name: Build Electron App on: workflow_dispatch: + inputs: + arch: + description: 'Architecture to build' + required: true + default: 'both' + type: choice + options: + - arm64 + - x64 + - both jobs: build-windows: @@ -36,38 +46,180 @@ jobs: build-macos: runs-on: macos-latest + strategy: + matrix: + arch: ${{ github.event.inputs.arch == 'both' && fromJSON('["arm64", "x64"]') || fromJSON(format('["{0}"]', github.event.inputs.arch)) }} + steps: + # ─── Checkout ───────────────────────────────────────────── - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 + # ─── Setup Node.js ──────────────────────────────────────── - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: '22' + node-version: 22 + cache: npm + # ─── Setup Python (needed by some native deps) ──────────── - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' + # ─── Install Dependencies ───────────────────────────────── - name: Install dependencies run: npm ci - - name: Install app dependencies - run: npx electron-builder install-app-deps - - - name: Build macOS app - run: npm run build:mac + # ─── Import Code Signing Certificate ────────────────────── + # This is the KEY step that makes CI signing work. + # We create a temporary keychain, import the .p12 cert into it, + # and set it as the default so codesign can find it. + - name: Import code signing certificate env: + MAC_CERTIFICATE_P12: ${{ secrets.MAC_CERTIFICATE_P12 }} + MAC_CERTIFICATE_PASSWORD: ${{ secrets.MAC_CERTIFICATE_PASSWORD }} + run: | + # Create a temporary keychain + KEYCHAIN_PATH=$RUNNER_TEMP/build.keychain-db + KEYCHAIN_PASSWORD=$(openssl rand -base64 32) + + # Create and configure keychain + security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" + security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + + # Decode and import certificate + echo "$MAC_CERTIFICATE_P12" | base64 --decode > $RUNNER_TEMP/certificate.p12 + security import $RUNNER_TEMP/certificate.p12 \ + -k "$KEYCHAIN_PATH" \ + -P "$MAC_CERTIFICATE_PASSWORD" \ + -T /usr/bin/codesign \ + -T /usr/bin/security + + # Allow codesign to access the keychain without UI prompt + security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + + # Add to keychain search path (makes it the default) + security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"') + + # Verify the identity is available + security find-identity -v -p codesigning "$KEYCHAIN_PATH" + + # Clean up the .p12 file + rm -f $RUNNER_TEMP/certificate.p12 + + # ─── Build Vite + Electron ──────────────────────────────── + - name: Build Vite + Electron + run: npx tsc && npx vite build + + # ─── Package with electron-builder ──────────────────────── + # electron-builder handles deep codesigning the .app bundle + # "notarize: false" in electron-builder.json5 prevents it from + # trying its own notarization flow + - name: Package .app bundle + run: npx electron-builder --mac --${{ matrix.arch }} --dir + env: + CSC_NAME: "Samir Patil (N26FZ4GW28)" GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Upload macOS build + # ─── Read version from package.json ─────────────────────── + - name: Get version + id: version + run: echo "version=$(node -p 'require(\"./package.json\").version')" >> $GITHUB_OUTPUT + + # ─── Locate the .app bundle ─────────────────────────────── + - name: Find .app bundle + id: find_app + run: | + VERSION="${{ steps.version.outputs.version }}" + echo "=== Release directory contents ===" + ls -laR "release/${VERSION}/" || echo "release/${VERSION}/ not found" + echo "=== Searching for .app bundle ===" + APP_BUNDLE=$(find "release/${VERSION}" -maxdepth 4 -name "*.app" -type d | head -n1) + if [ -z "$APP_BUNDLE" ]; then + echo "::error::No .app bundle found in release/${VERSION}/" + exit 1 + fi + echo "app_bundle=$APP_BUNDLE" >> $GITHUB_OUTPUT + echo "Found: $APP_BUNDLE" + + # ─── Verify .app signature ──────────────────────────────── + - name: Verify .app code signature + run: codesign --verify --deep --strict "${{ steps.find_app.outputs.app_bundle }}" + + # ─── Create DMG ─────────────────────────────────────────── + - name: Create DMG + id: dmg + run: | + VERSION="${{ steps.version.outputs.version }}" + ARCH="${{ matrix.arch }}" + DMG_NAME="Openscreen-Mac-${ARCH}-${VERSION}.dmg" + RELEASE_DIR="release/${VERSION}" + DMG_OUTPUT="${RELEASE_DIR}/${DMG_NAME}" + STAGING="${RELEASE_DIR}/dmg-staging" + + mkdir -p "$STAGING" + cp -R "${{ steps.find_app.outputs.app_bundle }}" "$STAGING/" + ln -s /Applications "$STAGING/Applications" + + hdiutil create \ + -srcfolder "$STAGING" \ + -volname "Openscreen" \ + -fs HFS+ \ + -fsargs "-c c=64,a=16,e=16" \ + -format UDBZ \ + "$DMG_OUTPUT" + + rm -rf "$STAGING" + + echo "dmg_path=$DMG_OUTPUT" >> $GITHUB_OUTPUT + echo "dmg_name=$DMG_NAME" >> $GITHUB_OUTPUT + + # ─── Sign DMG ───────────────────────────────────────────── + - name: Sign DMG + run: | + codesign --force \ + --sign "Developer ID Application: Samir Patil (N26FZ4GW28)" \ + --timestamp \ + "${{ steps.dmg.outputs.dmg_path }}" + + # ─── Notarize DMG ──────────────────────────────────────── + # On CI we can't use keychain profiles for notarytool, so we + # pass credentials directly via env vars / flags + - name: Notarize DMG + run: | + xcrun notarytool submit "${{ steps.dmg.outputs.dmg_path }}" \ + --apple-id "${{ secrets.APPLE_ID }}" \ + --team-id "${{ secrets.APPLE_TEAM_ID }}" \ + --password "${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}" \ + --wait + timeout-minutes: 15 + + # ─── Staple ─────────────────────────────────────────────── + - name: Staple notarization ticket + run: xcrun stapler staple "${{ steps.dmg.outputs.dmg_path }}" + + # ─── Validate ───────────────────────────────────────────── + - name: Validate stapled DMG + run: | + xcrun stapler validate "${{ steps.dmg.outputs.dmg_path }}" + spctl -a -vv -t install "${{ steps.dmg.outputs.dmg_path }}" + + # ─── Upload Artifact ────────────────────────────────────── + - name: Upload notarized DMG uses: actions/upload-artifact@v4 with: - name: macos-installer - path: release/**/*.dmg + name: openscreen-mac-${{ matrix.arch }} + path: ${{ steps.dmg.outputs.dmg_path }} retention-days: 30 + # ─── Cleanup Keychain ───────────────────────────────────── + - name: Cleanup keychain + if: always() + run: security delete-keychain $RUNNER_TEMP/build.keychain-db || true + build-linux: runs-on: ubuntu-latest steps: @@ -97,4 +249,5 @@ jobs: path: | release/**/*.AppImage release/**/*.zsync + release/**/*.deb retention-days: 30 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 757d997..4194797 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,19 @@ jobs: - run: npm ci - run: npx tsc --noEmit + test: + name: Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + - run: npm ci + - run: npm run test:browser:install + - run: npm run test:browser + build: name: Build runs-on: ubuntu-latest @@ -42,26 +55,3 @@ jobs: cache: npm - run: npm ci - run: npx vite build - - e2e: - name: E2E Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: npm - - run: npm ci - - run: npx playwright install --with-deps chromium - # Install Electron system dependencies not covered by Playwright's chromium deps - - run: npx electron . --version || sudo apt-get install -y libgbm-dev - - run: npm run build-vite - # xvfb provides a virtual display; Electron needs one on Linux even with show:false - - run: xvfb-run --auto-servernum npm run test:e2e - - uses: actions/upload-artifact@v4 - if: failure() - with: - name: playwright-report - path: playwright-report/ - retention-days: 7 diff --git a/.github/workflows/discord.yaml b/.github/workflows/discord.yaml new file mode 100644 index 0000000..6da25d0 --- /dev/null +++ b/.github/workflows/discord.yaml @@ -0,0 +1,519 @@ +name: PR to Discord Forum + +on: + pull_request_target: + types: [opened, reopened, ready_for_review, converted_to_draft, synchronize, edited, labeled, unlabeled, closed] + pull_request_review: + types: [submitted] + issue_comment: + types: [created] + schedule: + - cron: "0 12 * * 1" + workflow_dispatch: + +permissions: + contents: read + pull-requests: write + issues: read + +jobs: + notify: + if: github.event_name != 'schedule' && github.actor != 'github-actions[bot]' + concurrency: + group: discord-pr-sync-${{ github.repository }}-${{ github.event.pull_request.number || github.event.issue.number || github.run_id }} + cancel-in-progress: false + runs-on: ubuntu-latest + steps: + - name: Sync PR activity to Discord forum thread + id: sync + uses: actions/github-script@v7 + env: + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} + DISCORD_PR_FORUM_WEBHOOK: ${{ secrets.DISCORD_PR_FORUM_WEBHOOK }} + DISCORD_WEBHOOK_USERNAME: ${{ secrets.DISCORD_WEBHOOK_USERNAME }} + DISCORD_WEBHOOK_AVATAR_URL: ${{ secrets.DISCORD_WEBHOOK_AVATAR_URL }} + DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }} + DISCORD_REVIEWER_ROLE_ID: ${{ secrets.DISCORD_REVIEWER_ROLE_ID }} + DISCORD_ALERT_WEBHOOK_URL: ${{ secrets.DISCORD_ALERT_WEBHOOK_URL }} + with: + script: | + const WEBHOOK_USERNAME = (process.env.DISCORD_WEBHOOK_USERNAME || "OpenScreen").trim(); + const WEBHOOK_AVATAR = (process.env.DISCORD_WEBHOOK_AVATAR_URL || "").trim(); + + const THREAD_MARKER_REGEX = //i; + const webhookUrl = (process.env.DISCORD_WEBHOOK_URL || process.env.DISCORD_PR_FORUM_WEBHOOK || "").trim(); + const botToken = (process.env.DISCORD_BOT_TOKEN || "").trim(); + const reviewerRoleId = (process.env.DISCORD_REVIEWER_ROLE_ID || "").trim(); + const alertWebhookUrl = (process.env.DISCORD_ALERT_WEBHOOK_URL || "").trim(); + + const TAGS = { + open: "1493976692967080096", + draft: "1493976782028935279", + ready: "1493976833626996756", + changes: "1493976909875515564", + approved: "1493976951038152764", + merged: "1493977049709281320", + closed: "1493977108102516786", + }; + + const labelTagMap = { + bug: "1493977562773458975", + enhancement: "1493977619216207993", + documentation: "1493978565153394830", + }; + + function cleanDescription(text, maxLen = 3500) { + if (!text) return "No description provided."; + const normalized = text + .replace(/\r\n/g, "\n") + .replace(/\n{3,}/g, "\n\n") + .trim(); + if (normalized.length <= maxLen) return normalized; + return `${normalized.slice(0, maxLen - 1)}…`; + } + + function trimThreadName(name) { + return name.length > 95 ? name.slice(0, 95) : name; + } + + function extractThreadId(body) { + if (!body) return null; + const match = body.match(THREAD_MARKER_REGEX); + return match ? match[1] : null; + } + + function upsertThreadMarker(body, threadId) { + const cleaned = (body || "").replace(THREAD_MARKER_REGEX, "").trim(); + return `${cleaned}\n\n`.trim(); + } + + async function discordPost(payload, options = {}) { + const endpoint = new URL(webhookUrl); + endpoint.searchParams.set("wait", "true"); + if (options.threadId) endpoint.searchParams.set("thread_id", String(options.threadId)); + + const response = await fetch(endpoint.toString(), { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + username: WEBHOOK_USERNAME, + avatar_url: WEBHOOK_AVATAR, + allowed_mentions: { parse: [] }, + ...payload, + }) + }); + + const contentType = (response.headers.get("content-type") || "").toLowerCase(); + const text = await response.text(); + + if (!response.ok) { + throw new Error(`Discord API error ${response.status}: ${text}`); + } + + if (!text) return {}; + if (contentType.includes("application/json")) return JSON.parse(text); + + // Some proxy/CDN edge responses may return HTML with 2xx; avoid crashing on JSON parse. + core.warning(`Discord webhook returned non-JSON response (content-type: ${contentType || "unknown"}).`); + return {}; + } + + async function patchDiscordThread(threadId, patchBody) { + if (!botToken || !threadId) return; + const response = await fetch(`https://discord.com/api/v10/channels/${threadId}`, { + method: "PATCH", + headers: { + "Authorization": `Bot ${botToken}`, + "Content-Type": "application/json", + }, + body: JSON.stringify(patchBody), + }); + if (!response.ok) { + const text = await response.text(); + core.warning(`Discord thread patch failed (${response.status}): ${text}`); + } + } + + function desiredStatusTag(prState) { + if (prState.merged && TAGS.merged) return TAGS.merged; + if (prState.closed && !prState.merged && TAGS.closed) return TAGS.closed; + if (prState.reviewState === "CHANGES_REQUESTED" && TAGS.changes) return TAGS.changes; + if (prState.reviewState === "APPROVED" && TAGS.approved) return TAGS.approved; + if (prState.draft && TAGS.draft) return TAGS.draft; + if (!prState.draft && TAGS.ready) return TAGS.ready; + return TAGS.open || null; + } + + function tagIdsFromLabels(labels) { + const out = []; + for (const label of labels) { + const mapped = labelTagMap[label.toLowerCase()] || labelTagMap[label]; + if (mapped) out.push(String(mapped)); + } + return out; + } + + async function getPullRequest() { + if (context.eventName === "pull_request_target" || context.eventName === "pull_request_review") { + return context.payload.pull_request || null; + } + if (context.eventName === "issue_comment") { + const issue = context.payload.issue; + if (!issue?.pull_request) return null; + const { data } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: issue.number, + }); + return data; + } + return null; + } + + async function getReviewState(owner, repo, pullNumber) { + const { data } = await github.rest.pulls.listReviews({ owner, repo, pull_number: pullNumber, per_page: 100 }); + let hasChanges = false; + let hasApproved = false; + for (const r of data) { + const s = (r.state || "").toUpperCase(); + if (s === "CHANGES_REQUESTED") hasChanges = true; + if (s === "APPROVED") hasApproved = true; + } + if (hasChanges) return "CHANGES_REQUESTED"; + if (hasApproved) return "APPROVED"; + return "NONE"; + } + + async function sendFailureAlert(message) { + if (!alertWebhookUrl) return; + try { + await fetch(alertWebhookUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + username: "OpenScreen", + avatar_url: WEBHOOK_AVATAR, + content: `⚠️ PR Discord sync failed\n${message}\nRun: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, + allowed_mentions: { parse: [] } + }) + }); + } catch { + core.warning("Failed to send failure alert webhook."); + } + } + + try { + const pr = await getPullRequest(); + if (!pr) { + core.info("No PR context found. Skipping."); + return; + } + + if (!webhookUrl) { + const strictEvents = new Set(["pull_request_target", "workflow_dispatch"]); + const msg = + `Discord sync skipped: webhook secret unavailable for event '${context.eventName}'. ` + + "Set either DISCORD_WEBHOOK_URL or DISCORD_PR_FORUM_WEBHOOK in repository secrets."; + if (strictEvents.has(context.eventName)) { + core.setFailed(msg); + } else { + core.warning(msg); + } + return; + } + + const action = context.payload.action || ""; + const owner = context.repo.owner; + const repo = context.repo.repo; + const number = pr.number; + const title = pr.title; + const author = pr.user?.login || "unknown"; + const url = pr.html_url; + const authorUrl = pr.user?.html_url || ""; + const authorAvatar = pr.user?.avatar_url || ""; + const base = pr.base?.ref || ""; + const head = pr.head?.ref || ""; + const repoFullName = pr.base?.repo?.full_name || `${owner}/${repo}`; + const labels = (pr.labels || []).map((l) => l.name); + const body = (pr.body || "").trim(); + const reviewState = await getReviewState(owner, repo, number); + + let threadId = extractThreadId(body); + const shouldCreateThread = + context.eventName === "pull_request_target" && + ["opened", "reopened", "ready_for_review"].includes(action) && + !threadId; + + if (shouldCreateThread) { + const fields = [ + { name: "PR", value: `[#${number}](${url})`, inline: true }, + { name: "Author", value: `[${author}](${authorUrl || url})`, inline: true }, + { name: "Status", value: pr.draft ? "Draft" : "Open", inline: true }, + { name: "Branches", value: `\`${head}\` -> \`${base}\``, inline: true }, + { name: "Changes", value: `+${pr.additions} / -${pr.deletions}`, inline: true }, + { name: "Files Changed", value: String(pr.changed_files), inline: true } + ]; + + if (labels.length) { + fields.push({ + name: "Labels", + value: labels.map((l) => `\`${l}\``).join(" "), + inline: false, + }); + } + + const statusTag = desiredStatusTag({ draft: pr.draft, reviewState, merged: false, closed: false }); + const mappedLabelTags = tagIdsFromLabels(labels); + const appliedTags = [...new Set([statusTag, ...mappedLabelTags].filter(Boolean))]; + + const createPayload = { + content: action === "ready_for_review" ? "🔔 PR is now ready for review" : "🔔 New pull request opened", + thread_name: trimThreadName(`PR #${number} - ${title}`), + applied_tags: appliedTags, + embeds: [ + { + title: `PR #${number}: ${title}`, + url, + description: cleanDescription(body), + color: pr.draft ? 15105570 : 1998671, + author: { + name: author, + url: authorUrl || undefined, + icon_url: authorAvatar || undefined, + }, + fields, + footer: { text: repoFullName }, + timestamp: new Date().toISOString(), + }, + ], + }; + + const result = await discordPost(createPayload); + const createdThreadId = result.channel_id || null; + if (createdThreadId) { + const updatedBody = upsertThreadMarker(body, createdThreadId); + await github.rest.pulls.update({ owner, repo, pull_number: number, body: updatedBody }); + core.info(`Created Discord thread ${createdThreadId} and stored mapping.`); + } else { + core.warning("Discord thread created but channel_id missing in response."); + } + return; + } + + if (!threadId) { + core.info("No mapped Discord thread ID found; skipping update event."); + return; + } + + if (context.eventName === "pull_request_target" && ["edited", "labeled", "unlabeled", "ready_for_review", "converted_to_draft"].includes(action)) { + const statusTag = desiredStatusTag({ + draft: action === "converted_to_draft" ? true : pr.draft, + reviewState, + merged: false, + closed: false, + }); + const mappedLabelTags = tagIdsFromLabels(labels); + const appliedTags = [...new Set([statusTag, ...mappedLabelTags].filter(Boolean))]; + await patchDiscordThread(threadId, { + name: trimThreadName(`PR #${number} - ${title}`), + ...(appliedTags.length ? { applied_tags: appliedTags } : {}), + }); + } + + let updateMessage = null; + let updateEmbed = null; + + if (context.eventName === "pull_request_target") { + if (action === "synchronize") { + const { data: commits } = await github.rest.pulls.listCommits({ owner, repo, pull_number: number, per_page: 5 }); + const list = commits.map((c) => `- \`${c.sha.slice(0, 7)}\` ${c.commit.message.split("\n")[0]}`).join("\n") || "- No commit details"; + updateMessage = `🧩 New commits pushed to PR #${number}`; + updateEmbed = { + title: `Commit Update • PR #${number}`, + url: `${url}/files`, + description: `${list}`, + color: 1998671, + footer: { text: repoFullName }, + timestamp: new Date().toISOString(), + }; + } else if (action === "edited") { + updateMessage = `✏️ PR #${number} details were edited`; + updateEmbed = { + title: `PR Updated • #${number}`, + url, + description: cleanDescription(body, 1200), + color: 1998671, + timestamp: new Date().toISOString(), + }; + } else if (action === "closed") { + const isMerged = !!pr.merged; + const statusTag = desiredStatusTag({ draft: false, reviewState, merged: isMerged, closed: true }); + const mappedLabelTags = tagIdsFromLabels(labels); + const appliedTags = [...new Set([statusTag, ...mappedLabelTags].filter(Boolean))]; + await patchDiscordThread(threadId, { + ...(appliedTags.length ? { applied_tags: appliedTags } : {}), + ...(isMerged ? { archived: true, locked: true } : {}), + }); + + updateMessage = isMerged + ? `✅ PR #${number} was merged` + : `🛑 PR #${number} was closed without merge`; + updateEmbed = { + title: isMerged ? `Merged • PR #${number}` : `Closed • PR #${number}`, + url, + description: isMerged ? "This PR has been merged into the base branch." : "This PR was closed before merge.", + color: isMerged ? 5763719 : 15158332, + timestamp: new Date().toISOString(), + }; + } else if (action === "ready_for_review") { + updateMessage = `🚀 PR #${number} moved from draft to ready for review`; + if (reviewerRoleId) updateMessage += ` <@&${reviewerRoleId}>`; + } else if (action === "converted_to_draft") { + updateMessage = `📝 PR #${number} converted to draft`; + } + } else if (context.eventName === "pull_request_review") { + const review = context.payload.review; + if (review) { + const state = (review.state || "commented").toUpperCase(); + const reviewer = review.user?.login || "reviewer"; + updateMessage = `🧪 Review ${state} by **${reviewer}** on PR #${number}`; + if (state === "CHANGES_REQUESTED" && reviewerRoleId) updateMessage += ` <@&${reviewerRoleId}>`; + updateEmbed = { + title: `Review ${state} • PR #${number}`, + url: review.html_url || url, + description: cleanDescription(review.body || "No review note.", 1000), + color: state === "APPROVED" ? 5763719 : state === "CHANGES_REQUESTED" ? 15158332 : 1998671, + timestamp: new Date().toISOString(), + }; + + if (state === "CHANGES_REQUESTED" || state === "APPROVED") { + const statusTag = desiredStatusTag({ draft: pr.draft, reviewState: state, merged: false, closed: false }); + const mappedLabelTags = tagIdsFromLabels(labels); + const appliedTags = [...new Set([statusTag, ...mappedLabelTags].filter(Boolean))]; + await patchDiscordThread(threadId, { + ...(appliedTags.length ? { applied_tags: appliedTags } : {}), + }); + } + } + } else if (context.eventName === "issue_comment") { + const comment = context.payload.comment; + if (comment) { + const commenter = comment.user?.login || "user"; + updateMessage = `💬 New comment by **${commenter}** on PR #${number}`; + updateEmbed = { + title: `New PR Comment • #${number}`, + url: comment.html_url || url, + description: cleanDescription(comment.body || "No comment body.", 1000), + color: 1998671, + timestamp: new Date().toISOString(), + }; + } + } + + if (!updateMessage && !updateEmbed) { + core.info("No Discord update message for this event/action. Skipping."); + return; + } + + const payload = { content: updateMessage || "" }; + if (updateEmbed) payload.embeds = [updateEmbed]; + await discordPost(payload, { threadId }); + core.info(`Posted update to Discord thread ${threadId}.`); + } catch (err) { + const msg = err && err.message ? err.message : String(err); + core.setFailed(msg); + + const alertWebhook = process.env.DISCORD_ALERT_WEBHOOK_URL; + if (alertWebhook) { + try { + await fetch(alertWebhook, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + username: "OpenScreen", + avatar_url: WEBHOOK_AVATAR, + content: `⚠️ PR->Discord sync failed\n${msg}\nRun: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, + allowed_mentions: { parse: [] } + }) + }); + } catch { + core.warning("Failed to send alert webhook."); + } + } + } + + weekly-contributor-leaderboard: + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + steps: + - name: Post weekly contributor leaderboard + uses: actions/github-script@v7 + env: + DISCORD_SPOTLIGHT_WEBHOOK_URL: ${{ secrets.DISCORD_SPOTLIGHT_WEBHOOK_URL }} + DISCORD_WEBHOOK_USERNAME: ${{ secrets.DISCORD_WEBHOOK_USERNAME }} + DISCORD_WEBHOOK_AVATAR_URL: ${{ secrets.DISCORD_WEBHOOK_AVATAR_URL }} + with: + script: | + const spotlightWebhook = (process.env.DISCORD_SPOTLIGHT_WEBHOOK_URL || "").trim(); + const webhookUsername = (process.env.DISCORD_WEBHOOK_USERNAME || "OpenScreen").trim(); + const webhookAvatar = (process.env.DISCORD_WEBHOOK_AVATAR_URL || "").trim(); + if (!spotlightWebhook) { + core.info("DISCORD_SPOTLIGHT_WEBHOOK_URL missing. Skipping leaderboard post."); + return; + } + + const since = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(); + const owner = context.repo.owner; + const repo = context.repo.repo; + + const q = `repo:${owner}/${repo} is:pr is:merged merged:>=${since.substring(0, 10)}`; + const search = await github.rest.search.issuesAndPullRequests({ + q, + per_page: 100, + }); + + const counter = new Map(); + for (const item of search.data.items) { + const login = item.user?.login; + if (!login) continue; + counter.set(login, (counter.get(login) || 0) + 1); + } + + const ranked = [...counter.entries()] + .sort((a, b) => b[1] - a[1]) + .slice(0, 10); + + const totalMerged = search.data.items.length; + const lines = ranked.length + ? ranked.map(([user, count], idx) => `${idx + 1}. **${user}** - ${count} merged PR(s)`).join("\n") + : "No merged PRs this week."; + + const payload = { + username: webhookUsername, + ...(webhookAvatar ? { avatar_url: webhookAvatar } : {}), + embeds: [ + { + title: "🌟 Weekly Contributor Leaderboard", + description: lines, + color: 1998671, + fields: [ + { name: "Merged PRs (7d)", value: String(totalMerged), inline: true }, + { name: "Repository", value: `${owner}/${repo}`, inline: true }, + { name: "Period", value: "Last 7 days", inline: true } + ], + timestamp: new Date().toISOString() + } + ], + allowed_mentions: { parse: [] } + }; + + const res = await fetch(`${spotlightWebhook}?wait=true`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(payload) + }); + + if (!res.ok) { + const txt = await res.text(); + core.setFailed(`Leaderboard post failed ${res.status}: ${txt}`); + } diff --git a/.gitignore b/.gitignore index 70cc387..771c4bd 100644 --- a/.gitignore +++ b/.gitignore @@ -12,9 +12,11 @@ dist dist-electron dist-ssr *.local +.env # Editor directories and files .vscode/* +.zed/ !.vscode/extensions.json .idea .DS_Store @@ -25,8 +27,19 @@ dist-ssr *.sw? release/** *.kiro/ +.claude/ # npx electron-builder --mac --win # Playwright test-results -playwright-report/ \ No newline at end of file +playwright-report/ + +# Vitest browser mode screenshots +__screenshots__/ + +# shell files +/shell.sh +# Nix +result +result-* +.direnv/ diff --git a/README.md b/README.md index 0e9ed4d..9ed0d1a 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,16 @@ OpenScreen Logo

+ siddharthvaddem%2Fopenscreen | Trendshift +
+
Ask DeepWiki +   + + Join Discord +

#

OpenScreen

@@ -21,21 +28,20 @@ Screen Studio is an awesome product and this is definitely not a 1:1 clone. Open OpenScreen is 100% free for personal and commercial use. Use it, modify it, distribute it. (Just be cool 😁 and give a shoutout if you feel like it !)

- OpenScreen App Preview 3 - OpenScreen App Preview 4 + OpenScreen App Preview 3 + OpenScreen App Preview 4

## Core Features -- Record your whole screen or specific windows. -- Add Automatic zooms or manual zooms (customizable depth levels). -- Record microphone audio and system audio capture. -- Customize the duration and position of zooms however you please. +- Record specific windows or your whole screen. +- Add automatic or manual zooms (adjustable depth levels) and customize their durarion and position. +- Record microphone and system audio. - Crop video recordings to hide parts. - Choose between wallpapers, solid colors, gradients or a custom background. - Motion blur for smoother pan and zoom effects. - Add annotations (text, arrows, images). - Trim sections of the clip. -- Customize speed at different segments. +- Customize the speed of different segments. - Export in different aspect ratios and resolutions. ## Installation @@ -74,9 +80,9 @@ You may need to grant screen recording permissions depending on your desktop env System audio capture relies on Electron's [desktopCapturer](https://www.electronjs.org/docs/latest/api/desktop-capturer) and has some platform-specific quirks: -- **macOS**: Requires macOS 13+. On macOS 14.2+ you'll be prompted to grant audio capture permission. macOS 12 and below does not support system audio (mic still work). +- **macOS**: Requires macOS 13+. On macOS 14.2+ you'll be prompted to grant audio capture permission. macOS 12 and below does not support system audio (mic still works). - **Windows**: Works out of the box. -- **Linux**: Needs PipeWire (default on Ubuntu 22.04+, Fedora 34+). Older PulseAudio-only setups may not support system audio (mic should still works). +- **Linux**: Needs PipeWire (default on Ubuntu 22.04+, Fedora 34+). Older PulseAudio-only setups may not support system audio (mic should still work). ## Built with - Electron @@ -90,10 +96,25 @@ System audio capture relies on Electron's [desktopCapturer](https://www.electron _I'm new to open source, idk what I'm doing lol. If something is wrong please raise an issue 🙏_ +## Documentation + +See the documentation here: +[OpenScreen Docs](https://deepwiki.com/siddharthvaddem/openscreen) + ## Contributing Contributions are welcome! If you’d like to help out or see what’s currently being worked on, take a look at the open issues and the [project roadmap](https://github.com/users/siddharthvaddem/projects/3) to understand the current direction of the project and find ways to contribute. +## Star History + + + + + + Star History Chart + + + ## License This project is licensed under the [MIT License](./LICENSE). By using this software, you agree that the authors are not liable for any issues, damages, or claims arising from its use. diff --git a/biome.json b/biome.json index c4c22f6..517be72 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.3.13/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.12/schema.json", "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true }, "files": { "ignoreUnknown": false, "includes": ["**", "!**/*.css"] }, "formatter": { diff --git a/electron-builder.json5 b/electron-builder.json5 index 40fce0a..1770238 100644 --- a/electron-builder.json5 +++ b/electron-builder.json5 @@ -3,6 +3,11 @@ "$schema": "https://raw.githubusercontent.com/electron-userland/electron-builder/master/packages/app-builder-lib/scheme.json", "appId": "com.siddharthvaddem.openscreen", "asar": true, + // .node binaries can't be dlopen'd from inside an asar — must live unpacked. + "asarUnpack": [ + "node_modules/uiohook-napi/**/*", + "**/*.node" + ], "productName": "Openscreen", "npmRebuild": true, "buildDependenciesFromSource": true, @@ -20,16 +25,20 @@ "!CONTRIBUTING.md", "!LICENSE" ], - "extraResources": [ - { - "from": "public/wallpapers", - "to": "assets/wallpapers" - } - ], - "publish": [{"provider": "github"}], - - "mac": { - "hardenedRuntime": false, + // Asset layout contract: "wallpapers/" under resourcesPath must align with + // assetBaseDir in electron/preload.ts (packaged branch). + "extraResources": [ + { + "from": "public/wallpapers", + "to": "wallpapers" + } + ], + + "mac": { + "notarize": false, + "hardenedRuntime": true, + "entitlements": "macos.entitlements", + "entitlementsInherit": "macos.entitlements", "target": [ { "target": "dmg", @@ -38,13 +47,13 @@ ], "icon": "icons/icons/mac/icon.icns", "artifactName": "${productName}-Mac-${arch}-${version}-Installer.${ext}", - "extendInfo": { - "NSAudioCaptureUsageDescription": "OpenScreen needs audio capture permission to record system audio.", - "NSMicrophoneUsageDescription": "OpenScreen needs microphone access to record voice audio.", - "NSCameraUsageDescription": "OpenScreen needs camera access to record webcam video.", - "NSCameraUseContinuityCameraDeviceType": true, - "com.apple.security.device.audio-input": true - } + "extendInfo": { + "NSAudioCaptureUsageDescription": "OpenScreen needs audio capture permission to record system audio.", + "NSMicrophoneUsageDescription": "OpenScreen needs microphone access to record voice audio.", + "NSCameraUsageDescription": "OpenScreen needs camera access to record webcam video.", + "NSCameraUseContinuityCameraDeviceType": true, + "com.apple.security.device.audio-input": true + } }, "linux": { "target": [ @@ -54,14 +63,14 @@ "artifactName": "${productName}-Linux-${version}.${ext}", "category": "AudioVideo" }, - "win": { - "target": [ - "nsis" - ], - "icon": "icons/icons/win/icon.ico" - }, - "nsis": { - "oneClick": false, - "allowToChangeInstallationDirectory": true - } -} + "win": { + "target": [ + "nsis" + ], + "icon": "icons/icons/win/icon.ico" + }, + "nsis": { + "oneClick": false, + "allowToChangeInstallationDirectory": true + } +} diff --git a/electron/electron-env.d.ts b/electron/electron-env.d.ts index 573aee8..d9ebab2 100644 --- a/electron/electron-env.d.ts +++ b/electron/electron-env.d.ts @@ -26,6 +26,8 @@ interface Window { electronAPI: { getSources: (opts: Electron.SourcesOptions) => Promise; switchToEditor: () => Promise; + switchToHud: () => Promise; + startNewRecording: () => Promise<{ success: boolean; error?: string }>; openSourceSelector: () => Promise; selectSource: (source: ProcessedDesktopSource) => Promise; getSelectedSource: () => Promise; @@ -35,7 +37,12 @@ interface Window { status: string; error?: string; }>; - getAssetBasePath: () => Promise; + requestAccessibilityAccess: () => Promise<{ + success: boolean; + granted: boolean; + error?: string; + }>; + assetBaseUrl: string; storeRecordedVideo: ( videoData: ArrayBuffer, fileName: string, @@ -61,10 +68,12 @@ interface Window { message?: string; error?: string; }>; - setRecordingState: (recording: boolean) => Promise; + setRecordingState: (recording: boolean, recordingId?: number) => Promise; + discardCursorTelemetry: (recordingId: number) => Promise; getCursorTelemetry: (videoPath?: string) => Promise<{ success: boolean; samples: CursorTelemetryPoint[]; + clicks: number[]; message?: string; error?: string; }>; @@ -133,6 +142,10 @@ interface Window { saveShortcuts: (shortcuts: unknown) => Promise<{ success: boolean; error?: string }>; hudOverlayHide: () => void; hudOverlayClose: () => void; + showCountdownOverlay: (value: number, runId: number) => Promise; + setCountdownOverlayValue: (value: number, runId: number) => Promise; + hideCountdownOverlay: (runId: number) => Promise; + onCountdownOverlayValue: (callback: (value: number | null) => void) => () => void; setMicrophoneExpanded: (expanded: boolean) => void; setHasUnsavedChanges: (hasChanges: boolean) => void; onRequestSaveBeforeClose: (callback: () => Promise | boolean) => () => void; diff --git a/electron/i18n.ts b/electron/i18n.ts index b385008..4222741 100644 --- a/electron/i18n.ts +++ b/electron/i18n.ts @@ -5,23 +5,47 @@ import commonEn from "../src/i18n/locales/en/common.json"; import dialogsEn from "../src/i18n/locales/en/dialogs.json"; import commonEs from "../src/i18n/locales/es/common.json"; import dialogsEs from "../src/i18n/locales/es/dialogs.json"; +import commonFr from "../src/i18n/locales/fr/common.json"; +import dialogsFr from "../src/i18n/locales/fr/dialogs.json"; +import commonJa from "../src/i18n/locales/ja-JP/common.json"; +import dialogsJa from "../src/i18n/locales/ja-JP/dialogs.json"; +import commonKo from "../src/i18n/locales/ko-KR/common.json"; +import dialogsKo from "../src/i18n/locales/ko-KR/dialogs.json"; +import commonTr from "../src/i18n/locales/tr/common.json"; +import dialogsTr from "../src/i18n/locales/tr/dialogs.json"; import commonZh from "../src/i18n/locales/zh-CN/common.json"; import dialogsZh from "../src/i18n/locales/zh-CN/dialogs.json"; +import commonZhTw from "../src/i18n/locales/zh-TW/common.json"; +import dialogsZhTw from "../src/i18n/locales/zh-TW/dialogs.json"; -type Locale = "en" | "zh-CN" | "es"; +type Locale = "en" | "zh-CN" | "zh-TW" | "es" | "fr" | "ja-JP" | "ko-KR" | "tr"; type Namespace = "common" | "dialogs"; type MessageMap = Record; const messages: Record> = { en: { common: commonEn, dialogs: dialogsEn }, "zh-CN": { common: commonZh, dialogs: dialogsZh }, + "zh-TW": { common: commonZhTw, dialogs: dialogsZhTw }, es: { common: commonEs, dialogs: dialogsEs }, + fr: { common: commonFr, dialogs: dialogsFr }, + "ja-JP": { common: commonJa, dialogs: dialogsJa }, + "ko-KR": { common: commonKo, dialogs: dialogsKo }, + tr: { common: commonTr, dialogs: dialogsTr }, }; let currentLocale: Locale = "en"; export function setMainLocale(locale: string) { - if (locale === "en" || locale === "zh-CN" || locale === "es") { + if ( + locale === "en" || + locale === "zh-CN" || + locale === "zh-TW" || + locale === "es" || + locale === "fr" || + locale === "ja-JP" || + locale === "ko-KR" || + locale === "tr" + ) { currentLocale = locale; } } diff --git a/electron/ipc/handlers.ts b/electron/ipc/handlers.ts index 78d8344..30fbf23 100644 --- a/electron/ipc/handlers.ts +++ b/electron/ipc/handlers.ts @@ -1,6 +1,10 @@ import fs from "node:fs/promises"; +import { createRequire } from "node:module"; import path from "node:path"; -import { fileURLToPath, pathToFileURL } from "node:url"; +import { fileURLToPath } from "node:url"; + +const nodeRequire = createRequire(import.meta.url); + import { app, BrowserWindow, @@ -11,9 +15,14 @@ import { shell, systemPreferences, } from "electron"; +import { + type CursorTelemetryPoint, + createCursorTelemetryBuffer, +} from "../../src/lib/cursorTelemetryBuffer"; import { normalizeProjectMedia, normalizeRecordingSession, + type ProjectMedia, type RecordingSession, type StoreRecordedSessionInput, } from "../../src/lib/recordingSession"; @@ -23,6 +32,143 @@ import { RECORDINGS_DIR } from "../main"; const PROJECT_FILE_EXTENSION = "openscreen"; const SHORTCUTS_FILE = path.join(app.getPath("userData"), "shortcuts.json"); const RECORDING_SESSION_SUFFIX = ".session.json"; +const ALLOWED_IMPORT_VIDEO_EXTENSIONS = new Set([".webm", ".mp4", ".mov", ".avi", ".mkv"]); + +/** + * Paths explicitly approved by the user via file picker dialogs or project loads. + * These are added at runtime when the user selects files from outside the default directories. + */ +const approvedPaths = new Set(); + +function approveFilePath(filePath: string): void { + approvedPaths.add(path.resolve(filePath)); +} + +function getAllowedReadDirs(): string[] { + return [RECORDINGS_DIR]; +} + +function isPathWithinDir(filePath: string, dirPath: string): boolean { + const resolved = path.resolve(filePath); + const resolvedDir = path.resolve(dirPath); + return resolved === resolvedDir || resolved.startsWith(resolvedDir + path.sep); +} + +function isPathAllowed(filePath: string): boolean { + const resolved = path.resolve(filePath); + if (approvedPaths.has(resolved)) return true; + return getAllowedReadDirs().some((dir) => isPathWithinDir(resolved, dir)); +} + +function hasAllowedImportVideoExtension(filePath: string): boolean { + return ALLOWED_IMPORT_VIDEO_EXTENSIONS.has(path.extname(filePath).toLowerCase()); +} + +async function approveReadableVideoPath( + filePath?: string | null, + trustedDirs?: string[], +): Promise { + const normalizedPath = normalizeVideoSourcePath(filePath); + if (!normalizedPath) { + return null; + } + + if (isPathAllowed(normalizedPath)) { + return normalizedPath; + } + + if (!hasAllowedImportVideoExtension(normalizedPath)) { + return null; + } + + // When called with trustedDirs (e.g. from project load), only auto-approve + // paths within those directories. This prevents malicious project files from + // approving reads to arbitrary filesystem locations. + if (trustedDirs) { + const resolved = path.resolve(normalizedPath); + const withinTrusted = trustedDirs.some((dir) => isPathWithinDir(resolved, dir)); + if (!withinTrusted) { + return null; + } + } + + try { + const stats = await fs.stat(normalizedPath); + if (!stats.isFile()) { + return null; + } + } catch { + return null; + } + + approveFilePath(normalizedPath); + return normalizedPath; +} + +function resolveRecordingOutputPath(fileName: string): string { + const trimmed = fileName.trim(); + if (!trimmed) { + throw new Error("Invalid recording file name"); + } + + const parsedPath = path.parse(trimmed); + const hasTraversalSegments = trimmed.split(/[\\/]+/).some((segment) => segment === ".."); + const isNestedPath = + parsedPath.dir !== "" || + path.isAbsolute(trimmed) || + trimmed.includes("/") || + trimmed.includes("\\"); + if (hasTraversalSegments || isNestedPath || parsedPath.base !== trimmed) { + throw new Error("Recording file name must not contain path segments"); + } + + return path.join(RECORDINGS_DIR, parsedPath.base); +} + +async function getApprovedProjectSession( + project: unknown, + projectFilePath?: string, +): Promise { + if (!project || typeof project !== "object") { + return null; + } + + const rawProject = project as { media?: unknown; videoPath?: unknown }; + const media: ProjectMedia | null = + normalizeProjectMedia(rawProject.media) ?? + (typeof rawProject.videoPath === "string" + ? { + screenVideoPath: normalizeVideoSourcePath(rawProject.videoPath) ?? rawProject.videoPath, + } + : null); + + if (!media) { + return null; + } + + // Only auto-approve media paths within the project's directory or RECORDINGS_DIR. + // This prevents crafted project files from approving reads to arbitrary locations. + const trustedDirs = [RECORDINGS_DIR]; + if (projectFilePath) { + trustedDirs.push(path.dirname(path.resolve(projectFilePath))); + } + + const screenVideoPath = await approveReadableVideoPath(media.screenVideoPath, trustedDirs); + if (!screenVideoPath) { + throw new Error("Project references an invalid or unsupported screen video path"); + } + + const webcamVideoPath = media.webcamVideoPath + ? await approveReadableVideoPath(media.webcamVideoPath, trustedDirs) + : undefined; + if (media.webcamVideoPath && !webcamVideoPath) { + throw new Error("Project references an invalid or unsupported webcam video path"); + } + + return webcamVideoPath + ? { screenVideoPath, webcamVideoPath, createdAt: Date.now() } + : { screenVideoPath, createdAt: Date.now() }; +} type SelectedSource = { name: string; @@ -121,12 +267,12 @@ async function storeRecordedSessionFiles(payload: StoreRecordedSessionInput) { typeof payload.createdAt === "number" && Number.isFinite(payload.createdAt) ? payload.createdAt : Date.now(); - const screenVideoPath = path.join(RECORDINGS_DIR, payload.screen.fileName); + const screenVideoPath = resolveRecordingOutputPath(payload.screen.fileName); await fs.writeFile(screenVideoPath, Buffer.from(payload.screen.videoData)); let webcamVideoPath: string | undefined; if (payload.webcam) { - webcamVideoPath = path.join(RECORDINGS_DIR, payload.webcam.fileName); + webcamVideoPath = resolveRecordingOutputPath(payload.webcam.fileName); await fs.writeFile(webcamVideoPath, Buffer.from(payload.webcam.videoData)); } @@ -137,14 +283,28 @@ async function storeRecordedSessionFiles(payload: StoreRecordedSessionInput) { currentProjectPath = null; const telemetryPath = `${screenVideoPath}.cursor.json`; - if (pendingCursorSamples.length > 0) { - await fs.writeFile( - telemetryPath, - JSON.stringify({ version: CURSOR_TELEMETRY_VERSION, samples: pendingCursorSamples }, null, 2), - "utf-8", - ); + const pendingBatch = cursorTelemetryBuffer.takeNextBatch(); + const pendingClicks = takeCursorClickTimestamps(); + if ((pendingBatch && pendingBatch.samples.length > 0) || pendingClicks.length > 0) { + try { + await fs.writeFile( + telemetryPath, + JSON.stringify( + { + version: CURSOR_TELEMETRY_VERSION, + samples: pendingBatch?.samples ?? [], + clicks: pendingClicks, + }, + null, + 2, + ), + "utf-8", + ); + } catch (err) { + if (pendingBatch) cursorTelemetryBuffer.prependBatch(pendingBatch); + throw err; + } } - pendingCursorSamples = []; const sessionManifestPath = path.join( RECORDINGS_DIR, @@ -164,26 +324,120 @@ const CURSOR_TELEMETRY_VERSION = 1; const CURSOR_SAMPLE_INTERVAL_MS = 100; const MAX_CURSOR_SAMPLES = 60 * 60 * 10; // 1 hour @ 10Hz -interface CursorTelemetryPoint { - timeMs: number; - cx: number; - cy: number; -} - let cursorCaptureInterval: NodeJS.Timeout | null = null; let cursorCaptureStartTimeMs = 0; -let activeCursorSamples: CursorTelemetryPoint[] = []; -let pendingCursorSamples: CursorTelemetryPoint[] = []; +const cursorTelemetryBuffer = createCursorTelemetryBuffer({ + maxActiveSamples: MAX_CURSOR_SAMPLES, +}); + +// Mouse click timestamps (macOS only — uiohook-napi behind Accessibility). +const MAX_CURSOR_CLICKS = 60 * 60 * 60; // ~1 click/sec for an hour +let cursorClickTimestampsMs: number[] = []; +let uioHookInstance: { + start: () => void; + stop: () => void; + on: (...a: unknown[]) => void; + off?: (...a: unknown[]) => void; + removeListener?: (...a: unknown[]) => void; +} | null = null; +let uioHookMouseDownHandler: ((event: { time?: number }) => void) | null = null; +let uioHookFailureLogged = false; function clamp(value: number, min: number, max: number) { return Math.min(max, Math.max(min, value)); } +function loadUioHookForClicks(): typeof uioHookInstance { + try { + // Dynamic require + try/catch so a broken native binary doesn't crash startup. + const mod = nodeRequire("uiohook-napi"); + const candidate = mod.uIOhook ?? mod.default?.uIOhook ?? mod.uiohook ?? mod.default; + if (candidate && typeof candidate.start === "function" && typeof candidate.on === "function") { + return candidate; + } + return null; + } catch (error) { + if (!uioHookFailureLogged) { + uioHookFailureLogged = true; + console.warn("[clickCapture] uiohook-napi unavailable:", error); + } + return null; + } +} + +function startClickCapture() { + if (process.platform !== "darwin") return; + if (uioHookInstance) return; + + // Passive check — the prompt fires from the renderer when the user toggles + // "Only on clicks" so it doesn't stack with the screen-recording prompt. + try { + if (!systemPreferences.isTrustedAccessibilityClient(false)) { + if (!uioHookFailureLogged) { + uioHookFailureLogged = true; + console.warn( + "[clickCapture] Accessibility permission not granted — click capture disabled.", + ); + } + return; + } + } catch { + // fall through; uiohook will fail defensively below + } + + const hook = loadUioHookForClicks(); + if (!hook) return; + + uioHookMouseDownHandler = (event) => { + const elapsed = Math.max(0, Date.now() - cursorCaptureStartTimeMs); + void event; + if (cursorClickTimestampsMs.length >= MAX_CURSOR_CLICKS) return; + cursorClickTimestampsMs.push(elapsed); + }; + + try { + hook.on("mousedown", uioHookMouseDownHandler); + hook.start(); + uioHookInstance = hook; + } catch (error) { + if (!uioHookFailureLogged) { + uioHookFailureLogged = true; + console.warn("[clickCapture] failed to start uiohook:", error); + } + uioHookMouseDownHandler = null; + } +} + +function stopClickCapture() { + if (!uioHookInstance) return; + try { + if (uioHookMouseDownHandler) { + if (typeof uioHookInstance.off === "function") { + uioHookInstance.off("mousedown", uioHookMouseDownHandler); + } else if (typeof uioHookInstance.removeListener === "function") { + uioHookInstance.removeListener("mousedown", uioHookMouseDownHandler); + } + } + uioHookInstance.stop(); + } catch (error) { + console.warn("[clickCapture] failed to stop uiohook:", error); + } + uioHookInstance = null; + uioHookMouseDownHandler = null; +} + +function takeCursorClickTimestamps(): number[] { + const out = cursorClickTimestampsMs; + cursorClickTimestampsMs = []; + return out; +} + function stopCursorCapture() { if (cursorCaptureInterval) { clearInterval(cursorCaptureInterval); cursorCaptureInterval = null; } + stopClickCapture(); } function sampleCursorPoint() { @@ -200,33 +454,207 @@ function sampleCursorPoint() { const cx = clamp((cursor.x - bounds.x) / width, 0, 1); const cy = clamp((cursor.y - bounds.y) / height, 0, 1); - activeCursorSamples.push({ + cursorTelemetryBuffer.push({ timeMs: Math.max(0, Date.now() - cursorCaptureStartTimeMs), cx, cy, }); - - if (activeCursorSamples.length > MAX_CURSOR_SAMPLES) { - activeCursorSamples.shift(); - } } export function registerIpcHandlers( createEditorWindow: () => void, createSourceSelectorWindow: () => BrowserWindow, + createCountdownOverlayWindow: () => BrowserWindow, getMainWindow: () => BrowserWindow | null, getSourceSelectorWindow: () => BrowserWindow | null, + getCountdownOverlayWindow: () => BrowserWindow | null, onRecordingStateChange?: (recording: boolean, sourceName: string) => void, + switchToHud?: () => void, ) { + const supportsWindowOpacity = process.platform !== "linux"; + const countdownOverlayState = { + visible: false, + value: null as number | null, + activeRunId: null as number | null, + hideCommitId: 0, + hideCommitTimer: null as ReturnType | null, + }; + const COUNTDOWN_OVERLAY_HIDE_DEBOUNCE_MS = 1200; + + const clearCountdownOverlayHideCommit = () => { + if (countdownOverlayState.hideCommitTimer) { + clearTimeout(countdownOverlayState.hideCommitTimer); + countdownOverlayState.hideCommitTimer = null; + } + }; + + const commitCountdownOverlayHide = (win: BrowserWindow, hideCommitId: number) => { + if (win.isDestroyed()) { + return; + } + + if (countdownOverlayState.visible || countdownOverlayState.hideCommitId !== hideCommitId) { + return; + } + + win.hide(); + if (supportsWindowOpacity) { + // Reset baseline opacity for the next show cycle. + win.setOpacity(1); + } + }; + + const flushCountdownOverlayState = (win: BrowserWindow) => { + if (win.isDestroyed()) { + return; + } + + clearCountdownOverlayHideCommit(); + win.webContents.send("countdown-overlay-value", countdownOverlayState.value); + if (!countdownOverlayState.visible) { + return; + } + + if (win.isVisible()) { + if (supportsWindowOpacity) { + win.setOpacity(1); + } + return; + } + + setTimeout(() => { + if (!win.isDestroyed() && countdownOverlayState.visible && !win.isVisible()) { + if (supportsWindowOpacity) { + win.setOpacity(0); + } + win.showInactive(); + + if (supportsWindowOpacity) { + setTimeout(() => { + if (!win.isDestroyed() && countdownOverlayState.visible && win.isVisible()) { + win.setOpacity(1); + } + }, 0); + } + } + }, 16); + }; + + ipcMain.handle("countdown-overlay-show", (_, value: number, runId: number) => { + countdownOverlayState.activeRunId = runId; + countdownOverlayState.visible = true; + countdownOverlayState.value = value; + + const win = getCountdownOverlayWindow() ?? createCountdownOverlayWindow(); + if (win.isDestroyed()) { + return; + } + + if (win.webContents.isLoading()) { + win.webContents.once("did-finish-load", () => { + if (!win.isDestroyed()) { + flushCountdownOverlayState(win); + } + }); + } else { + flushCountdownOverlayState(win); + } + }); + + ipcMain.handle("countdown-overlay-set-value", (_, value: number, runId: number) => { + if (countdownOverlayState.activeRunId !== runId || !countdownOverlayState.visible) { + return; + } + + countdownOverlayState.value = value; + + const win = getCountdownOverlayWindow(); + if (!win || win.isDestroyed()) { + return; + } + + if (win.webContents.isLoading()) { + return; + } + + win.webContents.send("countdown-overlay-value", value); + }); + + ipcMain.handle("countdown-overlay-hide", (_, runId: number) => { + if (countdownOverlayState.activeRunId !== runId) { + return; + } + + countdownOverlayState.visible = false; + countdownOverlayState.hideCommitId += 1; + const hideCommitId = countdownOverlayState.hideCommitId; + clearCountdownOverlayHideCommit(); + + const win = getCountdownOverlayWindow(); + if (!win || win.isDestroyed()) { + countdownOverlayState.value = null; + return; + } + + if (supportsWindowOpacity) { + // Hide visually immediately to avoid hide/show compositor flashes on rapid restart. + win.setOpacity(0); + } + + countdownOverlayState.value = null; + if (!win.webContents.isLoading()) { + win.webContents.send("countdown-overlay-value", countdownOverlayState.value); + } + + if (!supportsWindowOpacity) { + win.hide(); + return; + } + + countdownOverlayState.hideCommitTimer = setTimeout(() => { + countdownOverlayState.hideCommitTimer = null; + commitCountdownOverlayHide(win, hideCommitId); + }, COUNTDOWN_OVERLAY_HIDE_DEBOUNCE_MS); + }); + + ipcMain.handle("switch-to-hud", () => { + if (switchToHud) switchToHud(); + }); + ipcMain.handle("start-new-recording", () => { + try { + setCurrentRecordingSessionState(null); + if (switchToHud) { + switchToHud(); + } + return { success: true }; + } catch (error) { + console.error("Failed to start new recording:", error); + return { success: false, error: String(error) }; + } + }); + ipcMain.handle("get-sources", async (_, opts) => { + const ownWindowSourceIds = new Set( + BrowserWindow.getAllWindows() + .map((win) => { + try { + return win.getMediaSourceId(); + } catch { + return null; + } + }) + .filter((id): id is string => Boolean(id)), + ); const sources = await desktopCapturer.getSources(opts); - return sources.map((source) => ({ - id: source.id, - name: source.name, - display_id: source.display_id, - thumbnail: source.thumbnail ? source.thumbnail.toDataURL() : null, - appIcon: source.appIcon ? source.appIcon.toDataURL() : null, - })); + return sources + .filter((source) => !ownWindowSourceIds.has(source.id)) + .map((source) => ({ + id: source.id, + name: source.name, + display_id: source.display_id, + thumbnail: source.thumbnail ? source.thumbnail.toDataURL() : null, + appIcon: source.appIcon ? source.appIcon.toDataURL() : null, + })); }); ipcMain.handle("select-source", (_, source: SelectedSource) => { @@ -274,6 +702,22 @@ export function registerIpcHandlers( } }); + // macOS Accessibility prompt for global click capture. First call shows the + // system dialog; the user has to toggle the app in System Settings (no + // programmatic grant exists for Accessibility). + ipcMain.handle("request-accessibility-access", () => { + if (process.platform !== "darwin") { + return { success: true, granted: true }; + } + try { + const granted = systemPreferences.isTrustedAccessibilityClient(true); + return { success: true, granted }; + } catch (error) { + console.error("Failed to request accessibility access:", error); + return { success: false, granted: false, error: String(error) }; + } + }); + ipcMain.handle("open-source-selector", () => { const sourceSelectorWin = getSourceSelectorWindow(); if (sourceSelectorWin) { @@ -335,7 +779,24 @@ export function registerIpcHandlers( return { success: false, message: "No recorded video found" }; } - const latestVideo = videoFiles.sort().reverse()[0]; + // Sort by most recently modified to reliably get the latest recording. + // Lexicographic sort is unreliable (e.g. recording-9.webm > recording-10.webm). + let latestVideo: string | null = null; + let latestMtimeMs = 0; + for (const file of videoFiles) { + try { + const stat = await fs.stat(path.join(RECORDINGS_DIR, file)); + if (stat.mtimeMs > latestMtimeMs) { + latestMtimeMs = stat.mtimeMs; + latestVideo = file; + } + } catch { + // Skip inaccessible files. + } + } + if (!latestVideo) { + return { success: false, message: "No recorded video found" }; + } const videoPath = path.join(RECORDINGS_DIR, latestVideo); return { success: true, path: videoPath }; @@ -352,6 +813,14 @@ export function registerIpcHandlers( return { success: false, message: "Invalid file path" }; } + if (!isPathAllowed(normalizedPath)) { + console.warn( + "[read-binary-file] Rejected path outside allowed directories:", + normalizedPath, + ); + return { success: false, message: "Access denied: path outside allowed directories" }; + } + const data = await fs.readFile(normalizedPath); return { success: true, @@ -368,18 +837,23 @@ export function registerIpcHandlers( } }); - ipcMain.handle("set-recording-state", (_, recording: boolean) => { + ipcMain.handle("set-recording-state", (_, recording: boolean, recordingId?: number) => { if (recording) { stopCursorCapture(); - activeCursorSamples = []; - pendingCursorSamples = []; + // The renderer is the source of truth for the recording id (it + // uses the same id as the saved fileName). Fall back to a + // timestamp only if the renderer didn't supply one, so the + // buffer always has a stable key per session. + const id = typeof recordingId === "number" ? recordingId : Date.now(); + cursorTelemetryBuffer.startSession(id); cursorCaptureStartTimeMs = Date.now(); + cursorClickTimestampsMs = []; + startClickCapture(); sampleCursorPoint(); cursorCaptureInterval = setInterval(sampleCursorPoint, CURSOR_SAMPLE_INTERVAL_MS); } else { stopCursorCapture(); - pendingCursorSamples = [...activeCursorSamples]; - activeCursorSamples = []; + cursorTelemetryBuffer.endSession(); } const source = selectedSource || { name: "Screen" }; @@ -388,6 +862,10 @@ export function registerIpcHandlers( } }); + ipcMain.handle("discard-cursor-telemetry", (_, recordingId: number) => { + cursorTelemetryBuffer.discardBatch(recordingId); + }); + ipcMain.handle("get-cursor-telemetry", async (_, videoPath?: string) => { const targetVideoPath = normalizeVideoSourcePath( videoPath ?? currentRecordingSession?.screenVideoPath, @@ -396,6 +874,14 @@ export function registerIpcHandlers( return { success: true, samples: [] }; } + if (!isPathAllowed(targetVideoPath)) { + console.warn( + "[get-cursor-telemetry] Rejected path outside allowed directories:", + targetVideoPath, + ); + return { success: true, samples: [] }; + } + const telemetryPath = `${targetVideoPath}.cursor.json`; try { const content = await fs.readFile(telemetryPath, "utf-8"); @@ -427,11 +913,19 @@ export function registerIpcHandlers( }) .sort((a: CursorTelemetryPoint, b: CursorTelemetryPoint) => a.timeMs - b.timeMs); - return { success: true, samples }; + const rawClicks = Array.isArray(parsed?.clicks) ? parsed.clicks : []; + const clicks: number[] = rawClicks + .map((value: unknown) => + typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : null, + ) + .filter((v: number | null): v is number => v !== null) + .sort((a: number, b: number) => a - b); + + return { success: true, samples, clicks }; } catch (error) { const nodeError = error as NodeJS.ErrnoException; if (nodeError.code === "ENOENT") { - return { success: true, samples: [] }; + return { success: true, samples: [], clicks: [] }; } console.error("Failed to load cursor telemetry:", error); return { @@ -439,13 +933,26 @@ export function registerIpcHandlers( message: "Failed to load cursor telemetry", error: String(error), samples: [], + clicks: [], }; } }); ipcMain.handle("open-external-url", async (_, url: string) => { try { - await shell.openExternal(url); + const ALLOWED_SCHEMES = ["http:", "https:", "mailto:"]; + let parsed: URL; + try { + parsed = new URL(url); + } catch { + return { success: false, error: "Invalid URL" }; + } + + if (!ALLOWED_SCHEMES.includes(parsed.protocol)) { + return { success: false, error: `Unsupported URL scheme: ${parsed.protocol}` }; + } + + await shell.openExternal(parsed.toString()); return { success: true }; } catch (error) { console.error("Failed to open URL:", error); @@ -453,20 +960,15 @@ export function registerIpcHandlers( } }); - // Return base path for assets so renderer can resolve file:// paths in production - ipcMain.handle("get-asset-base-path", () => { - try { - if (app.isPackaged) { - const assetPath = path.join(process.resourcesPath, "assets"); - return pathToFileURL(`${assetPath}${path.sep}`).toString(); - } - const assetPath = path.join(app.getAppPath(), "public", "assets"); - return pathToFileURL(`${assetPath}${path.sep}`).toString(); - } catch (err) { - console.error("Failed to resolve asset base path:", err); - return null; - } - }); + /** + * Handles saving an exported video file. + * Shows a save dialog, normalizes the file path for the current OS, + * ensures the directory exists, and writes the video data. + * @param _ - Unused event parameter. + * @param videoData - The exported video as an ArrayBuffer. + * @param fileName - Suggested filename for the save dialog. + * @returns Object with success status, optional file path, and error details. + */ ipcMain.handle("save-exported-video", async (_, videoData: ArrayBuffer, fileName: string) => { try { @@ -493,11 +995,18 @@ export function registerIpcHandlers( }; } - await fs.writeFile(result.filePath, Buffer.from(videoData)); + // --- FIX: Normalize the path for Windows compatibility --- + const normalizedPath = path.normalize(result.filePath); + + // Ensure the parent directory exists (Windows may fail if the folder is missing) + await fs.mkdir(path.dirname(normalizedPath), { recursive: true }); + // --- END FIX --- + + await fs.writeFile(normalizedPath, Buffer.from(videoData)); return { success: true, - path: result.filePath, + path: normalizedPath, message: "Video exported successfully", }; } catch (error) { @@ -509,7 +1018,6 @@ export function registerIpcHandlers( }; } }); - ipcMain.handle("open-video-file-picker", async () => { try { const result = await dialog.showOpenDialog({ @@ -529,10 +1037,17 @@ export function registerIpcHandlers( return { success: false, canceled: true }; } + const approvedPath = await approveReadableVideoPath(result.filePaths[0]); + if (!approvedPath) { + return { + success: false, + message: "Selected file is not a supported video", + }; + } currentProjectPath = null; return { success: true, - path: result.filePaths[0], + path: approvedPath, }; } catch (error) { console.error("Failed to open file picker:", error); @@ -658,19 +1173,9 @@ export function registerIpcHandlers( const filePath = result.filePaths[0]; const content = await fs.readFile(filePath, "utf-8"); const project = JSON.parse(content); + const session = await getApprovedProjectSession(project, filePath); currentProjectPath = filePath; - if (project && typeof project === "object") { - const rawProject = project as { media?: unknown; videoPath?: unknown }; - const media = - normalizeProjectMedia(rawProject.media) ?? - (typeof rawProject.videoPath === "string" - ? { - screenVideoPath: - normalizeVideoSourcePath(rawProject.videoPath) ?? rawProject.videoPath, - } - : null); - setCurrentRecordingSessionState(media ? { ...media, createdAt: Date.now() } : null); - } + setCurrentRecordingSessionState(session); return { success: true, @@ -695,18 +1200,8 @@ export function registerIpcHandlers( const content = await fs.readFile(currentProjectPath, "utf-8"); const project = JSON.parse(content); - if (project && typeof project === "object") { - const rawProject = project as { media?: unknown; videoPath?: unknown }; - const media = - normalizeProjectMedia(rawProject.media) ?? - (typeof rawProject.videoPath === "string" - ? { - screenVideoPath: - normalizeVideoSourcePath(rawProject.videoPath) ?? rawProject.videoPath, - } - : null); - setCurrentRecordingSessionState(media ? { ...media, createdAt: Date.now() } : null); - } + const session = await getApprovedProjectSession(project, currentProjectPath); + setCurrentRecordingSessionState(session); return { success: true, path: currentProjectPath, @@ -735,12 +1230,22 @@ export function registerIpcHandlers( }); ipcMain.handle("set-current-video-path", async (_, path: string) => { - const restoredSession = await loadRecordedSessionForVideoPath(path); + const normalizedPath = normalizeVideoSourcePath(path); + if (!normalizedPath || !isPathAllowed(normalizedPath)) { + return { success: false, message: "Video path has not been approved" }; + } + + const restoredSession = await loadRecordedSessionForVideoPath(normalizedPath); if (restoredSession) { + // Approve all media paths from the restored session so they can be read later + approveFilePath(restoredSession.screenVideoPath); + if (restoredSession.webcamVideoPath) { + approveFilePath(restoredSession.webcamVideoPath); + } setCurrentRecordingSessionState(restoredSession); } else { setCurrentRecordingSessionState({ - screenVideoPath: normalizeVideoSourcePath(path) ?? path, + screenVideoPath: normalizedPath, createdAt: Date.now(), }); } diff --git a/electron/main.ts b/electron/main.ts index 7e19d46..ad0a33f 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -14,7 +14,12 @@ import { } from "electron"; import { mainT, setMainLocale } from "./i18n"; import { registerIpcHandlers } from "./ipc/handlers"; -import { createEditorWindow, createHudOverlayWindow, createSourceSelectorWindow } from "./windows"; +import { + createCountdownOverlayWindow, + createEditorWindow, + createHudOverlayWindow, + createSourceSelectorWindow, +} from "./windows"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -60,12 +65,15 @@ process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL // Window references let mainWindow: BrowserWindow | null = null; let sourceSelectorWindow: BrowserWindow | null = null; +let countdownOverlayWindow: BrowserWindow | null = null; let tray: Tray | null = null; let selectedSourceName = ""; +const isMac = process.platform === "darwin"; +const trayIconSize = isMac ? 16 : 24; // Tray Icons -const defaultTrayIcon = getTrayIcon("openscreen.png"); -const recordingTrayIcon = getTrayIcon("rec-button.png"); +const defaultTrayIcon = getTrayIcon("openscreen.png", trayIconSize); +const recordingTrayIcon = getTrayIcon("rec-button.png", trayIconSize); function createWindow() { mainWindow = createHudOverlayWindow(); @@ -199,12 +207,12 @@ function createTray() { }); } -function getTrayIcon(filename: string) { +function getTrayIcon(filename: string, size: number) { return nativeImage .createFromPath(path.join(process.env.VITE_PUBLIC || RENDERER_DIST, filename)) .resize({ - width: 24, - height: 24, + width: size, + height: size, quality: "best", }); } @@ -320,6 +328,18 @@ function createSourceSelectorWindowWrapper() { return sourceSelectorWindow; } +function createCountdownOverlayWindowWrapper() { + if (countdownOverlayWindow && !countdownOverlayWindow.isDestroyed()) { + return countdownOverlayWindow; + } + + countdownOverlayWindow = createCountdownOverlayWindow(); + countdownOverlayWindow.on("closed", () => { + countdownOverlayWindow = null; + }); + return countdownOverlayWindow; +} + // On macOS, applications and their menu bar stay active until the user quits // explicitly with Cmd + Q. app.on("window-all-closed", () => { @@ -329,8 +349,17 @@ app.on("window-all-closed", () => { app.on("activate", () => { // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. - if (BrowserWindow.getAllWindows().length === 0) { - createWindow(); + const hasVisibleWindow = BrowserWindow.getAllWindows().some((window) => { + if (window.isDestroyed() || !window.isVisible()) { + return false; + } + + const url = window.webContents.getURL(); + const isCountdownOverlayWindow = url.includes("windowType=countdown-overlay"); + return !isCountdownOverlayWindow; + }); + if (!hasVisibleWindow) { + showMainWindow(); } }); @@ -371,11 +400,23 @@ app.whenReady().then(async () => { // Ensure recordings directory exists await ensureRecordingsDir(); + function switchToHudWrapper() { + if (mainWindow) { + isForceClosing = true; + mainWindow.close(); + isForceClosing = false; + mainWindow = null; + } + showMainWindow(); + } + registerIpcHandlers( createEditorWindowWrapper, createSourceSelectorWindowWrapper, + createCountdownOverlayWindowWrapper, () => mainWindow, () => sourceSelectorWindow, + () => countdownOverlayWindow, (recording: boolean, sourceName: string) => { selectedSourceName = sourceName; if (!tray) createTray(); @@ -384,6 +425,7 @@ app.whenReady().then(async () => { showMainWindow(); } }, + switchToHudWrapper, ); createWindow(); }); diff --git a/electron/preload.ts b/electron/preload.ts index 8f1836b..6c705d7 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -1,23 +1,33 @@ import { contextBridge, ipcRenderer } from "electron"; import type { RecordingSession, StoreRecordedSessionInput } from "../src/lib/recordingSession"; +// Asset base URL is passed from the main process via webPreferences.additionalArguments +// (see windows.ts). Sandboxed preloads cannot import node:path / node:url, so we +// can't compute it here. +const ASSET_BASE_URL_ARG_PREFIX = "--asset-base-url="; +const assetBaseUrlArg = process.argv.find((arg) => arg.startsWith(ASSET_BASE_URL_ARG_PREFIX)); +const assetBaseUrl = assetBaseUrlArg ? assetBaseUrlArg.slice(ASSET_BASE_URL_ARG_PREFIX.length) : ""; + contextBridge.exposeInMainWorld("electronAPI", { + assetBaseUrl, hudOverlayHide: () => { ipcRenderer.send("hud-overlay-hide"); }, hudOverlayClose: () => { ipcRenderer.send("hud-overlay-close"); }, - getAssetBasePath: async () => { - // ask main process for the correct base path (production vs dev) - return await ipcRenderer.invoke("get-asset-base-path"); - }, getSources: async (opts: Electron.SourcesOptions) => { return await ipcRenderer.invoke("get-sources", opts); }, switchToEditor: () => { return ipcRenderer.invoke("switch-to-editor"); }, + switchToHud: () => { + return ipcRenderer.invoke("switch-to-hud"); + }, + startNewRecording: () => { + return ipcRenderer.invoke("start-new-recording"); + }, openSourceSelector: () => { return ipcRenderer.invoke("open-source-selector"); }, @@ -30,6 +40,9 @@ contextBridge.exposeInMainWorld("electronAPI", { requestCameraAccess: () => { return ipcRenderer.invoke("request-camera-access"); }, + requestAccessibilityAccess: () => { + return ipcRenderer.invoke("request-accessibility-access"); + }, storeRecordedVideo: (videoData: ArrayBuffer, fileName: string) => { return ipcRenderer.invoke("store-recorded-video", videoData, fileName); @@ -41,12 +54,15 @@ contextBridge.exposeInMainWorld("electronAPI", { getRecordedVideoPath: () => { return ipcRenderer.invoke("get-recorded-video-path"); }, - setRecordingState: (recording: boolean) => { - return ipcRenderer.invoke("set-recording-state", recording); + setRecordingState: (recording: boolean, recordingId?: number) => { + return ipcRenderer.invoke("set-recording-state", recording, recordingId); }, getCursorTelemetry: (videoPath?: string) => { return ipcRenderer.invoke("get-cursor-telemetry", videoPath); }, + discardCursorTelemetry: (recordingId: number) => { + return ipcRenderer.invoke("discard-cursor-telemetry", recordingId); + }, onStopRecordingFromTray: (callback: () => void) => { const listener = () => callback(); ipcRenderer.on("stop-recording-from-tray", listener); @@ -124,6 +140,20 @@ contextBridge.exposeInMainWorld("electronAPI", { setHasUnsavedChanges: (hasChanges: boolean) => { ipcRenderer.send("set-has-unsaved-changes", hasChanges); }, + showCountdownOverlay: (value: number, runId: number) => { + return ipcRenderer.invoke("countdown-overlay-show", value, runId); + }, + setCountdownOverlayValue: (value: number, runId: number) => { + return ipcRenderer.invoke("countdown-overlay-set-value", value, runId); + }, + hideCountdownOverlay: (runId: number) => { + return ipcRenderer.invoke("countdown-overlay-hide", runId); + }, + onCountdownOverlayValue: (callback: (value: number | null) => void) => { + const listener = (_event: unknown, value: number | null) => callback(value); + ipcRenderer.on("countdown-overlay-value", listener); + return () => ipcRenderer.removeListener("countdown-overlay-value", listener); + }, onRequestSaveBeforeClose: (callback: () => Promise | boolean) => { const listener = async () => { try { diff --git a/electron/windows.ts b/electron/windows.ts index fb9a655..f94009a 100644 --- a/electron/windows.ts +++ b/electron/windows.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; +import { fileURLToPath, pathToFileURL } from "node:url"; import { BrowserWindow, ipcMain, screen } from "electron"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -9,6 +9,13 @@ const VITE_DEV_SERVER_URL = process.env["VITE_DEV_SERVER_URL"]; const RENDERER_DIST = path.join(APP_ROOT, "dist"); const HEADLESS = process.env["HEADLESS"] === "true"; +// Asset base URL for renderer (wallpapers, etc.). Packaged: extraResources copies +// public/wallpapers -> resources/wallpapers. Unpackaged: /public/. +const ASSET_BASE_DIR = process.defaultApp + ? path.join(__dirname, "..", "public") + : process.resourcesPath; +const ASSET_BASE_URL_ARG = `--asset-base-url=${pathToFileURL(`${ASSET_BASE_DIR}${path.sep}`).toString()}`; + let hudOverlayWindow: BrowserWindow | null = null; ipcMain.on("hud-overlay-hide", () => { @@ -17,6 +24,11 @@ ipcMain.on("hud-overlay-hide", () => { } }); +/** + * Creates the always-on-top HUD overlay window centred at the bottom of the + * primary display. The window is frameless, transparent, and follows the user + * across macOS Spaces so it is never lost when switching virtual desktops. + */ export function createHudOverlayWindow(): BrowserWindow { const primaryDisplay = screen.getPrimaryDisplay(); const { workArea } = primaryDisplay; @@ -45,12 +57,19 @@ export function createHudOverlayWindow(): BrowserWindow { show: !HEADLESS, webPreferences: { preload: path.join(__dirname, "preload.mjs"), + additionalArguments: [ASSET_BASE_URL_ARG], nodeIntegration: false, contextIsolation: true, backgroundThrottling: false, }, }); + // Follow the user across macOS Spaces (virtual desktops). + // Without this the HUD stays pinned to the Space it was first opened on. + if (process.platform === "darwin") { + win.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); + } + win.webContents.on("did-finish-load", () => { win?.webContents.send("main-process-message", new Date().toLocaleString()); }); @@ -74,6 +93,10 @@ export function createHudOverlayWindow(): BrowserWindow { return win; } +/** + * Creates the main editor window. Starts maximised with a hidden title bar on + * macOS. This window is not always-on-top and appears in the taskbar/dock. + */ export function createEditorWindow(): BrowserWindow { const isMac = process.platform === "darwin"; @@ -95,6 +118,7 @@ export function createEditorWindow(): BrowserWindow { show: !HEADLESS, webPreferences: { preload: path.join(__dirname, "preload.mjs"), + additionalArguments: [ASSET_BASE_URL_ARG], nodeIntegration: false, contextIsolation: true, webSecurity: false, @@ -120,6 +144,10 @@ export function createEditorWindow(): BrowserWindow { return win; } +/** + * Creates the floating source-selector window used to pick a screen or window + * to record. Frameless, transparent, and follows the user across macOS Spaces. + */ export function createSourceSelectorWindow(): BrowserWindow { const { width, height } = screen.getPrimaryDisplay().workAreaSize; @@ -137,11 +165,18 @@ export function createSourceSelectorWindow(): BrowserWindow { backgroundColor: "#00000000", webPreferences: { preload: path.join(__dirname, "preload.mjs"), + additionalArguments: [ASSET_BASE_URL_ARG], nodeIntegration: false, contextIsolation: true, }, }); + // Follow the user across macOS Spaces so the selector appears on the + // active desktop regardless of where the HUD was originally opened. + if (process.platform === "darwin") { + win.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); + } + if (VITE_DEV_SERVER_URL) { win.loadURL(VITE_DEV_SERVER_URL + "?windowType=source-selector"); } else { @@ -152,3 +187,56 @@ export function createSourceSelectorWindow(): BrowserWindow { return win; } + +/** + * Creates a centered transparent countdown overlay window that sits above the + * HUD while recording pre-roll is running. + */ +export function createCountdownOverlayWindow(): BrowserWindow { + const { workArea } = screen.getPrimaryDisplay(); + const overlayWidth = 420; + const overlayHeight = 260; + + const win = new BrowserWindow({ + width: overlayWidth, + height: overlayHeight, + minWidth: overlayWidth, + maxWidth: overlayWidth, + minHeight: overlayHeight, + maxHeight: overlayHeight, + x: Math.round(workArea.x + (workArea.width - overlayWidth) / 2), + y: Math.round(workArea.y + (workArea.height - overlayHeight) / 2), + frame: false, + resizable: false, + alwaysOnTop: true, + skipTaskbar: true, + focusable: false, + transparent: true, + backgroundColor: "#00000000", + hasShadow: false, + show: false, + webPreferences: { + preload: path.join(__dirname, "preload.mjs"), + additionalArguments: [ASSET_BASE_URL_ARG], + nodeIntegration: false, + contextIsolation: true, + backgroundThrottling: false, + }, + }); + + win.setIgnoreMouseEvents(true); + + if (process.platform === "darwin") { + win.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); + } + + if (VITE_DEV_SERVER_URL) { + win.loadURL(VITE_DEV_SERVER_URL + "?windowType=countdown-overlay"); + } else { + win.loadFile(path.join(RENDERER_DIST, "index.html"), { + query: { windowType: "countdown-overlay" }, + }); + } + + return win; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..77972fb --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1775710090, + "narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4c1018dae018162ec878d42fec712642d214fdfa", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..7b2d328 --- /dev/null +++ b/flake.nix @@ -0,0 +1,122 @@ +{ + description = "OpenScreen — desktop screen recorder with built-in editor"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = + { self, nixpkgs }: + let + systems = [ + "x86_64-linux" + "aarch64-linux" + ]; + forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system}); + in + { + # -- Per-system outputs (packages, dev shells) -- + + packages = forAllSystems (pkgs: { + openscreen = pkgs.callPackage ./nix/package.nix { }; + default = self.packages.${pkgs.stdenv.hostPlatform.system}.openscreen; + }); + + devShells = forAllSystems ( + pkgs: + let + electron = pkgs.electron; + + # Libraries Electron needs at runtime on Linux + runtimeLibs = with pkgs; [ + # X11 + libx11 + libxcomposite + libxdamage + libxext + libxfixes + libxrandr + libxtst + libxcb + libxshmfence + + # Wayland + wayland + + # GTK / UI toolkit + gtk3 + glib + pango + cairo + gdk-pixbuf + atk + at-spi2-atk + at-spi2-core + + # Graphics + mesa + libGL + libdrm + vulkan-loader + + # Networking / crypto (NSS for Chromium) + nss + nspr + + # Audio + alsa-lib + pipewire + pulseaudio + + # System + dbus + cups + expat + libnotify + libsecret + util-linux # libuuid + ]; + in + { + default = pkgs.mkShell { + packages = with pkgs; [ + nodejs_22 + electron + + # Native module compilation + python3 + pkg-config + gcc + + # Playwright browser tests + playwright-driver.browsers + ]; + + # Electron's prebuilt binary needs these at runtime + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath runtimeLibs; + + # Tell the npm `electron` package to use the Nix-provided binary + # instead of downloading its own. vite-plugin-electron respects this. + ELECTRON_OVERRIDE_DIST_PATH = "${electron}/libexec/electron"; + + # Playwright browser path for test:browser / test:e2e + PLAYWRIGHT_BROWSERS_PATH = "${pkgs.playwright-driver.browsers}"; + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = "1"; + + shellHook = '' + echo "OpenScreen dev shell — node $(node --version), electron v$(electron --version 2>/dev/null | tr -d 'v')" + ''; + }; + } + ); + + # -- System-wide outputs (modules, overlay) -- + + overlays.default = final: _prev: { + openscreen = self.packages.${final.stdenv.hostPlatform.system}.openscreen; + }; + + nixosModules.default = import ./nix/module.nix self; + homeManagerModules.default = import ./nix/hm-module.nix self; + }; +} diff --git a/icons/icons/mac/icon.icns b/icons/icons/mac/icon.icns index 7d5a493..02de106 100644 Binary files a/icons/icons/mac/icon.icns and b/icons/icons/mac/icon.icns differ diff --git a/macos.entitlements b/macos.entitlements new file mode 100644 index 0000000..5c6ddcf --- /dev/null +++ b/macos.entitlements @@ -0,0 +1,25 @@ + + + + + + com.apple.security.cs.allow-jit + + + + com.apple.security.cs.allow-unsigned-executable-memory + + + + com.apple.security.cs.disable-library-validation + + + + com.apple.security.device.audio-input + + + + com.apple.security.device.camera + + + diff --git a/nix/hm-module.nix b/nix/hm-module.nix new file mode 100644 index 0000000..b04f827 --- /dev/null +++ b/nix/hm-module.nix @@ -0,0 +1,36 @@ +# Home Manager module for OpenScreen +# Usage in flake-based Home Manager config: +# +# inputs.openscreen.url = "github:siddharthvaddem/openscreen"; +# +# { inputs, ... }: { +# imports = [ inputs.openscreen.homeManagerModules.default ]; +# programs.openscreen.enable = true; +# } +self: +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.programs.openscreen; +in +{ + options.programs.openscreen = { + enable = lib.mkEnableOption "OpenScreen screen recorder"; + + package = lib.mkOption { + type = lib.types.package; + default = self.packages.${pkgs.stdenv.hostPlatform.system}.openscreen; + defaultText = lib.literalExpression "inputs.openscreen.packages.\${pkgs.stdenv.hostPlatform.system}.openscreen"; + description = "The OpenScreen package to use."; + }; + }; + + config = lib.mkIf cfg.enable { + home.packages = [ cfg.package ]; + }; +} diff --git a/nix/module.nix b/nix/module.nix new file mode 100644 index 0000000..3282d2d --- /dev/null +++ b/nix/module.nix @@ -0,0 +1,42 @@ +# NixOS module for OpenScreen +# Usage in flake-based NixOS config: +# +# inputs.openscreen.url = "github:siddharthvaddem/openscreen"; +# +# { inputs, ... }: { +# imports = [ inputs.openscreen.nixosModules.default ]; +# programs.openscreen.enable = true; +# } +self: +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.programs.openscreen; +in +{ + options.programs.openscreen = { + enable = lib.mkEnableOption "OpenScreen screen recorder"; + + package = lib.mkOption { + type = lib.types.package; + default = self.packages.${pkgs.stdenv.hostPlatform.system}.openscreen; + defaultText = lib.literalExpression "inputs.openscreen.packages.\${pkgs.stdenv.hostPlatform.system}.openscreen"; + description = "The OpenScreen package to use."; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + # Screen capture on Wayland requires xdg-desktop-portal. + # We enable the base portal; users should also enable a + # desktop-specific portal (e.g. xdg-desktop-portal-gtk, + # xdg-desktop-portal-hyprland) in their DE config. + xdg.portal.enable = lib.mkDefault true; + }; +} diff --git a/nix/package.nix b/nix/package.nix new file mode 100644 index 0000000..13a8658 --- /dev/null +++ b/nix/package.nix @@ -0,0 +1,124 @@ +{ + lib, + buildNpmPackage, + nodejs_22, + electron, + makeWrapper, + makeDesktopItem, + copyDesktopItems, +}: + +buildNpmPackage { + nodejs = nodejs_22; + pname = "openscreen"; + version = "1.3.0"; + + src = + let + fs = lib.fileset; + # gitTracked fails when source is already a store path (path: flake inputs). + # Detect this and fall back to cleanSource which handles both cases. + isStorePath = builtins.storeDir == builtins.substring 0 (builtins.stringLength builtins.storeDir) (toString ../.); + baseFiles = if isStorePath then fs.fromSource (lib.cleanSource ../.) else fs.gitTracked ../.; + in + fs.toSource { + root = ../.; + fileset = fs.difference baseFiles ( + fs.unions [ + ../nix + ../flake.nix + ../flake.lock + (fs.fileFilter (file: file.hasExt "md") ../.) + ] + ); + }; + + npmDepsHash = "sha256-Pd6J9TuggA9vM4s/LjdoK4MoBEivSzAWc/G2+pFOM2U="; + + env.ELECTRON_SKIP_BINARY_DOWNLOAD = "1"; + + # electron-builder is not needed — we wrap system electron directly + npmFlags = [ "--ignore-scripts" ]; + makeCacheWritable = true; + + # vite-plugin-electron compiles electron/ sources into dist-electron/ + # tsconfig has noEmit — tsc is type-check only + buildPhase = '' + runHook preBuild + npx vite build + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + mkdir -p "$out/lib/openscreen" + + # Renderer build output (index.html, JS chunks, copied public/ assets) + cp -r dist "$out/lib/openscreen/" + + # Main process + preload (compiled by vite-plugin-electron) + cp -r dist-electron "$out/lib/openscreen/" + + # Package manifest (electron reads "main" field to find entry point) + cp package.json "$out/lib/openscreen/" + + # Strip devDependencies (electron, vitest, biome, playwright, etc.) + npm prune --omit=dev --no-save + cp -r node_modules "$out/lib/openscreen/" + + # Asset resolution: when app.isPackaged is false, the main process resolves + # assets at /public/. Place wallpapers at that root to match the + # packaged layout (electron-builder extraResources -> resources/wallpapers). + mkdir -p "$out/lib/openscreen/public" + cp -r public/wallpapers "$out/lib/openscreen/public/wallpapers" + + # Wrap system electron with the app directory + mkdir -p "$out/bin" + makeWrapper "${electron}/bin/electron" "$out/bin/openscreen" \ + --add-flags "$out/lib/openscreen" \ + --set ELECTRON_IS_DEV 0 + + # Install icons to hicolor theme + for size in 16 24 32 48 64 128 256 512 1024; do + icon="icons/icons/png/''${size}x''${size}.png" + if [ -f "$icon" ]; then + install -Dm644 "$icon" \ + "$out/share/icons/hicolor/''${size}x''${size}/apps/openscreen.png" + fi + done + + runHook postInstall + ''; + + nativeBuildInputs = [ + makeWrapper + copyDesktopItems + ]; + + desktopItems = [ + (makeDesktopItem { + name = "openscreen"; + desktopName = "OpenScreen"; + genericName = "Screen Recorder"; + exec = "openscreen %U"; + icon = "openscreen"; + comment = "Desktop screen recorder with built-in editor"; + categories = [ + "AudioVideo" + "Video" + "Recorder" + ]; + startupWMClass = "Openscreen"; + terminal = false; + }) + ]; + + meta = { + description = "Desktop screen recorder with built-in editor"; + homepage = "https://github.com/siddharthvaddem/openscreen"; + license = lib.licenses.mit; + mainProgram = "openscreen"; + platforms = lib.platforms.linux; + }; +} diff --git a/package-lock.json b/package-lock.json index 70e3395..e823ad1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openscreen", - "version": "1.2.0", + "version": "1.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "openscreen", - "version": "1.2.0", + "version": "1.3.0", "dependencies": { "@fix-webm-duration/fix": "^1.0.1", "@pixi/filter-drop-shadow": "^5.2.0", @@ -16,67 +16,70 @@ "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slider": "^1.3.6", - "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-toggle": "^1.1.10", "@radix-ui/react-toggle-group": "^1.1.11", "@radix-ui/react-tooltip": "^1.2.8", "@types/gif.js": "^0.2.5", - "@uiw/color-convert": "^2.9.2", - "@uiw/react-color-block": "^2.9.2", + "@uiw/color-convert": "^2.10.1", + "@uiw/react-color-block": "^2.10.1", + "@uiw/react-color-colorful": "^2.9.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "dnd-timeline": "^2.2.0", - "emoji-picker-react": "^4.16.1", + "dnd-timeline": "^2.4.0", + "emoji-picker-react": "^4.18.0", "fix-webm-duration": "^1.0.6", "gif.js": "^0.2.0", - "gsap": "^3.13.0", + "gsap": "^3.15.0", "lucide-react": "^0.545.0", - "mediabunny": "^1.25.1", - "motion": "^12.23.24", - "mp4box": "^2.2.0", + "mediabunny": "^1.40.1", + "motion": "^12.38.0", + "mp4box": "^2.3.0", "pixi-filters": "^6.1.5", - "pixi.js": "^8.14.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-icons": "^5.5.0", + "pixi.js": "^8.18.1", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-icons": "^5.6.0", "react-resizable-panels": "^3.0.6", - "react-rnd": "^10.5.2", + "react-rnd": "^10.5.3", "sonner": "^2.0.7", - "tailwind-merge": "^3.3.1", + "tailwind-merge": "^3.5.0", "tailwindcss-animate": "^1.0.7", + "uiohook-napi": "^1.5.5", "uuid": "^13.0.0", "web-demuxer": "^4.0.0" }, "devDependencies": { - "@biomejs/biome": "^2.3.13", - "@playwright/test": "^1.58.2", + "@biomejs/biome": "^2.4.12", + "@electron/rebuild": "^4.0.4", + "@playwright/test": "^1.59.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", - "@types/node": "^25.0.3", - "@types/react": "^18.2.64", - "@types/react-dom": "^18.2.21", - "@types/uuid": "^10.0.0", - "@vitejs/plugin-react": "^4.2.1", - "autoprefixer": "^10.4.21", - "electron": "^39.2.7", - "electron-builder": "^26.7.0", - "electron-icon-builder": "^2.0.1", - "electron-rebuild": "^3.2.9", - "fast-check": "^4.5.2", + "@types/node": "^22.19.17", + "@types/react": "^18.3.28", + "@types/react-dom": "^18.3.7", + "@vitejs/plugin-react": "^5.2.0", + "@vitest/browser": "^4.1.4", + "@vitest/browser-playwright": "^4.1.4", + "autoprefixer": "^10.5.0", + "electron": "^41.2.1", + "electron-builder": "^26.8.1", + "esbuild": "^0.27.0", + "fast-check": "^4.7.0", "husky": "^9.1.7", - "jsdom": "^29.0.1", - "lint-staged": "^16.3.2", - "postcss": "^8.5.6", - "tailwindcss": "^3.4.18", - "terser": "^5.44.1", - "typescript": "^5.2.2", - "vite": "^5.1.6", - "vite-plugin-electron": "^0.28.6", - "vite-plugin-electron-renderer": "^0.14.5", - "vitest": "^4.0.16" + "jsdom": "^29.0.2", + "lint-staged": "^16.4.0", + "postcss": "^8.5.10", + "tailwindcss": "^3.4.19", + "terser": "^5.46.1", + "typescript": "^5.9.3", + "vite": "^7.3.2", + "vite-plugin-electron": "^0.29.1", + "vite-plugin-electron-renderer": "^0.14.6", + "vitest": "^4.1.4" }, "engines": { "node": "22.22.1", @@ -103,57 +106,47 @@ } }, "node_modules/@asamuzakjp/css-color": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.0.1.tgz", - "integrity": "sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw==", + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz", + "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-calc": "^3.1.1", - "@csstools/css-color-parser": "^4.0.2", + "@asamuzakjp/generational-cache": "^1.0.1", + "@csstools/css-calc": "^3.2.0", + "@csstools/css-color-parser": "^4.1.0", "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-tokenizer": "^4.0.0", - "lru-cache": "^11.2.6" + "@csstools/css-tokenizer": "^4.0.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, - "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@asamuzakjp/dom-selector": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.0.4.tgz", - "integrity": "sha512-jXR6x4AcT3eIrS2fSNAwJpwirOkGcd+E7F7CP3zjdTqz9B/2huHOL8YJZBgekKwLML+u7qB/6P1LXQuMScsx0w==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz", + "integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==", "dev": true, "license": "MIT", "dependencies": { + "@asamuzakjp/generational-cache": "^1.0.1", "@asamuzakjp/nwsapi": "^2.3.9", "bidi-js": "^1.0.3", "css-tree": "^3.2.1", - "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.2.7" + "is-potential-custom-element-name": "^1.0.1" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, - "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "node_modules/@asamuzakjp/generational-cache": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz", + "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "engines": { - "node": "20 || >=22" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, "node_modules/@asamuzakjp/nwsapi": { @@ -164,13 +157,13 @@ "license": "MIT" }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -179,9 +172,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", - "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", "engines": { @@ -189,21 +182,21 @@ } }, "node_modules/@babel/core": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", - "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.4", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.4", - "@babel/types": "^7.28.4", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -219,25 +212,15 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/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/@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -247,13 +230,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", + "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -263,16 +246,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets/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/@babel/helper-globals": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", @@ -284,29 +257,29 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -316,9 +289,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, "license": "MIT", "engines": { @@ -336,9 +309,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -356,27 +329,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.4" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -418,42 +391,42 @@ } }, "node_modules/@babel/runtime": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", - "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.4", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { @@ -461,23 +434,23 @@ } }, "node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@biomejs/biome": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.13.tgz", - "integrity": "sha512-Fw7UsV0UAtWIBIm0M7g5CRerpu1eKyKAXIazzxhbXYUyMkwNrkX/KLkGI7b+uVDQ5cLUMfOC9vR60q9IDYDstA==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.12.tgz", + "integrity": "sha512-Rro7adQl3NLq/zJCIL98eElXKI8eEiBtoeu5TbXF/U3qbjuSc7Jb5rjUbeHHcquDWeSf3HnGP7XI5qGrlRk/pA==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -491,20 +464,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "2.3.13", - "@biomejs/cli-darwin-x64": "2.3.13", - "@biomejs/cli-linux-arm64": "2.3.13", - "@biomejs/cli-linux-arm64-musl": "2.3.13", - "@biomejs/cli-linux-x64": "2.3.13", - "@biomejs/cli-linux-x64-musl": "2.3.13", - "@biomejs/cli-win32-arm64": "2.3.13", - "@biomejs/cli-win32-x64": "2.3.13" + "@biomejs/cli-darwin-arm64": "2.4.12", + "@biomejs/cli-darwin-x64": "2.4.12", + "@biomejs/cli-linux-arm64": "2.4.12", + "@biomejs/cli-linux-arm64-musl": "2.4.12", + "@biomejs/cli-linux-x64": "2.4.12", + "@biomejs/cli-linux-x64-musl": "2.4.12", + "@biomejs/cli-win32-arm64": "2.4.12", + "@biomejs/cli-win32-x64": "2.4.12" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.13.tgz", - "integrity": "sha512-0OCwP0/BoKzyJHnFdaTk/i7hIP9JHH9oJJq6hrSCPmJPo8JWcJhprK4gQlhFzrwdTBAW4Bjt/RmCf3ZZe59gwQ==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.12.tgz", + "integrity": "sha512-BnMU4Pc3ciEVteVpZ0BK33MLr7X57F5w1dwDLDn+/iy/yTrA4Q/N2yftidFtsA4vrDh0FMXDpacNV/Tl3fbmng==", "cpu": [ "arm64" ], @@ -519,9 +492,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.13.tgz", - "integrity": "sha512-AGr8OoemT/ejynbIu56qeil2+F2WLkIjn2d8jGK1JkchxnMUhYOfnqc9sVzcRxpG9Ycvw4weQ5sprRvtb7Yhcw==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.12.tgz", + "integrity": "sha512-x9uJ0bI1rJsWICp3VH8w/5PnAVD3A7SqzDpbrfoUQX1QyWrK5jSU4fRLo/wSgGeplCivbxBRKmt5Xq4/nWvq8A==", "cpu": [ "x64" ], @@ -536,9 +509,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.13.tgz", - "integrity": "sha512-xvOiFkrDNu607MPMBUQ6huHmBG1PZLOrqhtK6pXJW3GjfVqJg0Z/qpTdhXfcqWdSZHcT+Nct2fOgewZvytESkw==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.12.tgz", + "integrity": "sha512-tOwuCuZZtKi1jVzbk/5nXmIsziOB6yqN8c9r9QM0EJYPU6DpQWf11uBOSCfFKKM4H3d9ZoarvlgMfbcuD051Pw==", "cpu": [ "arm64" ], @@ -553,9 +526,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.13.tgz", - "integrity": "sha512-TUdDCSY+Eo/EHjhJz7P2GnWwfqet+lFxBZzGHldrvULr59AgahamLs/N85SC4+bdF86EhqDuuw9rYLvLFWWlXA==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.12.tgz", + "integrity": "sha512-FhfpkAAlKL6kwvcVap0Hgp4AhZmtd3YImg0kK1jd7C/aSoh4SfsB2f++yG1rU0lr8Y5MCFJrcSkmssiL9Xnnig==", "cpu": [ "arm64" ], @@ -570,9 +543,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.13.tgz", - "integrity": "sha512-s+YsZlgiXNq8XkgHs6xdvKDFOj/bwTEevqEY6rC2I3cBHbxXYU1LOZstH3Ffw9hE5tE1sqT7U23C00MzkXztMw==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.12.tgz", + "integrity": "sha512-8pFeAnLU9QdW9jCIslB/v82bI0lhBmz2ZAKc8pVMFPO0t0wAHsoEkrUQUbMkIorTRIjbqyNZHA3lEXavsPWYSw==", "cpu": [ "x64" ], @@ -587,9 +560,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.13.tgz", - "integrity": "sha512-0bdwFVSbbM//Sds6OjtnmQGp4eUjOTt6kHvR/1P0ieR9GcTUAlPNvPC3DiavTqq302W34Ae2T6u5VVNGuQtGlQ==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.12.tgz", + "integrity": "sha512-dwTIgZrGutzhkQCuvHynCkyW6hJxUuyZqKKO0YNfaS2GUoRO+tOvxXZqZB6SkWAOdfZTzwaw8IEdUnIkHKHoew==", "cpu": [ "x64" ], @@ -604,9 +577,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.13.tgz", - "integrity": "sha512-QweDxY89fq0VvrxME+wS/BXKmqMrOTZlN9SqQ79kQSIc3FrEwvW/PvUegQF6XIVaekncDykB5dzPqjbwSKs9DA==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.12.tgz", + "integrity": "sha512-B0DLnx0vA9ya/3v7XyCaP+/lCpnbWbMOfUFFve+xb5OxyYvdHaS55YsSddr228Y+JAFk58agCuZTsqNiw2a6ig==", "cpu": [ "arm64" ], @@ -621,9 +594,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.13.tgz", - "integrity": "sha512-trDw2ogdM2lyav9WFQsdsfdVy1dvZALymRpgmWsvSez0BJzBjulhOT/t+wyKeh3pZWvwP3VMs1SoOKwO3wecMQ==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.12.tgz", + "integrity": "sha512-yMckRzTyZ83hkk8iDFWswqSdU8tvZxspJKnYNh7JZr/zhZNOlzH13k4ecboU6MurKExCe2HUkH75pGI/O2JwGA==", "cpu": [ "x64" ], @@ -637,6 +610,13 @@ "node": ">=14.21.3" } }, + "node_modules/@blazediff/core": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@blazediff/core/-/core-1.9.1.tgz", + "integrity": "sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA==", + "dev": true, + "license": "MIT" + }, "node_modules/@bramus/specificity": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", @@ -671,9 +651,9 @@ } }, "node_modules/@csstools/css-calc": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", - "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.0.tgz", + "integrity": "sha512-bR9e6o2BDB12jzN/gIbjHa5wLJ4UjD1CB9pM7ehlc0ddk6EBz+yYS1EV2MF55/HUxrHcB/hehAyt5vhsA3hx7w==", "dev": true, "funding": [ { @@ -695,9 +675,9 @@ } }, "node_modules/@csstools/css-color-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz", - "integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.0.tgz", + "integrity": "sha512-U0KhLYmy2GVj6q4T3WaAe6NPuFYCPQoE3b0dRGxejWDgcPp8TP7S5rVdM5ZrFaqu4N67X8YaPBw14dQSYx3IyQ==", "dev": true, "funding": [ { @@ -712,7 +692,7 @@ "license": "MIT", "dependencies": { "@csstools/color-helpers": "^6.0.2", - "@csstools/css-calc": "^3.1.1" + "@csstools/css-calc": "^3.2.0" }, "engines": { "node": ">=20.19.0" @@ -746,9 +726,9 @@ } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.1.tgz", - "integrity": "sha512-BvqN0AMWNAnLk9G8jnUT77D+mUbY/H2b3uDTvg2isJkHaOufUE2R3AOwxWo7VBQKT1lOdwdvorddo2B/lk64+w==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.3.tgz", + "integrity": "sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==", "dev": true, "funding": [ { @@ -865,10 +845,17 @@ "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.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -877,9 +864,9 @@ } }, "node_modules/@electron/asar/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "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": { @@ -921,9 +908,9 @@ } }, "node_modules/@electron/fuses/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -965,16 +952,6 @@ "global-agent": "^3.0.0" } }, - "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/@electron/notarize": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz", @@ -1007,9 +984,9 @@ } }, "node_modules/@electron/notarize/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -1080,9 +1057,9 @@ } }, "node_modules/@electron/osx-sign/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -1103,25 +1080,18 @@ } }, "node_modules/@electron/rebuild": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-4.0.3.tgz", - "integrity": "sha512-u9vpTHRMkOYCs/1FLiSVAFZ7FbjsXK+bQuzviJZa+lG7BHZl1nz52/IcGvwa3sk80/fc3llutBkbCq10Vh8WQA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-4.0.4.tgz", + "integrity": "sha512-Rzc39XPdk/+/wBG8MfwAHohXflep0ITUfulb6Rgz3R0NeSB1noE+E9/M/cb8ftCAiyDD9PPhLuuWgE1GaInbKg==", "dev": true, "license": "MIT", "dependencies": { "@malept/cross-spawn-promise": "^2.0.0", "debug": "^4.1.1", - "detect-libc": "^2.0.1", - "got": "^11.7.0", - "graceful-fs": "^4.2.11", "node-abi": "^4.2.0", "node-api-version": "^0.2.1", - "node-gyp": "^11.2.0", - "ora": "^5.1.0", - "read-binary-file-arch": "^1.0.6", - "semver": "^7.3.5", - "tar": "^7.5.6", - "yargs": "^17.0.1" + "node-gyp": "^12.2.0", + "read-binary-file-arch": "^1.0.6" }, "bin": { "electron-rebuild": "lib/cli.js" @@ -1130,361 +1100,6 @@ "node": ">=22.12.0" } }, - "node_modules/@electron/rebuild/node_modules/@npmcli/fs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", - "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@electron/rebuild/node_modules/abbrev": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", - "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@electron/rebuild/node_modules/cacache": { - "version": "19.0.1", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", - "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^4.0.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^7.0.2", - "ssri": "^12.0.0", - "tar": "^7.4.3", - "unique-filename": "^4.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@electron/rebuild/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/@electron/rebuild/node_modules/fs-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "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": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@electron/rebuild/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/@electron/rebuild/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@electron/rebuild/node_modules/make-fetch-happen": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", - "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^3.0.0", - "cacache": "^19.0.1", - "http-cache-semantics": "^4.1.1", - "minipass": "^7.0.2", - "minipass-fetch": "^4.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^1.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "ssri": "^12.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@electron/rebuild/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/@electron/rebuild/node_modules/minipass-collect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", - "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/@electron/rebuild/node_modules/minipass-fetch": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.1.tgz", - "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^3.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/@electron/rebuild/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/@electron/rebuild/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@electron/rebuild/node_modules/node-abi": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-4.26.0.tgz", - "integrity": "sha512-8QwIZqikRvDIkXS2S93LjzhsSPJuIbfaMETWH+Bx8oOT9Sa9UsUtBFQlc3gBNd1+QINjaTloitXr1W3dQLi9Iw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.6.3" - }, - "engines": { - "node": ">=22.12.0" - } - }, - "node_modules/@electron/rebuild/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/@electron/rebuild/node_modules/node-gyp": { - "version": "11.5.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.5.0.tgz", - "integrity": "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^14.0.3", - "nopt": "^8.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.5", - "tar": "^7.4.3", - "tinyglobby": "^0.2.12", - "which": "^5.0.0" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@electron/rebuild/node_modules/nopt": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", - "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", - "dev": true, - "license": "ISC", - "dependencies": { - "abbrev": "^3.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@electron/rebuild/node_modules/p-map": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", - "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@electron/rebuild/node_modules/ssri": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", - "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@electron/rebuild/node_modules/tar": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz", - "integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==", - "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/@electron/rebuild/node_modules/unique-filename": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", - "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^5.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@electron/rebuild/node_modules/unique-slug": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", - "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@electron/rebuild/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/@electron/rebuild/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/@electron/universal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.3.tgz", @@ -1504,10 +1119,27 @@ "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.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/@electron/universal/node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "dev": true, "license": "MIT", "dependencies": { @@ -1520,9 +1152,9 @@ } }, "node_modules/@electron/universal/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -1532,6 +1164,22 @@ "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", @@ -1565,9 +1213,9 @@ } }, "node_modules/@electron/windows-sign/node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "dev": true, "license": "MIT", "optional": true, @@ -1582,9 +1230,9 @@ } }, "node_modules/@electron/windows-sign/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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, @@ -1609,9 +1257,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", "cpu": [ "ppc64" ], @@ -1622,13 +1270,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", "cpu": [ "arm" ], @@ -1639,13 +1287,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", "cpu": [ "arm64" ], @@ -1656,13 +1304,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", "cpu": [ "x64" ], @@ -1673,13 +1321,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", "cpu": [ "arm64" ], @@ -1690,13 +1338,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", "cpu": [ "x64" ], @@ -1707,13 +1355,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", "cpu": [ "arm64" ], @@ -1724,13 +1372,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", "cpu": [ "x64" ], @@ -1741,13 +1389,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", "cpu": [ "arm" ], @@ -1758,13 +1406,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", "cpu": [ "arm64" ], @@ -1775,13 +1423,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", "cpu": [ "ia32" ], @@ -1792,13 +1440,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", "cpu": [ "loong64" ], @@ -1809,13 +1457,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", "cpu": [ "mips64el" ], @@ -1826,13 +1474,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", "cpu": [ "ppc64" ], @@ -1843,13 +1491,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", "cpu": [ "riscv64" ], @@ -1860,13 +1508,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", "cpu": [ "s390x" ], @@ -1877,13 +1525,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", "cpu": [ "x64" ], @@ -1894,13 +1542,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", - "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", "cpu": [ "arm64" ], @@ -1915,9 +1563,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", "cpu": [ "x64" ], @@ -1928,13 +1576,13 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", - "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", "cpu": [ "arm64" ], @@ -1949,9 +1597,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", "cpu": [ "x64" ], @@ -1962,13 +1610,13 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", - "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", "cpu": [ "arm64" ], @@ -1983,9 +1631,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", "cpu": [ "x64" ], @@ -1996,13 +1644,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", "cpu": [ "arm64" ], @@ -2013,13 +1661,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", "cpu": [ "ia32" ], @@ -2030,13 +1678,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", "cpu": [ "x64" ], @@ -2047,7 +1695,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@exodus/bytes": { @@ -2088,31 +1736,31 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", - "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.10" + "@floating-ui/utils": "^0.2.11" } }, "node_modules/@floating-ui/dom": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", - "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.7.3", - "@floating-ui/utils": "^0.2.10" + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", - "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", + "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.7.4" + "@floating-ui/dom": "^1.7.6" }, "peerDependencies": { "react": ">=16.8.0", @@ -2120,114 +1768,11 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", - "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", "license": "MIT" }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", @@ -2241,522 +1786,6 @@ "node": ">=18.0.0" } }, - "node_modules/@isaacs/fs-minipass/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/@jimp/bmp": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.16.13.tgz", - "integrity": "sha512-9edAxu7N2FX7vzkdl5Jo1BbACfycUtBQX+XBMcHA2bk62P8R0otgkHg798frgAk/WxQIzwxqOH6wMiCwrlAzdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13", - "bmp-js": "^0.1.0" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/core": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.16.13.tgz", - "integrity": "sha512-qXpA1tzTnlkTku9yqtuRtS/wVntvE6f3m3GNxdTdtmc+O+Wcg9Xo2ABPMh7Nc0AHbMKzwvwgB2JnjZmlmJEObg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13", - "any-base": "^1.1.0", - "buffer": "^5.2.0", - "exif-parser": "^0.1.12", - "file-type": "^16.5.4", - "load-bmfont": "^1.3.1", - "mkdirp": "^0.5.1", - "phin": "^2.9.1", - "pixelmatch": "^4.0.2", - "tinycolor2": "^1.4.1" - } - }, - "node_modules/@jimp/core/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", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/@jimp/custom": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.16.13.tgz", - "integrity": "sha512-LTATglVUPGkPf15zX1wTMlZ0+AU7cGEGF6ekVF1crA8eHUWsGjrYTB+Ht4E3HTrCok8weQG+K01rJndCp/l4XA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/core": "^0.16.13" - } - }, - "node_modules/@jimp/gif": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.16.13.tgz", - "integrity": "sha512-yFAMZGv3o+YcjXilMWWwS/bv1iSqykFahFMSO169uVMtfQVfa90kt4/kDwrXNR6Q9i6VHpFiGZMlF2UnHClBvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13", - "gifwrap": "^0.9.2", - "omggif": "^1.0.9" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/jpeg": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.16.13.tgz", - "integrity": "sha512-BJHlDxzTlCqP2ThqP8J0eDrbBfod7npWCbJAcfkKqdQuFk0zBPaZ6KKaQKyKxmWJ87Z6ohANZoMKEbtvrwz1AA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13", - "jpeg-js": "^0.4.2" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-blit": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.16.13.tgz", - "integrity": "sha512-8Z1k96ZFxlhK2bgrY1JNWNwvaBeI/bciLM0yDOni2+aZwfIIiC7Y6PeWHTAvjHNjphz+XCt01WQmOYWCn0ML6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-blur": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.16.13.tgz", - "integrity": "sha512-PvLrfa8vkej3qinlebyhLpksJgCF5aiysDMSVhOZqwH5nQLLtDE9WYbnsofGw4r0VVpyw3H/ANCIzYTyCtP9Cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-circle": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.16.13.tgz", - "integrity": "sha512-RNave7EFgZrb5V5EpdvJGAEHMnDAJuwv05hKscNfIYxf0kR3KhViBTDy+MoTnMlIvaKFULfwIgaZWzyhuINMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-color": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.16.13.tgz", - "integrity": "sha512-xW+9BtEvoIkkH/Wde9ql4nAFbYLkVINhpgAE7VcBUsuuB34WUbcBl/taOuUYQrPEFQJ4jfXiAJZ2H/rvKjCVnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13", - "tinycolor2": "^1.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-contain": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.16.13.tgz", - "integrity": "sha512-QayTXw4tXMwU6q6acNTQrTTFTXpNRBe+MgTGMDU0lk+23PjlFCO/9sacflelG8lsp7vNHhAxFeHptDMAksEYzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5", - "@jimp/plugin-scale": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-cover": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.16.13.tgz", - "integrity": "sha512-BSsP71GTNaqWRcvkbWuIVH+zK7b3TSNebbhDkFK0fVaUTzHuKMS/mgY4hDZIEVt7Rf5FjadAYtsujHN9w0iSYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-crop": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5", - "@jimp/plugin-scale": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-crop": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.16.13.tgz", - "integrity": "sha512-WEl2tPVYwzYL8OKme6Go2xqiWgKsgxlMwyHabdAU4tXaRwOCnOI7v4021gCcBb9zn/oWwguHuKHmK30Fw2Z/PA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-displace": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.16.13.tgz", - "integrity": "sha512-qt9WKq8vWrcjySa9DyQ0x/RBMHQeiVjdVSY1SJsMjssPUf0pS74qorcuAkGi89biN3YoGUgPkpqECnAWnYwgGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-dither": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.16.13.tgz", - "integrity": "sha512-5/N3yJggbWQTlGZHQYJPmQXEwR52qaXjEzkp1yRBbtdaekXE3BG/suo0fqeoV/csf8ooI78sJzYmIrxNoWVtgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-fisheye": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.16.13.tgz", - "integrity": "sha512-2rZmTdFbT/cF9lEZIkXCYO0TsT114Q27AX5IAo0Sju6jVQbvIk1dFUTnwLDadTo8wkJlFzGqMQ24Cs8cHWOliA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-flip": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.16.13.tgz", - "integrity": "sha512-EmcgAA74FTc5u7Z+hUO/sRjWwfPPLuOQP5O64x5g4j0T12Bd29IgsYZxoutZo/rb3579+JNa/3wsSEmyVv1EpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-rotate": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-gaussian": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.16.13.tgz", - "integrity": "sha512-A1XKfGQD0iDdIiKqFYi8nZMv4dDVYdxbrmgR7y/CzUHhSYdcmoljLIIsZZM3Iks/Wa353W3vtvkWLuDbQbch1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-invert": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.16.13.tgz", - "integrity": "sha512-xFMrIn7czEZbdbMzZWuaZFnlLGJDVJ82y5vlsKsXRTG2kcxRsMPXvZRWHV57nSs1YFsNqXSbrC8B98n0E32njQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-mask": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.16.13.tgz", - "integrity": "sha512-wLRYKVBXql2GAYgt6FkTnCfE+q5NomM7Dlh0oIPGAoMBWDyTx0eYutRK6PlUrRK2yMHuroAJCglICTbxqGzowQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-normalize": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.16.13.tgz", - "integrity": "sha512-3tfad0n9soRna4IfW9NzQdQ2Z3ijkmo21DREHbE6CGcMIxOSvfRdSvf1qQPApxjTSo8LTU4MCi/fidx/NZ0GqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-print": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.16.13.tgz", - "integrity": "sha512-0m6i3p01PGRkGAK9r53hDYrkyMq+tlhLOIbsSTmZyh6HLshUKlTB7eXskF5OpVd5ZUHoltlNc6R+ggvKIzxRFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13", - "load-bmfont": "^1.4.0" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-resize": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.16.13.tgz", - "integrity": "sha512-qoqtN8LDknm3fJm9nuPygJv30O3vGhSBD2TxrsCnhtOsxKAqVPJtFVdGd/qVuZ8nqQANQmTlfqTiK9mVWQ7MiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-rotate": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.16.13.tgz", - "integrity": "sha512-Ev+Jjmj1nHYw897z9C3R9dYsPv7S2/nxdgfFb/h8hOwK0Ovd1k/+yYS46A0uj/JCKK0pQk8wOslYBkPwdnLorw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5", - "@jimp/plugin-crop": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-scale": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.16.13.tgz", - "integrity": "sha512-05POQaEJVucjTiSGMoH68ZiELc7QqpIpuQlZ2JBbhCV+WCbPFUBcGSmE7w4Jd0E2GvCho/NoMODLwgcVGQA97A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-shadow": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.16.13.tgz", - "integrity": "sha512-nmu5VSZ9hsB1JchTKhnnCY+paRBnwzSyK5fhkhtQHHoFD5ArBQ/5wU8y6tCr7k/GQhhGq1OrixsECeMjPoc8Zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blur": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-threshold": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.16.13.tgz", - "integrity": "sha512-+3zArBH0OE3Rhjm4HyAokMsZlIq5gpQec33CncyoSwxtRBM2WAhUVmCUKuBo+Lr/2/4ISoY4BWpHKhMLDix6cA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-color": ">=0.8.0", - "@jimp/plugin-resize": ">=0.8.0" - } - }, - "node_modules/@jimp/plugins": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.16.13.tgz", - "integrity": "sha512-CJLdqODEhEVs4MgWCxpWL5l95sCBlkuSLz65cxEm56X5akIsn4LOlwnKoSEZioYcZUBvHhCheH67AyPTudfnQQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/plugin-blit": "^0.16.13", - "@jimp/plugin-blur": "^0.16.13", - "@jimp/plugin-circle": "^0.16.13", - "@jimp/plugin-color": "^0.16.13", - "@jimp/plugin-contain": "^0.16.13", - "@jimp/plugin-cover": "^0.16.13", - "@jimp/plugin-crop": "^0.16.13", - "@jimp/plugin-displace": "^0.16.13", - "@jimp/plugin-dither": "^0.16.13", - "@jimp/plugin-fisheye": "^0.16.13", - "@jimp/plugin-flip": "^0.16.13", - "@jimp/plugin-gaussian": "^0.16.13", - "@jimp/plugin-invert": "^0.16.13", - "@jimp/plugin-mask": "^0.16.13", - "@jimp/plugin-normalize": "^0.16.13", - "@jimp/plugin-print": "^0.16.13", - "@jimp/plugin-resize": "^0.16.13", - "@jimp/plugin-rotate": "^0.16.13", - "@jimp/plugin-scale": "^0.16.13", - "@jimp/plugin-shadow": "^0.16.13", - "@jimp/plugin-threshold": "^0.16.13", - "timm": "^1.6.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/png": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.16.13.tgz", - "integrity": "sha512-8cGqINvbWJf1G0Her9zbq9I80roEX0A+U45xFby3tDWfzn+Zz8XKDF1Nv9VUwVx0N3zpcG1RPs9hfheG4Cq2kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.16.13", - "pngjs": "^3.3.3" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/png/node_modules/pngjs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/@jimp/tiff": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.16.13.tgz", - "integrity": "sha512-oJY8d9u95SwW00VPHuCNxPap6Q1+E/xM5QThb9Hu+P6EGuu6lIeLaNBMmFZyblwFbwrH+WBOZlvIzDhi4Dm/6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "utif": "^2.0.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/types": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.16.13.tgz", - "integrity": "sha512-mC0yVNUobFDjoYLg4hoUwzMKgNlxynzwt3cDXzumGvRJ7Kb8qQGOWJQjQFo5OxmGExqzPphkirdbBF88RVLBCg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/bmp": "^0.16.13", - "@jimp/gif": "^0.16.13", - "@jimp/jpeg": "^0.16.13", - "@jimp/png": "^0.16.13", - "@jimp/tiff": "^0.16.13", - "timm": "^1.6.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/utils": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.16.13.tgz", - "integrity": "sha512-VyCpkZzFTHXtKgVO35iKN0sYR10psGpV6SkcSeV4oF7eSYlR8Bl6aQLCzVeFjvESF7mxTmIiI3/XrMobVrtxDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "regenerator-runtime": "^0.13.3" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -2870,9 +1899,9 @@ } }, "node_modules/@malept/flatpak-bundler/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -2927,112 +1956,6 @@ "node": ">= 8" } }, - "node_modules/@npmcli/agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", - "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@npmcli/agent/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/@npmcli/agent/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/@npmcli/agent/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/@npmcli/agent/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@npmcli/agent/node_modules/socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@npmcli/fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", - "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@npmcli/move-file": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", - "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "deprecated": "This functionality has been moved to @npmcli/fs", - "dev": true, - "license": "MIT", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/@pixi/color": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@pixi/color/-/color-7.4.3.tgz", @@ -3159,44 +2082,14 @@ "url": "^0.11.0" } }, - "node_modules/@pixi/utils/node_modules/@types/earcut": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.4.tgz", - "integrity": "sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ==", - "license": "MIT", - "peer": true - }, - "node_modules/@pixi/utils/node_modules/earcut": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", - "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==", - "license": "ISC", - "peer": true - }, - "node_modules/@pixi/utils/node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "license": "MIT", - "peer": true - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@playwright/test": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.2.tgz", - "integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==", + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz", + "integrity": "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "playwright": "1.58.2" + "playwright": "1.59.1" }, "bin": { "playwright": "cli.js" @@ -3205,6 +2098,13 @@ "node": ">=18" } }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, "node_modules/@radix-ui/number": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", @@ -3327,6 +2227,24 @@ } } }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", @@ -3393,6 +2311,24 @@ } } }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-direction": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", @@ -3562,6 +2498,24 @@ } } }, + "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popover": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", @@ -3599,6 +2553,24 @@ } } }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", @@ -3702,6 +2674,24 @@ } } }, + "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-roving-focus": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", @@ -3776,6 +2766,24 @@ } } }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-slider": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", @@ -3810,9 +2818,9 @@ } }, "node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -3974,6 +2982,24 @@ } } }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", @@ -4140,16 +3166,16 @@ "license": "MIT" }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.27", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", - "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", "dev": true, "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", - "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz", + "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==", "cpu": [ "arm" ], @@ -4161,9 +3187,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz", - "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz", + "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==", "cpu": [ "arm64" ], @@ -4175,9 +3201,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz", - "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz", + "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==", "cpu": [ "arm64" ], @@ -4189,9 +3215,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz", - "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz", + "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==", "cpu": [ "x64" ], @@ -4203,9 +3229,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz", - "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz", + "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==", "cpu": [ "arm64" ], @@ -4217,9 +3243,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz", - "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz", + "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==", "cpu": [ "x64" ], @@ -4231,9 +3257,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz", - "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz", + "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==", "cpu": [ "arm" ], @@ -4245,9 +3271,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz", - "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz", + "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==", "cpu": [ "arm" ], @@ -4259,9 +3285,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz", - "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz", + "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==", "cpu": [ "arm64" ], @@ -4273,9 +3299,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz", - "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", + "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", "cpu": [ "arm64" ], @@ -4287,9 +3313,23 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz", - "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", + "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", + "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", "cpu": [ "loong64" ], @@ -4301,9 +3341,23 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz", - "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", + "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", + "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", "cpu": [ "ppc64" ], @@ -4315,9 +3369,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz", - "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", + "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", "cpu": [ "riscv64" ], @@ -4329,9 +3383,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz", - "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", + "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", "cpu": [ "riscv64" ], @@ -4343,9 +3397,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz", - "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", + "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", "cpu": [ "s390x" ], @@ -4357,9 +3411,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz", - "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", + "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", "cpu": [ "x64" ], @@ -4371,9 +3425,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz", - "integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", + "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", "cpu": [ "x64" ], @@ -4384,10 +3438,24 @@ "linux" ] }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", + "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz", - "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", + "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", "cpu": [ "arm64" ], @@ -4399,9 +3467,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz", - "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", + "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", "cpu": [ "arm64" ], @@ -4413,9 +3481,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz", - "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", + "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", "cpu": [ "ia32" ], @@ -4427,9 +3495,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz", - "integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", + "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", "cpu": [ "x64" ], @@ -4441,9 +3509,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz", - "integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", + "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", "cpu": [ "x64" ], @@ -4577,23 +3645,6 @@ "@testing-library/dom": ">=7.21.4" } }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, "node_modules/@types/aria-query": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", @@ -4675,12 +3726,13 @@ "version": "0.0.12", "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.12.tgz", "integrity": "sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "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": { @@ -4704,16 +3756,17 @@ } }, "node_modules/@types/dom-webcodecs": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.17.tgz", - "integrity": "sha512-IwKW5uKL0Zrv5ccUJpjIlqf7ppk2v29l/ZLQxLlwHxljBfnDD9Gxm+hzMkGM0AOAL/21H0pp7cTUYLiiVUGchA==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz", + "integrity": "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==", "license": "MIT" }, "node_modules/@types/earcut": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-3.0.0.tgz", - "integrity": "sha512-k/9fOUGO39yd2sCjrbAJvGDEQvRwRnQIZlBz43roGwUZo5SHAmyVvSFyaVVZkicRVCaDXPKlbxrUcBuJoSWunQ==", - "license": "MIT" + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.4.tgz", + "integrity": "sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ==", + "license": "MIT", + "peer": true }, "node_modules/@types/estree": { "version": "1.0.8", @@ -4754,9 +3807,9 @@ "license": "MIT" }, "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "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" }, @@ -4778,13 +3831,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", - "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", + "version": "22.19.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz", + "integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~6.21.0" } }, "node_modules/@types/plist": { @@ -4807,14 +3860,14 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.26", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.26.tgz", - "integrity": "sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==", + "version": "18.3.28", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz", + "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==", "devOptional": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { @@ -4837,13 +3890,6 @@ "@types/node": "*" } }, - "node_modules/@types/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/verror": { "version": "1.10.11", "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", @@ -4864,9 +3910,39 @@ } }, "node_modules/@uiw/color-convert": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.2.tgz", - "integrity": "sha512-ibw9OS29S7GlL+vDwU3p5XG3vhR7XdzUecydpZbakUeg2Td6nfsnrCAX9sbLwQ73p0abO42v+V4qRaWq+7/BjQ==", + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.10.1.tgz", + "integrity": "sha512-/Z3YfBiX+SErRM59yQH88Id+Xy/k10nnkfTuqhX6RB2yYUcG57DoFqb6FudhiQ5fwzKvKf1k4xq9lfT1UTFUKQ==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0" + } + }, + "node_modules/@uiw/react-color-alpha": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@uiw/react-color-alpha/-/react-color-alpha-2.9.6.tgz", + "integrity": "sha512-DNzEVHZ0Izp4NAwzKqTcl4rLdPjSFjyZCP6Q2vKJEglugZ/bdPsmZaos9IYOrgnd1kPDmTSKZ/p8nI7vBIATGw==", + "license": "MIT", + "dependencies": { + "@uiw/color-convert": "2.9.6", + "@uiw/react-drag-event-interactive": "2.9.6" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-alpha/node_modules/@uiw/color-convert": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.6.tgz", + "integrity": "sha512-w8TpU3MRcquurQJxWR1daKcRygu/a0hLP/VGsLMA3ebb41sAZGxMQLHtS+zC/e3ciFNB7BbPrSPlzOcz6w6cRg==", "license": "MIT", "funding": { "url": "https://jaywcjlove.github.io/#/sponsor" @@ -4876,14 +3952,14 @@ } }, "node_modules/@uiw/react-color-block": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@uiw/react-color-block/-/react-color-block-2.9.2.tgz", - "integrity": "sha512-0EIZTELA5pnxyMlBOFo3hrpy73db+Qeq6E+QptNfD/8izor8OvY1Uquj2VqD6gDz+iVHMELIoKxpaQ8sZR7NOg==", + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@uiw/react-color-block/-/react-color-block-2.10.1.tgz", + "integrity": "sha512-nGfhUGZhCbYH/gVvD12H9wZ/NBiToiSyrSdbracyIbA01tZInmkRNmfzTCkPq7yoXMa09I9G8pPISoyHre4TQg==", "license": "MIT", "dependencies": { - "@uiw/color-convert": "2.9.2", - "@uiw/react-color-editable-input": "2.9.2", - "@uiw/react-color-swatch": "2.9.2" + "@uiw/color-convert": "2.10.1", + "@uiw/react-color-editable-input": "2.10.1", + "@uiw/react-color-swatch": "2.10.1" }, "funding": { "url": "https://jaywcjlove.github.io/#/sponsor" @@ -4894,10 +3970,42 @@ "react-dom": ">=16.9.0" } }, + "node_modules/@uiw/react-color-colorful": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@uiw/react-color-colorful/-/react-color-colorful-2.9.6.tgz", + "integrity": "sha512-h74zo+ve9Rpv7xwb1dRfoa23yN39b6eYScDIm7V2d5FzkXN6hR7jnnJ7ZUD9Joz/rdaCz1eFQD9ig+wp8+wSnQ==", + "license": "MIT", + "dependencies": { + "@uiw/color-convert": "2.9.6", + "@uiw/react-color-alpha": "2.9.6", + "@uiw/react-color-hue": "2.9.6", + "@uiw/react-color-saturation": "2.9.6" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-colorful/node_modules/@uiw/color-convert": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.6.tgz", + "integrity": "sha512-w8TpU3MRcquurQJxWR1daKcRygu/a0hLP/VGsLMA3ebb41sAZGxMQLHtS+zC/e3ciFNB7BbPrSPlzOcz6w6cRg==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0" + } + }, "node_modules/@uiw/react-color-editable-input": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@uiw/react-color-editable-input/-/react-color-editable-input-2.9.2.tgz", - "integrity": "sha512-DY7pu12+LDRn6cxDMvsy1/quaPTxicAPz/kfODV7KBf8+Hq4rFWeJ4KS6m22IKIbQxrBQgmQG0WFJLaPeY7cPw==", + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@uiw/react-color-editable-input/-/react-color-editable-input-2.10.1.tgz", + "integrity": "sha512-jMim8eAw/5hz7gaZwBy3vM5wMxPMocOG+u1+wcKbqvavHaeg/wHq7Y29uRyFKj80s4FXvUKehXRQl0F68mA7jQ==", "license": "MIT", "funding": { "url": "https://jaywcjlove.github.io/#/sponsor" @@ -4908,13 +4016,14 @@ "react-dom": ">=16.9.0" } }, - "node_modules/@uiw/react-color-swatch": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@uiw/react-color-swatch/-/react-color-swatch-2.9.2.tgz", - "integrity": "sha512-6zBy+E9NzZR672M2wPsbbNRqKy9Wi9jOuuxxyzov1CEZp+pPX7UwMlCX6RUhKdO0PzTSPCVQmbz5bplu5vsW0w==", + "node_modules/@uiw/react-color-hue": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@uiw/react-color-hue/-/react-color-hue-2.9.6.tgz", + "integrity": "sha512-B99dW2/AHMD3py83BrXl94bhXeGCZR1FMpU/FNbIIbUrV9QTiIXDs2/SB/tMD9ltcSP59RD5Sc5m2vCb/8anjw==", "license": "MIT", "dependencies": { - "@uiw/color-convert": "2.9.2" + "@uiw/color-convert": "2.9.6", + "@uiw/react-color-alpha": "2.9.6" }, "funding": { "url": "https://jaywcjlove.github.io/#/sponsor" @@ -4925,66 +4034,213 @@ "react-dom": ">=16.9.0" } }, + "node_modules/@uiw/react-color-hue/node_modules/@uiw/color-convert": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.6.tgz", + "integrity": "sha512-w8TpU3MRcquurQJxWR1daKcRygu/a0hLP/VGsLMA3ebb41sAZGxMQLHtS+zC/e3ciFNB7BbPrSPlzOcz6w6cRg==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0" + } + }, + "node_modules/@uiw/react-color-saturation": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@uiw/react-color-saturation/-/react-color-saturation-2.9.6.tgz", + "integrity": "sha512-R1tiKbTG2WiJXerkmuaKnBFfzgyZUn08q9OjQSvNH1f3ov2/YeUVlOwQY9MbQE7ytZv+9x+1h0Lpk4QG7AdulQ==", + "license": "MIT", + "dependencies": { + "@uiw/color-convert": "2.9.6", + "@uiw/react-drag-event-interactive": "2.9.6" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-saturation/node_modules/@uiw/color-convert": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.6.tgz", + "integrity": "sha512-w8TpU3MRcquurQJxWR1daKcRygu/a0hLP/VGsLMA3ebb41sAZGxMQLHtS+zC/e3ciFNB7BbPrSPlzOcz6w6cRg==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0" + } + }, + "node_modules/@uiw/react-color-swatch": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@uiw/react-color-swatch/-/react-color-swatch-2.10.1.tgz", + "integrity": "sha512-DuGlaIszNcvtsY8BfW+RiUkEK1yVmnAamkzc/S5cQZwaAA5bCKhwwyaKPqh1/XWs7pR4pysjSNlMaeqaSOO34A==", + "license": "MIT", + "dependencies": { + "@uiw/color-convert": "2.10.1" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-drag-event-interactive": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@uiw/react-drag-event-interactive/-/react-drag-event-interactive-2.9.6.tgz", + "integrity": "sha512-jXzt3Xis/BIYap2Hj2++gB3aEUD0mZoVNGfckurrwjAwxasxNiwkmTGxV5er3due0ZgaVKdOAfTRoYKlgZukSg==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, "node_modules/@vitejs/plugin-react": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", - "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz", + "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.28.0", + "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.27", + "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", - "react-refresh": "^0.17.0" + "react-refresh": "^0.18.0" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^20.19.0 || >=22.12.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@vitest/browser": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.5.tgz", + "integrity": "sha512-iCDGI8c4yg+xmjUg2VsygdAUSIIB4x5Rht/P68OXy1hPELKXHDkzh87lkuTcdYmemRChDkEpB426MmDjzC0ziA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@blazediff/core": "1.9.1", + "@vitest/mocker": "4.1.5", + "@vitest/utils": "4.1.5", + "magic-string": "^0.30.21", + "pngjs": "^7.0.0", + "sirv": "^3.0.2", + "tinyrainbow": "^3.1.0", + "ws": "^8.19.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "4.1.5" + } + }, + "node_modules/@vitest/browser-playwright": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.5.tgz", + "integrity": "sha512-CWy0lBQJq97nionyJJdnaU4961IXTl43a7UCu5nHy51IoKxAt6PVIJLo+76rVl7KOOgcWHNkG4kbJu/pW7knvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/browser": "4.1.5", + "@vitest/mocker": "4.1.5", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "4.1.5" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": false + } } }, "node_modules/@vitest/expect": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.16.tgz", - "integrity": "sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.5.tgz", + "integrity": "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==", "dev": true, "license": "MIT", "dependencies": { - "@standard-schema/spec": "^1.0.0", + "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.0.16", - "@vitest/utils": "4.0.16", - "chai": "^6.2.1", - "tinyrainbow": "^3.0.3" + "@vitest/spy": "4.1.5", + "@vitest/utils": "4.1.5", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/pretty-format": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.16.tgz", - "integrity": "sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==", + "node_modules/@vitest/mocker": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.5.tgz", + "integrity": "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^3.0.3" + "@vitest/spy": "4.1.5", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.5.tgz", + "integrity": "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.16.tgz", - "integrity": "sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.5.tgz", + "integrity": "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.0.16", + "@vitest/utils": "4.1.5", "pathe": "^2.0.3" }, "funding": { @@ -4992,13 +4248,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.16.tgz", - "integrity": "sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.5.tgz", + "integrity": "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.16", + "@vitest/pretty-format": "4.1.5", + "@vitest/utils": "4.1.5", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -5007,9 +4264,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.16.tgz", - "integrity": "sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.5.tgz", + "integrity": "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==", "dev": true, "license": "MIT", "funding": { @@ -5017,29 +4274,30 @@ } }, "node_modules/@vitest/utils": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.16.tgz", - "integrity": "sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.5.tgz", + "integrity": "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.16", - "tinyrainbow": "^3.0.3" + "@vitest/pretty-format": "4.1.5", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@webgpu/types": { - "version": "0.1.66", - "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.66.tgz", - "integrity": "sha512-YA2hLrwLpDsRueNDXIMqN9NTzD6bCDkuXbOSe0heS+f8YE8usA6Gbv1prj81pzVHrbaAma7zObnIC+I6/sXJgA==", + "version": "0.1.69", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.69.tgz", + "integrity": "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==", "license": "BSD-3-Clause" }, "node_modules/@xmldom/xmldom": { - "version": "0.8.11", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", - "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", + "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -5053,29 +4311,19 @@ "license": "MIT" }, "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", "dev": true, - "license": "ISC" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, + "license": "ISC", "engines": { - "node": ">=6.5" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -5086,49 +4334,19 @@ } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "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", - "dependencies": { - "debug": "4" - }, "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agentkeepalive": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", - "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": ">= 14" } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -5172,6 +4390,7 @@ "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" @@ -5181,6 +4400,7 @@ "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" @@ -5192,13 +4412,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/any-base": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", - "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", - "dev": true, - "license": "MIT" - }, "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -5218,6 +4431,18 @@ "node": ">= 8" } }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/app-builder-bin": { "version": "5.0.0-alpha.12", "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz", @@ -5226,9 +4451,9 @@ "license": "MIT" }, "node_modules/app-builder-lib": { - "version": "26.7.0", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.7.0.tgz", - "integrity": "sha512-/UgCD8VrO79Wv8aBNpjMfsS1pIUfIPURoRn0Ik6tMe5avdZF+vQgl/juJgipcMmH3YS0BD573lCdCHyoi84USg==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.8.1.tgz", + "integrity": "sha512-p0Im/Dx5C4tmz8QEE1Yn4MkuPC8PrnlRneMhWJj7BBXQfNTJUshM/bp3lusdEsDbvvfJZpXWnYesgSLvwtM2Zw==", "dev": true, "license": "MIT", "dependencies": { @@ -5243,7 +4468,7 @@ "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", - "builder-util": "26.4.1", + "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chromium-pickle-js": "^0.2.0", "ci-info": "4.3.1", @@ -5251,7 +4476,7 @@ "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "ejs": "^3.1.8", - "electron-publish": "26.6.0", + "electron-publish": "26.8.1", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "isbinaryfile": "^5.0.0", @@ -5273,8 +4498,8 @@ "node": ">=14.0.0" }, "peerDependencies": { - "dmg-builder": "26.7.0", - "electron-builder-squirrel-windows": "26.7.0" + "dmg-builder": "26.8.1", + "electron-builder-squirrel-windows": "26.8.1" } }, "node_modules/app-builder-lib/node_modules/@electron/get": { @@ -5324,52 +4549,6 @@ "semver": "bin/semver.js" } }, - "node_modules/app-builder-lib/node_modules/@isaacs/cliui": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", - "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/app-builder-lib/node_modules/balanced-match": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", - "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", - "dev": true, - "license": "MIT", - "dependencies": { - "jackspeak": "^4.2.3" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/app-builder-lib/node_modules/brace-expansion": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", - "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/app-builder-lib/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/app-builder-lib/node_modules/ci-info": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", @@ -5402,9 +4581,9 @@ } }, "node_modules/app-builder-lib/node_modules/fs-extra/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -5424,144 +4603,17 @@ "node": ">= 10.0.0" } }, - "node_modules/app-builder-lib/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==", + "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": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/app-builder-lib/node_modules/jackspeak": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", - "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^9.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/app-builder-lib/node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "dev": true, - "license": "MIT", + "license": "ISC", "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/app-builder-lib/node_modules/minimatch": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", - "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" + "semver": "bin/semver.js" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/app-builder-lib/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/app-builder-lib/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/app-builder-lib/node_modules/tar": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz", - "integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==", - "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/app-builder-lib/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/app-builder-lib/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/aproba": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", - "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", - "dev": true, - "license": "ISC" - }, - "node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=10" } }, "node_modules/arg": { @@ -5577,100 +4629,6 @@ "dev": true, "license": "Python-2.0" }, - "node_modules/args": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz", - "integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "5.0.0", - "chalk": "2.4.2", - "leven": "2.1.0", - "mri": "1.1.4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/args/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/args/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/args/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/args/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/args/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/args/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/args/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/aria-hidden": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", @@ -5693,32 +4651,13 @@ "dequal": "^2.0.3" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true, "license": "MIT", + "optional": true, "engines": { "node": ">=0.8" } @@ -5779,9 +4718,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.21", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", - "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz", + "integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==", "dev": true, "funding": [ { @@ -5799,10 +4738,9 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.24.4", - "caniuse-lite": "^1.0.30001702", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", + "browserslist": "^4.28.2", + "caniuse-lite": "^1.0.30001787", + "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, @@ -5816,28 +4754,15 @@ "postcss": "^8.1.0" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "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": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" + "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", @@ -5861,23 +4786,16 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.15", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.15.tgz", - "integrity": "sha512-qsJ8/X+UypqxHXN75M7dF88jNK37dLBRW7LeUzCPz+TNs37G8cfWy9nWzS+LS//g600zrt2le9KuXt0rWfDz5Q==", + "version": "2.10.20", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.20.tgz", + "integrity": "sha512-1AaXxEPfXT+GvTBJFuy4yXVHWJBXa4OdbIebGN/wX5DlsIkU0+wzGnd2lOzokSk51d5LUmqjgBLRLlypLUqInQ==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tweetnacl": "^0.14.3" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/bidi-js": { @@ -5902,25 +4820,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bmp-js": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", - "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==", - "dev": true, - "license": "MIT" - }, "node_modules/boolean": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", @@ -5931,12 +4830,16 @@ "optional": true }, "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/braces": { @@ -5952,9 +4855,9 @@ } }, "node_modules/browserslist": { - "version": "4.26.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz", - "integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "dev": true, "funding": [ { @@ -5972,11 +4875,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.8.9", - "caniuse-lite": "^1.0.30001746", - "electron-to-chromium": "^1.5.227", - "node-releases": "^2.0.21", - "update-browserslist-db": "^1.1.3" + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -6005,6 +4908,7 @@ } ], "license": "MIT", + "optional": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -6028,9 +4932,9 @@ "license": "MIT" }, "node_modules/builder-util": { - "version": "26.4.1", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.4.1.tgz", - "integrity": "sha512-FlgH43XZ50w3UtS1RVGDWOz8v9qMXPC7upMtKMtBEnYdt1OVoS61NYhKm/4x+cIaWqJTXua0+VVPI+fSPGXNIw==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.8.1.tgz", + "integrity": "sha512-pm1lTYbGyc90DHgCDO7eo8Rl4EqKLciayNbZqGziqnH9jrlKe8ZANGdityLZU+pJh16dfzjAx2xQq9McuIPEtw==", "dev": true, "license": "MIT", "dependencies": { @@ -6066,16 +4970,6 @@ "node": ">=12.0.0" } }, - "node_modules/builder-util/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/builder-util/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -6091,38 +4985,10 @@ "node": ">=12" } }, - "node_modules/builder-util/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/builder-util/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/builder-util/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -6142,100 +5008,6 @@ "node": ">= 10.0.0" } }, - "node_modules/cacache": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", - "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/cacache/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/cacache/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cacache/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacache/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/cacheable-lookup": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", @@ -6295,16 +5067,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", @@ -6315,9 +5077,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001749", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001749.tgz", - "integrity": "sha512-0rw2fJOmLfnzCRbkm8EyHL8SvI2Apu5UbnQuTsJ0ClgrH8hcwFooJ1s5R0EP8o8aVrFu8++ae29Kt9/gZAZp/Q==", + "version": "1.0.30001788", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz", + "integrity": "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==", "dev": true, "funding": [ { @@ -6335,27 +5097,10 @@ ], "license": "CC-BY-4.0" }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/centra": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/centra/-/centra-2.7.0.tgz", - "integrity": "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6" - } - }, "node_modules/chai": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.1.tgz", - "integrity": "sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", "engines": { @@ -6416,13 +5161,13 @@ } }, "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "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": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/chromium-pickle-js": { @@ -6460,37 +5205,17 @@ "url": "https://polar.sh/cva" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, "license": "MIT", "dependencies": { - "restore-cursor": "^3.1.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6529,14 +5254,35 @@ "node": ">=12" } }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "node_modules/cliui/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": ">=0.8" + "node": ">=8" + } + }, + "node_modules/cliui/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/clone-response": { @@ -6561,20 +5307,11 @@ "node": ">=6" } }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "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" @@ -6587,17 +5324,8 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } + "license": "MIT" }, "node_modules/colorette": { "version": "2.0.20", @@ -6646,62 +5374,6 @@ "dev": true, "license": "MIT" }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/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/concat-stream/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/concat-stream/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/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true, - "license": "ISC" - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -6714,7 +5386,8 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/crc": { "version": "3.8.0", @@ -6740,6 +5413,7 @@ "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", @@ -6750,6 +5424,29 @@ "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/css-tree": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", @@ -6784,25 +5481,12 @@ } }, "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "devOptional": true, "license": "MIT" }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-urls": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", @@ -6835,16 +5519,6 @@ } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/decimal.js": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", @@ -6881,19 +5555,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "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", @@ -6942,29 +5603,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dev": true, - "license": "MIT", - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -6975,13 +5613,6 @@ "node": ">=0.4.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true, - "license": "MIT" - }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -6992,16 +5623,6 @@ "node": ">=6" } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -7033,10 +5654,17 @@ "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.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -7045,9 +5673,9 @@ } }, "node_modules/dir-compare/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "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": { @@ -7057,19 +5685,6 @@ "node": "*" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -7077,14 +5692,14 @@ "license": "MIT" }, "node_modules/dmg-builder": { - "version": "26.7.0", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.7.0.tgz", - "integrity": "sha512-uOOBA3f+kW3o4KpSoMQ6SNpdXU7WtxlJRb9vCZgOvqhTz4b3GjcoWKstdisizNZLsylhTMv8TLHFPFW0Uxsj/g==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.8.1.tgz", + "integrity": "sha512-glMJgnTreo8CFINujtAhCgN96QAqApDMZ8Vl1r8f0QT8QprvC1UCltV4CcWj20YoIyLZx6IUskaJZ0NV8fokcg==", "dev": true, "license": "MIT", "dependencies": { - "app-builder-lib": "26.7.0", - "builder-util": "26.4.1", + "app-builder-lib": "26.8.1", + "builder-util": "26.8.1", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" @@ -7109,9 +5724,9 @@ } }, "node_modules/dmg-builder/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -7159,9 +5774,9 @@ } }, "node_modules/dnd-timeline": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dnd-timeline/-/dnd-timeline-2.2.0.tgz", - "integrity": "sha512-bQ/2bm70eA7YeztgdxoSpdpTwPzj8VT2/wTlYrnFpqJ71et7EVJZR35XPZIVzBqSyKK9T/QyUzE26gYck9ldxg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/dnd-timeline/-/dnd-timeline-2.4.0.tgz", + "integrity": "sha512-f71y55DjT2VDongtnqVd7S6XGmpUT1PkYlooFQZxLHfPVfKsyTtMHsfbXN98k2GkA5Z4h3ibqFjwBIfckE0aEg==", "license": "MIT", "dependencies": { "@dnd-kit/core": "^6.1.0", @@ -7177,12 +5792,6 @@ "license": "MIT", "peer": true }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, "node_modules/dotenv": { "version": "16.6.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", @@ -7227,27 +5836,11 @@ } }, "node_modules/earcut": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", - "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==", - "license": "ISC" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==", + "license": "ISC", + "peer": true }, "node_modules/ejs": { "version": "3.1.10", @@ -7266,15 +5859,15 @@ } }, "node_modules/electron": { - "version": "39.2.7", - "resolved": "https://registry.npmjs.org/electron/-/electron-39.2.7.tgz", - "integrity": "sha512-KU0uFS6LSTh4aOIC3miolcbizOFP7N1M46VTYVfqIgFiuA2ilfNaOHLDS9tCMvwwHRowAsvqBrh9NgMXcTOHCQ==", + "version": "41.2.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-41.2.1.tgz", + "integrity": "sha512-teeRThiYGTPKf/2yOW7zZA1bhb91KEQ4yLBPOg7GxpmnkLFLugKgQaAKOrCgdzwsXh/5mFIfmkm+4+wACJKwaA==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { "@electron/get": "^2.0.0", - "@types/node": "^22.7.7", + "@types/node": "^24.9.0", "extract-zip": "^2.0.1" }, "bin": { @@ -7285,18 +5878,18 @@ } }, "node_modules/electron-builder": { - "version": "26.7.0", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.7.0.tgz", - "integrity": "sha512-LoXbCvSFxLesPneQ/fM7FB4OheIDA2tjqCdUkKlObV5ZKGhYgi5VHPHO/6UUOUodAlg7SrkPx7BZJPby+Vrtbg==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.8.1.tgz", + "integrity": "sha512-uWhx1r74NGpCagG0ULs/P9Nqv2nsoo+7eo4fLUOB8L8MdWltq9odW/uuLXMFCDGnPafknYLZgjNX0ZIFRzOQAw==", "dev": true, "license": "MIT", "dependencies": { - "app-builder-lib": "26.7.0", - "builder-util": "26.4.1", + "app-builder-lib": "26.8.1", + "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "ci-info": "^4.2.0", - "dmg-builder": "26.7.0", + "dmg-builder": "26.8.1", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "simple-update-notifier": "2.0.0", @@ -7311,15 +5904,15 @@ } }, "node_modules/electron-builder-squirrel-windows": { - "version": "26.7.0", - "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.7.0.tgz", - "integrity": "sha512-3EqkQK+q0kGshdPSKEPb2p5F75TENMKu6Fe5aTdeaPfdzFK4Yjp5L0d6S7K8iyvqIsGQ/ei4bnpyX9wt+kVCKQ==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.8.1.tgz", + "integrity": "sha512-o288fIdgPLHA76eDrFADHPoo7VyGkDCYbLV1GzndaMSAVBoZrGvM9m2IehdcVMzdAZJ2eV9bgyissQXHv5tGzA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "app-builder-lib": "26.7.0", - "builder-util": "26.4.1", + "app-builder-lib": "26.8.1", + "builder-util": "26.8.1", "electron-winstaller": "5.4.0" } }, @@ -7339,9 +5932,9 @@ } }, "node_modules/electron-builder/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -7361,33 +5954,15 @@ "node": ">= 10.0.0" } }, - "node_modules/electron-icon-builder": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/electron-icon-builder/-/electron-icon-builder-2.0.1.tgz", - "integrity": "sha512-rg9BxW2kJi3TXsMFFNXWXrwQEd5dzXmeD+w7Pj3k3z7aYRePLxE89qU4lvL/rK1X/NTY5KDn3+Dbgm1TU2dGXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "args": "^5.0.1", - "icon-gen": "^2.0.0", - "jimp": "^0.16.1" - }, - "bin": { - "electron-icon-builder": "index.js" - }, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/electron-publish": { - "version": "26.6.0", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.6.0.tgz", - "integrity": "sha512-LsyHMMqbvJ2vsOvuWJ19OezgF2ANdCiHpIucDHNiLhuI+/F3eW98ouzWSRmXXi82ZOPZXC07jnIravY4YYwCLQ==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.8.1.tgz", + "integrity": "sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==", "dev": true, "license": "MIT", "dependencies": { "@types/fs-extra": "^9.0.11", - "builder-util": "26.4.1", + "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "form-data": "^4.0.5", @@ -7412,9 +5987,9 @@ } }, "node_modules/electron-publish/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -7434,78 +6009,10 @@ "node": ">= 10.0.0" } }, - "node_modules/electron-rebuild": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-3.2.9.tgz", - "integrity": "sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw==", - "deprecated": "Please use @electron/rebuild moving forward. There is no API change, just a package name change", - "dev": true, - "license": "MIT", - "dependencies": { - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.1.1", - "detect-libc": "^2.0.1", - "fs-extra": "^10.0.0", - "got": "^11.7.0", - "lzma-native": "^8.0.5", - "node-abi": "^3.0.0", - "node-api-version": "^0.1.4", - "node-gyp": "^9.0.0", - "ora": "^5.1.0", - "semver": "^7.3.5", - "tar": "^6.0.5", - "yargs": "^17.0.1" - }, - "bin": { - "electron-rebuild": "lib/src/cli.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/electron-rebuild/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-rebuild/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-rebuild/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-to-chromium": { - "version": "1.5.234", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz", - "integrity": "sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg==", + "version": "1.5.340", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.340.tgz", + "integrity": "sha512-908qahOGocRMinT2nM3ajCEM99H4iPdv84eagPP3FfZy/1ZGeOy2CZYzjhms81ckOPCXPlW7LkY4XpxD8r1DrA==", "dev": true, "license": "ISC" }, @@ -7548,26 +6055,26 @@ } }, "node_modules/electron/node_modules/@types/node": { - "version": "22.19.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", - "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", + "version": "24.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz", + "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.16.0" } }, "node_modules/electron/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==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" }, "node_modules/emoji-picker-react": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/emoji-picker-react/-/emoji-picker-react-4.16.1.tgz", - "integrity": "sha512-MrPX0tOCfRL3uYI4of/2GRZ7S6qS7YlacKiF78uFH84/C62vcuHE2DZyv5b4ZJMk0e06es1jjB4e31Bb+YSM8w==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/emoji-picker-react/-/emoji-picker-react-4.18.0.tgz", + "integrity": "sha512-vLTrLfApXAIciguGE57pXPWs9lPLBspbEpPMiUq03TIli2dHZBiB+aZ0R9/Wat0xmTfcd4AuEzQgSYxEZ8C88Q==", "license": "MIT", "dependencies": { "flairup": "1.0.0" @@ -7583,18 +6090,8 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } + "license": "MIT" }, "node_modules/end-of-stream": { "version": "1.4.5", @@ -7607,13 +6104,13 @@ } }, "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", "dev": true, "license": "BSD-2-Clause", "engines": { - "node": ">=0.12" + "node": ">=20.19.0" }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" @@ -7649,16 +6146,6 @@ "dev": true, "license": "MIT" }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -7678,9 +6165,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, @@ -7720,17 +6207,10 @@ "license": "MIT", "optional": true }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true, - "license": "MIT" - }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -7738,32 +6218,35 @@ "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" } }, "node_modules/escalade": { @@ -7800,37 +6283,12 @@ "@types/estree": "^1.0.0" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/exif-parser": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", - "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==", - "dev": true + "peer": true }, "node_modules/expect-type": { "version": "1.3.0", @@ -7849,13 +6307,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true, - "license": "MIT" - }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -7889,9 +6340,9 @@ "optional": true }, "node_modules/fast-check": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.5.2.tgz", - "integrity": "sha512-tOzL01LMrDIWPLfvMiGUMH0AjqnOelHQPmgvYkW/aRO4Yaw+pBQqWmyebNzAEbKOigoCN8HkRWUZXFkjmiaXMQ==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.7.0.tgz", + "integrity": "sha512-NsZRtqvSSoCP0HbNjUD+r1JH8zqZalyp6gLY9e7OYs7NK9b6AHOs2baBFeBG7bVNsuoukh89x2Yg3rPsul8ziQ==", "dev": true, "funding": [ { @@ -7905,7 +6356,7 @@ ], "license": "MIT", "dependencies": { - "pure-rand": "^7.0.0" + "pure-rand": "^8.0.0" }, "engines": { "node": ">=12.17.0" @@ -7954,9 +6405,9 @@ "license": "MIT" }, "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -7972,48 +6423,54 @@ "pend": "~1.2.0" } }, - "node_modules/file-type": { - "version": "16.5.4", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", - "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-web-to-node-stream": "^3.0.0", - "strtok3": "^6.2.4", - "token-types": "^4.1.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" - } - }, - "node_modules/file-url": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/file-url/-/file-url-2.0.2.tgz", - "integrity": "sha512-x3989K8a1jM6vulMigE8VngH7C5nci0Ks5d9kVjUXmNF28gmiZUNujk5HjwaS8dAzN2QmUfX56riJKgN00dNRw==", - "dev": true, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "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.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "dev": true, "license": "ISC", "dependencies": { @@ -8047,53 +6504,6 @@ "integrity": "sha512-IKlE+pNvL2R+kVL1kEhUYqRxVqeFnjiIvHWDMLFXNaqyUdFXQM2wte44EfMYJNHkW16X991t2Zg8apKkhv7OBA==", "license": "MIT" }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, "node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", @@ -8112,27 +6522,27 @@ } }, "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", "dev": true, "license": "MIT", "engines": { "node": "*" }, "funding": { - "type": "patreon", + "type": "github", "url": "https://github.com/sponsors/rawify" } }, "node_modules/framer-motion": { - "version": "12.23.24", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.24.tgz", - "integrity": "sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w==", + "version": "12.38.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz", + "integrity": "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==", "license": "MIT", "dependencies": { - "motion-dom": "^12.23.23", - "motion-utils": "^12.23.6", + "motion-dom": "^12.38.0", + "motion-utils": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { @@ -8167,39 +6577,6 @@ "node": ">=6 <7 || >=8" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs-minipass/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/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -8208,9 +6585,9 @@ "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "hasInstallScript": true, "license": "MIT", "optional": true, @@ -8230,34 +6607,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/gauge/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/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -8353,16 +6702,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/gif.js": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/gif.js/-/gif.js-0.2.0.tgz", @@ -8378,22 +6717,11 @@ "js-binary-schema-parser": "^2.0.3" } }, - "node_modules/gifwrap": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.4.tgz", - "integrity": "sha512-MDMwbhASQuVeD4JKd1fKgNgCRL3fGqMM4WaqpNhWO0JiMOAjbQdumbs4BbBZEy9/M00EHEjKN3HieVhCUlwjeQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "image-q": "^4.0.0", - "omggif": "^1.0.10" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "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": { @@ -8423,10 +6751,17 @@ "node": ">=10.13.0" } }, + "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.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -8435,9 +6770,9 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "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": { @@ -8447,17 +6782,6 @@ "node": "*" } }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "node_modules/global-agent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", @@ -8477,6 +6801,20 @@ "node": ">=10.0" } }, + "node_modules/global-agent/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", + "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", @@ -8495,27 +6833,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -8562,36 +6879,11 @@ "license": "ISC" }, "node_modules/gsap": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.13.0.tgz", - "integrity": "sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.15.0.tgz", + "integrity": "sha512-dMW4CWBTUK1AEEDeZc1g4xpPGIrSf9fJF960qbTZmN/QwZIWY5wgliS6JWl9/25fpTGJrMRtSjGtOmPnfjZB+A==", "license": "Standard 'no charge' license: https://gsap.com/standard-license." }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -8644,31 +6936,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/hasha": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", - "integrity": "sha512-jZ38TU/EBiGKrmyTNNZgnvCZHNowiRI4+w/I9noMlekHTZH3KyGgvJLmhSgykeAQ9j2SYPDosM0Bg3wHfzibAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -8731,34 +7002,17 @@ "license": "BSD-2-Clause" }, "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "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": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "node": ">= 14" } }, "node_modules/http2-wrapper": { @@ -8776,27 +7030,17 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "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": "6", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.0.0" + "node": ">= 14" } }, "node_modules/husky": { @@ -8815,47 +7059,6 @@ "url": "https://github.com/sponsors/typicode" } }, - "node_modules/icon-gen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/icon-gen/-/icon-gen-2.1.0.tgz", - "integrity": "sha512-rqIVvq9MJ8X7wnJW0NO8Eau/+5RWV7AH6L5vEt/U5Ajv5WefdDNDxGwJhGokyHuyBWeX7JqRMQ03tG0gAco4Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^6.2.0", - "del": "^6.0.0", - "mkdirp": "^1.0.4", - "pngjs": "^6.0.0", - "svg2png": "4.1.1", - "uuid": "^8.3.1" - }, - "bin": { - "icon-gen": "dist/bin/index.js" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/icon-gen/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/icon-gen/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/iconv-corefoundation": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", @@ -8906,44 +7109,8 @@ "url": "https://feross.org/support" } ], - "license": "BSD-3-Clause" - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/image-q": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", - "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "16.9.1" - } - }, - "node_modules/image-q/node_modules/@types/node": { - "version": "16.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==", - "dev": true, - "license": "MIT" - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } + "license": "BSD-3-Clause", + "optional": true }, "node_modules/indent-string": { "version": "4.0.0", @@ -8955,13 +7122,6 @@ "node": ">=8" } }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true, - "license": "ISC" - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -8981,33 +7141,6 @@ "dev": true, "license": "ISC" }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ip-address": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", - "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -9048,18 +7181,12 @@ "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/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true, - "license": "MIT" - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -9072,23 +7199,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true, - "license": "MIT" - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -9098,26 +7208,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -9125,50 +7215,6 @@ "dev": true, "license": "MIT" }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true, - "license": "MIT" - }, - "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", @@ -9183,10 +7229,14 @@ } }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" + "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/ismobilejs": { "version": "1.1.1", @@ -9194,28 +7244,6 @@ "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==", "license": "MIT" }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jake": { "version": "10.9.4", "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", @@ -9234,36 +7262,16 @@ "node": ">=10" } }, - "node_modules/jimp": { - "version": "0.16.13", - "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.16.13.tgz", - "integrity": "sha512-Bxz8q7V4rnCky9A0ktTNGA9SkNFVWRHodddI/DaAWZJzF7sVUlFYKQ60y9JGqrKpi48ECA/TnfMzzc5C70VByA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/custom": "^0.16.13", - "@jimp/plugins": "^0.16.13", - "@jimp/types": "^0.16.13", - "regenerator-runtime": "^0.13.3" - } - }, "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "devOptional": true, "license": "MIT", "bin": { - "jiti": "bin/jiti.js" + "jiti": "lib/jiti-cli.mjs" } }, - "node_modules/jpeg-js": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", - "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/js-binary-schema-parser": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/js-binary-schema-parser/-/js-binary-schema-parser-2.0.3.tgz", @@ -9289,22 +7297,15 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "license": "MIT" - }, "node_modules/jsdom": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.0.1.tgz", - "integrity": "sha512-z6JOK5gRO7aMybVq/y/MlIpKh8JIi68FBKMUtKkK2KH/wMSRlCxQ682d08LB9fYXplyY/UXG8P4XXTScmdjApg==", + "version": "29.0.2", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.0.2.tgz", + "integrity": "sha512-9VnGEBosc/ZpwyOsJBCQ/3I5p7Q5ngOY14a9bf5btenAORmZfDse1ZEheMiWcJ3h81+Fv7HmJFdS0szo/waF2w==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^5.0.1", - "@asamuzakjp/dom-selector": "^7.0.3", + "@asamuzakjp/css-color": "^5.1.5", + "@asamuzakjp/dom-selector": "^7.0.6", "@bramus/specificity": "^2.4.2", "@csstools/css-syntax-patches-for-csstree": "^1.1.1", "@exodus/bytes": "^1.15.0", @@ -9338,28 +7339,15 @@ } }, "node_modules/jsdom/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" } }, - "node_modules/jsdom/node_modules/tough-cookie": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", - "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tldts": "^7.0.5" - }, - "engines": { - "node": ">=16" - } - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -9380,13 +7368,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "license": "(AFL-2.1 OR BSD-3-Clause)" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -9399,7 +7380,8 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true, - "license": "ISC" + "license": "ISC", + "optional": true }, "node_modules/json5": { "version": "2.2.3", @@ -9424,54 +7406,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/jsprim/node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT" - }, - "node_modules/jsprim/node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/kew": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", - "integrity": "sha512-IG6nm0+QtAMdXt9KvbgbGdvY50RSrw+U4sGZg+KlrSKPJEwVE5JVoI3d7RWfSMdBQneRheeAOj3lIjX5VL/9RQ==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -9482,16 +7416,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.9" - } - }, "node_modules/lazy-val": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", @@ -9499,29 +7423,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -9541,17 +7442,17 @@ "license": "MIT" }, "node_modules/lint-staged": { - "version": "16.3.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.3.2.tgz", - "integrity": "sha512-xKqhC2AeXLwiAHXguxBjuChoTTWFC6Pees0SHPwOpwlvI3BH7ZADFPddAdN3pgo3aiKgPUx/bxE78JfUnxQnlg==", + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.4.0.tgz", + "integrity": "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==", "dev": true, "license": "MIT", "dependencies": { "commander": "^14.0.3", "listr2": "^9.0.5", - "micromatch": "^4.0.8", + "picomatch": "^4.0.3", "string-argv": "^0.3.2", - "tinyexec": "^1.0.2", + "tinyexec": "^1.0.4", "yaml": "^2.8.2" }, "bin": { @@ -9592,19 +7493,6 @@ "node": ">=20.0.0" } }, - "node_modules/listr2/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/listr2/node_modules/ansi-styles": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", @@ -9635,10 +7523,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "dev": true, "license": "MIT" }, @@ -9692,153 +7580,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/listr2/node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/listr2/node_modules/wrap-ansi/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/load-bmfont": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.2.tgz", - "integrity": "sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-equal": "0.0.1", - "mime": "^1.3.4", - "parse-bmfont-ascii": "^1.0.3", - "parse-bmfont-binary": "^1.0.5", - "parse-bmfont-xml": "^1.1.4", - "phin": "^3.7.1", - "xhr": "^2.0.1", - "xtend": "^4.0.0" - } - }, - "node_modules/load-bmfont/node_modules/buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/load-bmfont/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-bmfont/node_modules/phin": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/phin/-/phin-3.7.1.tgz", - "integrity": "sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "license": "MIT", - "dependencies": { - "centra": "^2.7.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "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/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/log-update": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", @@ -9859,19 +7607,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/log-update/node_modules/ansi-styles": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", @@ -9885,29 +7620,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/log-update/node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, - "license": "MIT" - }, "node_modules/log-update/node_modules/is-fullwidth-code-point": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", @@ -9924,39 +7636,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/log-update/node_modules/slice-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", @@ -9974,58 +7653,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/log-update/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -10078,32 +7705,6 @@ "lz-string": "bin/bin.js" } }, - "node_modules/lzma-native": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz", - "integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^3.1.0", - "node-gyp-build": "^4.2.1", - "readable-stream": "^3.6.0" - }, - "bin": { - "lzmajs": "bin/lzmajs" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/lzma-native/node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true, - "license": "MIT" - }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -10114,64 +7715,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/make-fetch-happen": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", - "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", - "dev": true, - "license": "ISC", - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/make-fetch-happen/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/make-fetch-happen/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/matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", @@ -10203,9 +7746,9 @@ "license": "CC0-1.0" }, "node_modules/mediabunny": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.25.1.tgz", - "integrity": "sha512-0Rrd47PMCVJbTPA7IJaXPCupV5/RZ/icgr+a0qExRJAr0n5vB4fsGSo+fdHIehG0CrddXtVRvNZwFtJz709yfA==", + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.40.1.tgz", + "integrity": "sha512-HU/stGzAkdWaJIly6ypbUVgAUvT9kt39DIg0IaErR7/1fwtTmgUYs4i8uEPYcgcjPjbB9gtBmUXOLnXi6J2LDw==", "license": "MPL-2.0", "workspaces": [ "packages/*" @@ -10219,12 +7762,6 @@ "url": "https://github.com/sponsors/Vanilagy" } }, - "node_modules/mediabunny/node_modules/@types/dom-webcodecs": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz", - "integrity": "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==", - "license": "MIT" - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -10247,6 +7784,18 @@ "node": ">=8.6" } }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -10283,16 +7832,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/mimic-function": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", @@ -10316,16 +7855,6 @@ "node": ">=4" } }, - "node_modules/min-document": { - "version": "2.19.2", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.2.tgz", - "integrity": "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "dom-walk": "^0.1.0" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -10337,15 +7866,16 @@ } }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -10362,238 +7892,49 @@ } }, "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "license": "ISC", + "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": ">=8" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect/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/minipass-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", - "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/minipass-fetch/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-fetch/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/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-flush/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/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/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/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized/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/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "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": "^3.0.0", - "yallist": "^4.0.0" + "minipass": "^7.1.2" }, "engines": { - "node": ">= 8" + "node": ">= 18" } }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib/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/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "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" - }, - "engines": { - "node": ">=10" } }, "node_modules/motion": { - "version": "12.23.24", - "resolved": "https://registry.npmjs.org/motion/-/motion-12.23.24.tgz", - "integrity": "sha512-Rc5E7oe2YZ72N//S3QXGzbnXgqNrTESv8KKxABR20q2FLch9gHLo0JLyYo2hZ238bZ9Gx6cWhj9VO0IgwbMjCw==", + "version": "12.38.0", + "resolved": "https://registry.npmjs.org/motion/-/motion-12.38.0.tgz", + "integrity": "sha512-uYfXzeHlgThchzwz5Te47dlv5JOUC7OB4rjJ/7XTUgtBZD8CchMN8qEJ4ZVsUmTyYA44zjV0fBwsiktRuFnn+w==", "license": "MIT", "dependencies": { - "framer-motion": "^12.23.24", + "framer-motion": "^12.38.0", "tslib": "^2.4.0" }, "peerDependencies": { @@ -10614,37 +7955,37 @@ } }, "node_modules/motion-dom": { - "version": "12.23.23", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.23.tgz", - "integrity": "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==", + "version": "12.38.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz", + "integrity": "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==", "license": "MIT", "dependencies": { - "motion-utils": "^12.23.6" + "motion-utils": "^12.36.0" } }, "node_modules/motion-utils": { - "version": "12.23.6", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz", - "integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==", + "version": "12.36.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz", + "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==", "license": "MIT" }, "node_modules/mp4box": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/mp4box/-/mp4box-2.2.0.tgz", - "integrity": "sha512-tE+L7wdhSuwBKZGjUzj03Qzj4lWyOw8pHSPyLnvHTKx92NJGkJls0pcEusUHWEh5gWVBlhdu79STJh4Bubz9mQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/mp4box/-/mp4box-2.3.0.tgz", + "integrity": "sha512-nnABYbdh4UguEYyV+uRwQBi1tbb8kXka2Fx9yKzmDKAeh8gkvRKYxoK1XDd8GQIjSfN4rvsXrW1CBo4yRQJZDA==", "license": "BSD-3-Clause", "engines": { "node": ">=20.8.1" } }, - "node_modules/mri": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz", - "integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==", + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=10" } }, "node_modules/ms": { @@ -10683,24 +8024,27 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/node-abi": { - "version": "3.78.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.78.0.tgz", - "integrity": "sha512-E2wEyrgX/CqvicaQYU3Ze1PFGjc4QYPGsjUrlYkqAE0WjHEZwgOsGMPMzkMse4LjJbDmaEuDX3CM036j5K2DSQ==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-4.28.0.tgz", + "integrity": "sha512-Qfp5XZL1cJDOabOT8H5gnqMTmM4NjvYzHp4I/Kt/Sl76OVkOBBHRFlPspGV0hYvMoqQsypFjT/Yp7Km0beXW9g==", "dev": true, "license": "MIT", "dependencies": { - "semver": "^7.3.5" + "semver": "^7.6.3" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/node-abi/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" @@ -10715,46 +8059,57 @@ "optional": true }, "node_modules/node-api-version": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz", - "integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==", + "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.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/node-gyp": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", - "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.3.0.tgz", + "integrity": "sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg==", "dev": true, "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", - "glob": "^7.1.4", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" + "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": "^12.13 || ^14.13 || >=16" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/node-gyp-build": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", - "dev": true, "license": "MIT", "bin": { "node-gyp-build": "bin.js", @@ -10762,57 +8117,76 @@ "node-gyp-build-test": "build-test.js" } }, + "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.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/node-gyp/node_modules/undici": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", + "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "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-releases": { - "version": "2.0.23", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.23.tgz", - "integrity": "sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==", + "version": "2.0.37", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", + "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", "dev": true, "license": "MIT" }, "node_modules/nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "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": "^1.0.0" + "abbrev": "^4.0.0" }, "bin": { "nopt": "bin/nopt.js" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/normalize-package-data/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": "^20.17.0 || >=22.9.0" } }, "node_modules/normalize-path": { @@ -10824,16 +8198,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/normalize-url": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", @@ -10847,43 +8211,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -10937,13 +8264,6 @@ ], "license": "MIT" }, - "node_modules/omggif": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", - "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", - "dev": true, - "license": "MIT" - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -10955,58 +8275,21 @@ } }, "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, "license": "MIT", "dependencies": { - "mimic-fn": "^2.1.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">=6" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", @@ -11033,80 +8316,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "license": "BlueOak-1.0.0" - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true, - "license": "(MIT AND Zlib)" - }, - "node_modules/parse-bmfont-ascii": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", - "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==", - "dev": true, - "license": "MIT" - }, - "node_modules/parse-bmfont-binary": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", - "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/parse-bmfont-xml": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz", - "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "xml-parse-from-string": "^1.0.0", - "xml2js": "^0.5.0" - } - }, - "node_modules/parse-headers": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.6.tgz", - "integrity": "sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==", - "dev": true, - "license": "MIT" - }, - "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/parse-svg-path": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", @@ -11114,13 +8323,13 @@ "license": "MIT" }, "node_modules/parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", - "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", "dev": true, "license": "MIT", "dependencies": { - "entities": "^6.0.0" + "entities": "^8.0.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -11140,6 +8349,7 @@ "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" @@ -11151,38 +8361,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -11205,20 +8383,6 @@ "url": "https://github.com/sponsors/jet2jet" } }, - "node_modules/peek-readable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", - "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -11226,134 +8390,6 @@ "dev": true, "license": "MIT" }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "license": "MIT" - }, - "node_modules/phantomjs-prebuilt": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", - "integrity": "sha512-PIiRzBhW85xco2fuj41FmsyuYHKjKuXWmhjy3A/Y+CMpN/63TV+s9uzfVhsUwFe0G77xWtHBG8xmXf5BqEUEuQ==", - "deprecated": "this package is now deprecated", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "es6-promise": "^4.0.3", - "extract-zip": "^1.6.5", - "fs-extra": "^1.0.0", - "hasha": "^2.2.0", - "kew": "^0.7.0", - "progress": "^1.1.8", - "request": "^2.81.0", - "request-progress": "^2.0.1", - "which": "^1.2.10" - }, - "bin": { - "phantomjs": "bin/phantomjs" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/phantomjs-prebuilt/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", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/phantomjs-prebuilt/node_modules/progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/phin": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", - "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -11361,12 +8397,12 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -11381,29 +8417,6 @@ "node": ">=0.10.0" } }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pirates": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", @@ -11413,29 +8426,6 @@ "node": ">= 6" } }, - "node_modules/pixelmatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", - "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", - "dev": true, - "license": "ISC", - "dependencies": { - "pngjs": "^3.0.0" - }, - "bin": { - "pixelmatch": "bin/pixelmatch" - } - }, - "node_modules/pixelmatch/node_modules/pngjs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/pixi-filters": { "version": "6.1.5", "resolved": "https://registry.npmjs.org/pixi-filters/-/pixi-filters-6.1.5.tgz", @@ -11449,35 +8439,57 @@ } }, "node_modules/pixi.js": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-8.14.0.tgz", - "integrity": "sha512-ituDiEBb1Oqx56RYwTtC6MjPUhPfF/i15fpUv5oEqmzC/ce3SaSumulJcOjKG7+y0J0Ekl9Rl4XTxaUw+MVFZw==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-8.18.1.tgz", + "integrity": "sha512-6LUPWYgulZhp/w4kam2XHXB0QedISZIqrJbRdHLLQ3csn5a38uzKxAp6B5j6s89QFYaIJbg95kvgTRcbgpO1ow==", "license": "MIT", + "workspaces": [ + "examples", + "playground" + ], "dependencies": { "@pixi/colord": "^2.9.6", - "@types/css-font-loading-module": "^0.0.12", "@types/earcut": "^3.0.0", - "@webgpu/types": "^0.1.40", - "@xmldom/xmldom": "^0.8.10", + "@webgpu/types": "^0.1.69", + "@xmldom/xmldom": "^0.8.12", "earcut": "^3.0.2", "eventemitter3": "^5.0.1", "gifuct-js": "^2.1.2", "ismobilejs": "^1.1.1", "parse-svg-path": "^0.1.2", - "tiny-lru": "^11.4.5" + "tiny-lru": "^11.4.7" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/pixijs" } }, + "node_modules/pixi.js/node_modules/@types/earcut": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-3.0.0.tgz", + "integrity": "sha512-k/9fOUGO39yd2sCjrbAJvGDEQvRwRnQIZlBz43roGwUZo5SHAmyVvSFyaVVZkicRVCaDXPKlbxrUcBuJoSWunQ==", + "license": "MIT" + }, + "node_modules/pixi.js/node_modules/earcut": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", + "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==", + "license": "ISC" + }, + "node_modules/pixi.js/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, "node_modules/playwright": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", - "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz", + "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.58.2" + "playwright-core": "1.59.1" }, "bin": { "playwright": "cli.js" @@ -11490,10 +8502,11 @@ } }, "node_modules/playwright-core": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", - "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz", + "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==", "dev": true, + "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" }, @@ -11501,20 +8514,6 @@ "node": ">=18" } }, - "node_modules/playwright/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/plist": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", @@ -11530,27 +8529,20 @@ "node": ">=10.4.0" } }, - "node_modules/pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", - "dev": true, - "license": "MIT" - }, "node_modules/pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", "dev": true, "license": "MIT", "engines": { - "node": ">=12.13.0" + "node": ">=14.19.0" } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", "funding": [ { "type": "opencollective", @@ -11763,41 +8755,16 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-format/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/proc-log": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", - "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "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": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.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", @@ -11808,13 +8775,6 @@ "node": ">=0.4.0" } }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true, - "license": "ISC" - }, "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", @@ -11840,6 +8800,12 @@ "react-is": "^16.13.1" } }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/proper-lockfile": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", @@ -11852,30 +8818,10 @@ "signal-exit": "^3.0.2" } }, - "node_modules/proper-lockfile/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/psl": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", - "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "funding": { - "url": "https://github.com/sponsors/lupomontero" - } - }, "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "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": { @@ -11894,9 +8840,9 @@ } }, "node_modules/pure-rand": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", - "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.0.tgz", + "integrity": "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==", "dev": true, "funding": [ { @@ -11911,9 +8857,9 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", "license": "BSD-3-Clause", "peer": true, "dependencies": { @@ -11995,12 +8941,12 @@ } }, "node_modules/react-draggable": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.6.tgz", - "integrity": "sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.5.0.tgz", + "integrity": "sha512-VC+HBLEZ0XJxnOxVAZsdRi8rD04Iz3SiiKOoYzamjylUcju/hP9np/aZdLHf/7WOD268WMoNJMvYfB5yAK45cw==", "license": "MIT", "dependencies": { - "clsx": "^1.1.1", + "clsx": "^2.1.1", "prop-types": "^15.8.1" }, "peerDependencies": { @@ -12008,34 +8954,27 @@ "react-dom": ">= 16.3.0" } }, - "node_modules/react-draggable/node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/react-icons": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", - "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.6.0.tgz", + "integrity": "sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==", "license": "MIT", "peerDependencies": { "react": "*" } }, "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true }, "node_modules/react-refresh": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", - "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", "dev": true, "license": "MIT", "engines": { @@ -12043,9 +8982,9 @@ } }, "node_modules/react-remove-scroll": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", - "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", + "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.7", @@ -12100,13 +9039,13 @@ } }, "node_modules/react-rnd": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/react-rnd/-/react-rnd-10.5.2.tgz", - "integrity": "sha512-0Tm4x7k7pfHf2snewJA8x7Nwgt3LV+58MVEWOVsFjk51eYruFEa6Wy7BNdxt4/lH0wIRsu7Gm3KjSXY2w7YaNw==", + "version": "10.5.3", + "resolved": "https://registry.npmjs.org/react-rnd/-/react-rnd-10.5.3.tgz", + "integrity": "sha512-s/sIT3pGZnQ+57egijkTp9mizjIWrJz68Pq6yd+F/wniFY3IriML18dUXnQe/HP9uMiJ+9MAp44hljG99fZu6Q==", "license": "MIT", "dependencies": { - "re-resizable": "6.11.2", - "react-draggable": "4.4.6", + "re-resizable": "^6.11.2", + "react-draggable": "^4.5.0", "tslib": "2.6.2" }, "peerDependencies": { @@ -12164,151 +9103,6 @@ "pify": "^2.3.0" } }, - "node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readable-web-to-node-stream": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", - "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "^4.7.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/readable-web-to-node-stream/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "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", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", - "dev": true, - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -12321,6 +9115,18 @@ "node": ">=8.10.0" } }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -12335,92 +9141,6 @@ "node": ">=8" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true, - "license": "MIT" - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha512-dxdraeZVUNEn9AvLrxkgB2k6buTlym71dJk1fk4v8j3Ou3RKNm07BcgbHdj2lLgYGfqX71F+awb1MR+tWPFJzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "throttleit": "^1.0.0" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -12441,13 +9161,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true, - "license": "ISC" - }, "node_modules/resedit": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/resedit/-/resedit-1.7.2.tgz", @@ -12473,12 +9186,13 @@ "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "license": "MIT", "dependencies": { - "is-core-module": "^2.16.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -12513,25 +9227,34 @@ } }, "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "dev": true, "license": "MIT", "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/restore-cursor/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==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "ISC" + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/retry": { "version": "0.12.0", @@ -12561,20 +9284,18 @@ "license": "MIT" }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "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" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/roarr": { @@ -12597,9 +9318,9 @@ } }, "node_modules/rollup": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", - "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz", + "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12613,28 +9334,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.52.4", - "@rollup/rollup-android-arm64": "4.52.4", - "@rollup/rollup-darwin-arm64": "4.52.4", - "@rollup/rollup-darwin-x64": "4.52.4", - "@rollup/rollup-freebsd-arm64": "4.52.4", - "@rollup/rollup-freebsd-x64": "4.52.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", - "@rollup/rollup-linux-arm-musleabihf": "4.52.4", - "@rollup/rollup-linux-arm64-gnu": "4.52.4", - "@rollup/rollup-linux-arm64-musl": "4.52.4", - "@rollup/rollup-linux-loong64-gnu": "4.52.4", - "@rollup/rollup-linux-ppc64-gnu": "4.52.4", - "@rollup/rollup-linux-riscv64-gnu": "4.52.4", - "@rollup/rollup-linux-riscv64-musl": "4.52.4", - "@rollup/rollup-linux-s390x-gnu": "4.52.4", - "@rollup/rollup-linux-x64-gnu": "4.52.4", - "@rollup/rollup-linux-x64-musl": "4.52.4", - "@rollup/rollup-openharmony-arm64": "4.52.4", - "@rollup/rollup-win32-arm64-msvc": "4.52.4", - "@rollup/rollup-win32-ia32-msvc": "4.52.4", - "@rollup/rollup-win32-x64-gnu": "4.52.4", - "@rollup/rollup-win32-x64-msvc": "4.52.4", + "@rollup/rollup-android-arm-eabi": "4.60.2", + "@rollup/rollup-android-arm64": "4.60.2", + "@rollup/rollup-darwin-arm64": "4.60.2", + "@rollup/rollup-darwin-x64": "4.60.2", + "@rollup/rollup-freebsd-arm64": "4.60.2", + "@rollup/rollup-freebsd-x64": "4.60.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", + "@rollup/rollup-linux-arm-musleabihf": "4.60.2", + "@rollup/rollup-linux-arm64-gnu": "4.60.2", + "@rollup/rollup-linux-arm64-musl": "4.60.2", + "@rollup/rollup-linux-loong64-gnu": "4.60.2", + "@rollup/rollup-linux-loong64-musl": "4.60.2", + "@rollup/rollup-linux-ppc64-gnu": "4.60.2", + "@rollup/rollup-linux-ppc64-musl": "4.60.2", + "@rollup/rollup-linux-riscv64-gnu": "4.60.2", + "@rollup/rollup-linux-riscv64-musl": "4.60.2", + "@rollup/rollup-linux-s390x-gnu": "4.60.2", + "@rollup/rollup-linux-x64-gnu": "4.60.2", + "@rollup/rollup-linux-x64-musl": "4.60.2", + "@rollup/rollup-openbsd-x64": "4.60.2", + "@rollup/rollup-openharmony-arm64": "4.60.2", + "@rollup/rollup-win32-arm64-msvc": "4.60.2", + "@rollup/rollup-win32-ia32-msvc": "4.60.2", + "@rollup/rollup-win32-x64-gnu": "4.60.2", + "@rollup/rollup-win32-x64-msvc": "4.60.2", "fsevents": "~2.3.2" } }, @@ -12661,27 +9385,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -12690,9 +9393,9 @@ "license": "MIT" }, "node_modules/sanitize-filename": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", - "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "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": { @@ -12700,11 +9403,14 @@ } }, "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", "dev": true, - "license": "ISC" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } }, "node_modules/saxes": { "version": "6.0.0", @@ -12729,16 +9435,13 @@ } }, "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "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" - }, - "engines": { - "node": ">=10" } }, "node_modules/semver-compare": { @@ -12766,31 +9469,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/serialize-error/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/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, - "license": "ISC" - }, "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" @@ -12803,6 +9486,7 @@ "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" @@ -12829,14 +9513,14 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "peer": true, "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -12892,16 +9576,11 @@ "license": "ISC" }, "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "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", @@ -12916,14 +9595,32 @@ "node": ">=10" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/simple-update-notifier/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/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", "dev": true, "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, "engines": { - "node": ">=8" + "node": ">=18" } }, "node_modules/slice-ansi": { @@ -12948,41 +9645,12 @@ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, "license": "MIT", + "optional": true, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" } }, - "node_modules/socks": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", - "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ip-address": "^10.0.1", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/sonner": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz", @@ -13023,42 +9691,6 @@ "source-map": "^0.6.0" } }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.22", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", - "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", - "dev": true, - "license": "CC0-1.0" - }, "node_modules/sprintf-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", @@ -13067,65 +9699,6 @@ "license": "BSD-3-Clause", "optional": true }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ssri": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/ssri/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ssri/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/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -13144,22 +9717,12 @@ } }, "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", + "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", "dev": true, "license": "MIT" }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -13174,6 +9737,7 @@ "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", @@ -13184,57 +9748,46 @@ "node": ">=8" } }, - "node_modules/string-width-cjs": { - "name": "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==", + "node_modules/string-width/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": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "ansi-regex": "^5.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==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { - "is-utf8": "^0.2.0" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/strip-indent": { @@ -13250,36 +9803,18 @@ "node": ">=8" } }, - "node_modules/strtok3": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", - "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^4.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", - "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { @@ -13299,35 +9834,6 @@ "node": ">= 6" } }, - "node_modules/sucrase/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sucrase/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -13366,155 +9872,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svg2png": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/svg2png/-/svg2png-4.1.1.tgz", - "integrity": "sha512-9tOp9Ugjlunuf1ugqkhiYboTmTaTI7p48dz5ZjNA5NQJ5xS1NLTZZ1tF8vkJOIBb/ZwxGJsKZvRWqVpo4q9z9Q==", - "dev": true, - "license": "WTFPL", - "dependencies": { - "file-url": "^2.0.0", - "phantomjs-prebuilt": "^2.1.14", - "pn": "^1.0.0", - "yargs": "^6.5.0" - }, - "bin": { - "svg2png": "bin/svg2png-cli.js" - } - }, - "node_modules/svg2png/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg2png/node_modules/camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg2png/node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/svg2png/node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true, - "license": "ISC" - }, - "node_modules/svg2png/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg2png/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg2png/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg2png/node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/svg2png/node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/svg2png/node_modules/yargs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", - "integrity": "sha512-6/QWTdisjnu5UHUzQGst+UOEuEVwIzFVGBjq3jMTFNs5WJQsH/X6nMURSaScIdF5txylr1Ao9bvbWiKi2yXbwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^4.2.0" - } - }, - "node_modules/svg2png/node_modules/yargs-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha512-+QQWqC2xeL0N5/TE+TY6OGEqyNRM+g2/r712PDNYgiCdXYCApXf1vzfmDSLBxfGRwV+moTq/V8FnMI24JCm2Yg==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^3.0.0" - } - }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -13523,9 +9880,9 @@ "license": "MIT" }, "node_modules/tailwind-merge": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz", - "integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.5.0.tgz", + "integrity": "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==", "license": "MIT", "funding": { "type": "github", @@ -13533,9 +9890,9 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.18", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.18.tgz", - "integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", + "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -13578,30 +9935,41 @@ "tailwindcss": ">=3.0.0 || insiders" } }, + "node_modules/tailwindcss/node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", + "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "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": "ISC" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } }, "node_modules/temp": { "version": "0.9.4", @@ -13645,9 +10013,9 @@ } }, "node_modules/temp-file/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "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": { @@ -13667,39 +10035,10 @@ "node": ">= 10.0.0" } }, - "node_modules/temp/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/temp/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/terser": { - "version": "5.44.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", - "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.1.tgz", + "integrity": "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -13743,23 +10082,6 @@ "node": ">=0.8" } }, - "node_modules/throttleit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", - "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/timm": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", - "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==", - "dev": true, - "license": "MIT" - }, "node_modules/tiny-async-pool": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-1.3.0.tgz", @@ -13781,9 +10103,9 @@ } }, "node_modules/tiny-lru": { - "version": "11.4.5", - "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.4.5.tgz", - "integrity": "sha512-hkcz3FjNJfKXjV4mjQ1OrXSLAehg8Hw+cEZclOVT+5c/cWQWImQ9wolzTjth+dmmDe++p3bme3fTxz6Q4Etsqw==", + "version": "11.4.7", + "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.4.7.tgz", + "integrity": "sha512-w/Te7uMUVeH0CR8vZIjr+XiN41V+30lkDdK+NRIDCUYKKuL9VcmaUEmaPISuwGhLlrTGh5yu18lENtR9axSxYw==", "license": "BSD-3-Clause", "engines": { "node": ">=12" @@ -13796,17 +10118,10 @@ "dev": true, "license": "MIT" }, - "node_modules/tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", - "dev": true, - "license": "MIT" - }, "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.1.tgz", + "integrity": "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==", "dev": true, "license": "MIT", "engines": { @@ -13814,14 +10129,13 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -13830,41 +10144,10 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinyglobby/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/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/tinyrainbow": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", - "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { @@ -13872,22 +10155,22 @@ } }, "node_modules/tldts": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.27.tgz", - "integrity": "sha512-I4FZcVFcqCRuT0ph6dCDpPuO4Xgzvh+spkcTr1gK7peIvxWauoloVO0vuy1FQnijT63ss6AsHB6+OIM4aXHbPg==", + "version": "7.0.28", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.28.tgz", + "integrity": "sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.0.27" + "tldts-core": "^7.0.28" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.27.tgz", - "integrity": "sha512-YQ7uPjgWUibIK6DW5lrKujGwUKhLevU4hcGbP5O6TcIUb+oTjJYJVWPS4nZsIHrEEEG6myk/oqAJUEQmpZrHsg==", + "version": "7.0.28", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.28.tgz", + "integrity": "sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ==", "dev": true, "license": "MIT" }, @@ -13923,36 +10206,27 @@ "node": ">=8.0" } }, - "node_modules/token-types": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", - "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, "license": "MIT", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - }, "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "node": ">=6" } }, "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", + "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" + "tldts": "^7.0.5" }, "engines": { - "node": ">=0.8" + "node": ">=16" } }, "node_modules/tr46": { @@ -13990,33 +10264,20 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "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": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, + "license": "(MIT OR CC0-1.0)", + "optional": true, "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "license": "Unlicense" - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, - "license": "MIT" - }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -14031,10 +10292,23 @@ "node": ">=14.17" } }, + "node_modules/uiohook-napi": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/uiohook-napi/-/uiohook-napi-1.5.5.tgz", + "integrity": "sha512-oSlTdnECw2GBfsJPTbBQBeE4v/EXP0EZmX6BJq5nzH/JgFaBE8JpFwEA/kLhiEP7HxQw28FViWiYgdIZzWuuJQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.8.4" + }, + "engines": { + "node": ">= 16" + } + }, "node_modules/undici": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.6.tgz", - "integrity": "sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", "dev": true, "license": "MIT", "engines": { @@ -14042,38 +10316,12 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "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/unique-filename": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", - "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", - "dev": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/unique-slug": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", - "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -14085,9 +10333,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -14196,16 +10444,6 @@ "dev": true, "license": "(WTFPL OR MIT)" }, - "node_modules/utif": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", - "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pako": "^1.0.5" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -14225,17 +10463,6 @@ "uuid": "dist-node/bin/uuid" } }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "node_modules/verror": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", @@ -14253,660 +10480,9 @@ } }, "node_modules/vite": { - "version": "5.4.21", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", - "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-plugin-electron": { - "version": "0.28.8", - "resolved": "https://registry.npmjs.org/vite-plugin-electron/-/vite-plugin-electron-0.28.8.tgz", - "integrity": "sha512-ir+B21oSGK9j23OEvt4EXyco9xDCaF6OGFe0V/8Zc0yL2+HMyQ6mmNQEIhXsEsZCSfIowBpwQBeHH4wVsfraeg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "vite-plugin-electron-renderer": "*" - }, - "peerDependenciesMeta": { - "vite-plugin-electron-renderer": { - "optional": true - } - } - }, - "node_modules/vite-plugin-electron-renderer": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vite-plugin-electron-renderer/-/vite-plugin-electron-renderer-0.14.6.tgz", - "integrity": "sha512-oqkWFa7kQIkvHXG7+Mnl1RTroA4sP0yesKatmAy0gjZC4VwUqlvF9IvOpHd1fpLWsqYX/eZlVxlhULNtaQ78Jw==", - "dev": true, - "license": "MIT" - }, - "node_modules/vitest": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.16.tgz", - "integrity": "sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "4.0.16", - "@vitest/mocker": "4.0.16", - "@vitest/pretty-format": "4.0.16", - "@vitest/runner": "4.0.16", - "@vitest/snapshot": "4.0.16", - "@vitest/spy": "4.0.16", - "@vitest/utils": "4.0.16", - "es-module-lexer": "^1.7.0", - "expect-type": "^1.2.2", - "magic-string": "^0.30.21", - "obug": "^2.1.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "std-env": "^3.10.0", - "tinybench": "^2.9.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tinyrainbow": "^3.0.3", - "vite": "^6.0.0 || ^7.0.0", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@opentelemetry/api": "^1.9.0", - "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.0.16", - "@vitest/browser-preview": "4.0.16", - "@vitest/browser-webdriverio": "4.0.16", - "@vitest/ui": "4.0.16", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@opentelemetry/api": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser-playwright": { - "optional": true - }, - "@vitest/browser-preview": { - "optional": true - }, - "@vitest/browser-webdriverio": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/vitest/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", - "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", - "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", - "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", - "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", - "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/darwin-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", - "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", - "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", - "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", - "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", - "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", - "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-loong64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", - "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", - "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", - "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", - "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-s390x": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", - "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", - "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", - "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", - "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/sunos-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", - "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", - "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", - "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", - "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@vitest/mocker": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.16.tgz", - "integrity": "sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "4.0.16", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0-0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } - } - }, - "node_modules/vitest/node_modules/esbuild": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", - "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.2", - "@esbuild/android-arm": "0.27.2", - "@esbuild/android-arm64": "0.27.2", - "@esbuild/android-x64": "0.27.2", - "@esbuild/darwin-arm64": "0.27.2", - "@esbuild/darwin-x64": "0.27.2", - "@esbuild/freebsd-arm64": "0.27.2", - "@esbuild/freebsd-x64": "0.27.2", - "@esbuild/linux-arm": "0.27.2", - "@esbuild/linux-arm64": "0.27.2", - "@esbuild/linux-ia32": "0.27.2", - "@esbuild/linux-loong64": "0.27.2", - "@esbuild/linux-mips64el": "0.27.2", - "@esbuild/linux-ppc64": "0.27.2", - "@esbuild/linux-riscv64": "0.27.2", - "@esbuild/linux-s390x": "0.27.2", - "@esbuild/linux-x64": "0.27.2", - "@esbuild/netbsd-arm64": "0.27.2", - "@esbuild/netbsd-x64": "0.27.2", - "@esbuild/openbsd-arm64": "0.27.2", - "@esbuild/openbsd-x64": "0.27.2", - "@esbuild/openharmony-arm64": "0.27.2", - "@esbuild/sunos-x64": "0.27.2", - "@esbuild/win32-arm64": "0.27.2", - "@esbuild/win32-ia32": "0.27.2", - "@esbuild/win32-x64": "0.27.2" - } - }, - "node_modules/vitest/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/vitest/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/vitest/node_modules/vite": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", - "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", + "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "dev": true, "license": "MIT", "dependencies": { @@ -14978,6 +10554,133 @@ } } }, + "node_modules/vite-plugin-electron": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/vite-plugin-electron/-/vite-plugin-electron-0.29.1.tgz", + "integrity": "sha512-AejNed5BgHFnuw8h5puTa61C6vdP4ydbsbo/uVjH1fTdHAlCDz1+o6pDQ/scQj1udDrGvH01+vTbzQh/vMnR9w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "vite-plugin-electron-renderer": "*" + }, + "peerDependenciesMeta": { + "vite-plugin-electron-renderer": { + "optional": true + } + } + }, + "node_modules/vite-plugin-electron-renderer": { + "version": "0.14.6", + "resolved": "https://registry.npmjs.org/vite-plugin-electron-renderer/-/vite-plugin-electron-renderer-0.14.6.tgz", + "integrity": "sha512-oqkWFa7kQIkvHXG7+Mnl1RTroA4sP0yesKatmAy0gjZC4VwUqlvF9IvOpHd1fpLWsqYX/eZlVxlhULNtaQ78Jw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/vitest": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.5.tgz", + "integrity": "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.5", + "@vitest/mocker": "4.1.5", + "@vitest/pretty-format": "4.1.5", + "@vitest/runner": "4.1.5", + "@vitest/snapshot": "4.1.5", + "@vitest/spy": "4.1.5", + "@vitest/utils": "4.1.5", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.5", + "@vitest/browser-preview": "4.1.5", + "@vitest/browser-webdriverio": "4.1.5", + "@vitest/coverage-istanbul": "4.1.5", + "@vitest/coverage-v8": "4.1.5", + "@vitest/ui": "4.1.5", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", @@ -14991,16 +10694,6 @@ "node": ">=18" } }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, "node_modules/web-demuxer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/web-demuxer/-/web-demuxer-4.0.0.tgz", @@ -15046,27 +10739,21 @@ } }, "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "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": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "node-which": "bin/node-which" + "node-which": "bin/which.js" }, "engines": { - "node": ">= 8" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true, - "license": "ISC" - }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", @@ -15084,50 +10771,60 @@ "node": ">=8" } }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, "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==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs": { - "name": "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==", + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/wrappy": { @@ -15137,17 +10834,26 @@ "dev": true, "license": "ISC" }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "dev": true, "license": "MIT", - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/xml-name-validator": { @@ -15160,37 +10866,6 @@ "node": ">=18" } }, - "node_modules/xml-parse-from-string": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", - "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xml2js/node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, "node_modules/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", @@ -15208,16 +10883,6 @@ "dev": true, "license": "MIT" }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -15236,9 +10901,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "devOptional": true, "license": "ISC", "bin": { diff --git a/package.json b/package.json index c367f9e..2709d3e 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,10 @@ "node": "22.22.1", "npm": "10.9.4" }, + "author": { + "name": "Sid", + "email": "svaddem@asu.edu" + }, "scripts": { "dev": "vite", "build": "tsc && vite build && electron-builder", @@ -18,12 +22,16 @@ "preview": "vite preview", "build:mac": "tsc && vite build && electron-builder --mac", "build:win": "tsc && vite build && electron-builder --win", - "build:linux": "tsc && vite build && electron-builder --linux", + "build:linux": "tsc && vite build && electron-builder --linux AppImage deb", "test": "vitest --run", "test:watch": "vitest", "build-vite": "tsc && vite build", + "test:browser": "vitest --config vitest.browser.config.ts --run", + "test:browser:install": "playwright install --with-deps chromium-headless-shell", "test:e2e": "playwright test", - "prepare": "husky" + "prepare": "husky", + "rebuild:native": "node ./node_modules/@electron/rebuild/lib/cli.js --force --only uiohook-napi", + "postinstall": "npm run rebuild:native" }, "dependencies": { "@fix-webm-duration/fix": "^1.0.1", @@ -34,67 +42,70 @@ "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slider": "^1.3.6", - "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-toggle": "^1.1.10", "@radix-ui/react-toggle-group": "^1.1.11", "@radix-ui/react-tooltip": "^1.2.8", "@types/gif.js": "^0.2.5", - "@uiw/color-convert": "^2.9.2", - "@uiw/react-color-block": "^2.9.2", + "@uiw/color-convert": "^2.10.1", + "@uiw/react-color-block": "^2.10.1", + "@uiw/react-color-colorful": "^2.9.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "dnd-timeline": "^2.2.0", - "emoji-picker-react": "^4.16.1", + "dnd-timeline": "^2.4.0", + "emoji-picker-react": "^4.18.0", "fix-webm-duration": "^1.0.6", "gif.js": "^0.2.0", - "gsap": "^3.13.0", + "gsap": "^3.15.0", "lucide-react": "^0.545.0", - "mediabunny": "^1.25.1", - "motion": "^12.23.24", - "mp4box": "^2.2.0", + "mediabunny": "^1.40.1", + "motion": "^12.38.0", + "mp4box": "^2.3.0", "pixi-filters": "^6.1.5", - "pixi.js": "^8.14.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-icons": "^5.5.0", + "pixi.js": "^8.18.1", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-icons": "^5.6.0", "react-resizable-panels": "^3.0.6", - "react-rnd": "^10.5.2", + "react-rnd": "^10.5.3", "sonner": "^2.0.7", - "tailwind-merge": "^3.3.1", + "tailwind-merge": "^3.5.0", "tailwindcss-animate": "^1.0.7", + "uiohook-napi": "^1.5.5", "uuid": "^13.0.0", "web-demuxer": "^4.0.0" }, "devDependencies": { - "@biomejs/biome": "^2.3.13", - "@playwright/test": "^1.58.2", + "@biomejs/biome": "^2.4.12", + "@electron/rebuild": "^4.0.4", + "@playwright/test": "^1.59.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", - "@types/node": "^25.0.3", - "@types/react": "^18.2.64", - "@types/react-dom": "^18.2.21", - "@types/uuid": "^10.0.0", - "@vitejs/plugin-react": "^4.2.1", - "autoprefixer": "^10.4.21", - "electron": "^39.2.7", - "electron-builder": "^26.7.0", - "electron-icon-builder": "^2.0.1", - "electron-rebuild": "^3.2.9", - "fast-check": "^4.5.2", + "@types/node": "^22.19.17", + "@types/react": "^18.3.28", + "@types/react-dom": "^18.3.7", + "@vitejs/plugin-react": "^5.2.0", + "@vitest/browser": "^4.1.4", + "@vitest/browser-playwright": "^4.1.4", + "autoprefixer": "^10.5.0", + "electron": "^41.2.1", + "electron-builder": "^26.8.1", + "esbuild": "^0.27.0", + "fast-check": "^4.7.0", "husky": "^9.1.7", - "jsdom": "^29.0.1", - "lint-staged": "^16.3.2", - "postcss": "^8.5.6", - "tailwindcss": "^3.4.18", - "terser": "^5.44.1", - "typescript": "^5.2.2", - "vite": "^5.1.6", - "vite-plugin-electron": "^0.28.6", - "vite-plugin-electron-renderer": "^0.14.5", - "vitest": "^4.0.16" + "jsdom": "^29.0.2", + "lint-staged": "^16.4.0", + "postcss": "^8.5.10", + "tailwindcss": "^3.4.19", + "terser": "^5.46.1", + "typescript": "^5.9.3", + "vite": "^7.3.2", + "vite-plugin-electron": "^0.29.1", + "vite-plugin-electron-renderer": "^0.14.6", + "vitest": "^4.1.4" }, "main": "dist-electron/main.js", "lint-staged": { diff --git a/scripts/build_macos.sh b/scripts/build_macos.sh new file mode 100755 index 0000000..bd35710 --- /dev/null +++ b/scripts/build_macos.sh @@ -0,0 +1,216 @@ +#!/bin/bash +# +# OpenScreen macOS Build Script +# Produces: release//OpenScreen-Mac--.dmg +# +# Usage: chmod +x scripts/build_macos.sh && ./scripts/build_macos.sh +# + +set -euo pipefail + +# ── Load .env ───────────────────────────────────────────────────────── +PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +ENV_FILE="${PROJECT_ROOT}/.env" + +if [ -f "$ENV_FILE" ]; then + set -a + source "$ENV_FILE" + set +a +else + echo "ERROR: .env file not found at ${ENV_FILE}" + echo "Create one with APP_NAME, SIGN_IDENTITY, NOTARY_PROFILE, etc." + exit 1 +fi + +# ── Config ──────────────────────────────────────────────────────────── +VERSION=$(node -p "require('${PROJECT_ROOT}/package.json').version") +RELEASE_DIR="${PROJECT_ROOT}/release/${VERSION}" +ENTITLEMENTS="${PROJECT_ROOT}/macos.entitlements" +ARCHS=("arm64" "x64") + +# ── Colors ──────────────────────────────────────────────────────────── +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color +BOLD='\033[1m' + +print_step() { echo -e "\n${CYAN}${BOLD}▸ $1${NC}"; } +print_ok() { echo -e "${GREEN}✓ $1${NC}"; } +print_warn() { echo -e "${YELLOW}⚠ $1${NC}"; } +print_err() { echo -e "${RED}✗ $1${NC}"; } + +# ── Preflight ───────────────────────────────────────────────────────── +echo -e "\n${BOLD}╔══════════════════════════════════════════╗${NC}" +echo -e "${BOLD}║ ${APP_NAME} macOS Build Script v${VERSION} ║${NC}" +echo -e "${BOLD}╚══════════════════════════════════════════╝${NC}" + +print_step "Checking prerequisites..." + +if [[ "$(uname)" != "Darwin" ]]; then + print_err "This script must be run on macOS." + exit 1 +fi +print_ok "Running on macOS ($(uname -m))" + +if ! command -v node &> /dev/null; then + print_err "Node.js not found. Please install Node.js first." + exit 1 +fi +print_ok "Node.js found: $(node -v)" + +if ! command -v npm &> /dev/null; then + print_err "npm not found." + exit 1 +fi +print_ok "npm found: $(npm -v)" + +# Check signing identity +if ! security find-identity -v -p codesigning | grep -q "$SIGN_IDENTITY"; then + print_err "Signing identity not found: ${SIGN_IDENTITY}" + print_err "Run 'security find-identity -v -p codesigning' to see available identities." + exit 1 +fi +print_ok "Signing identity found: ${SIGN_IDENTITY}" + +# Check notary profile +if ! xcrun notarytool history --keychain-profile "$NOTARY_PROFILE" &> /dev/null; then + print_err "Notary profile '${NOTARY_PROFILE}' not found in keychain." + print_err "Run: xcrun notarytool store-credentials \"${NOTARY_PROFILE}\" --apple-id \"${APPLE_ID}\" --team-id \"${TEAM_ID}\"" + exit 1 +fi +print_ok "Notary profile found: ${NOTARY_PROFILE}" + +# Check entitlements +if [ ! -f "$ENTITLEMENTS" ]; then + print_err "Entitlements file not found: ${ENTITLEMENTS}" + exit 1 +fi +print_ok "Entitlements file found" + +# ── Clean ───────────────────────────────────────────────────────────── +cd "$PROJECT_ROOT" + +print_step "Cleaning previous build artifacts..." +rm -rf dist dist-electron "${RELEASE_DIR}" +print_ok "Clean complete" + +# ── Install Dependencies ───────────────────────────────────────────── +print_step "Installing dependencies..." +npm ci +print_ok "Dependencies installed" + +# ── Build Vite + Electron ──────────────────────────────────────────── +print_step "Building Vite + Electron... (this may take a minute)" +npx tsc && npx vite build +print_ok "Vite + Electron build complete" + +# ── Package, Sign, Notarize per Architecture ───────────────────────── +for ARCH in "${ARCHS[@]}"; do + echo "" + echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" + echo -e "${BOLD} Building for: ${ARCH}${NC}" + echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" + + # ── Package with electron-builder ───────────────────────────── + print_step "[${ARCH}] Packaging with electron-builder..." + + # Build .app only (--dir), electron-builder handles codesigning + # with hardenedRuntime + entitlements from electron-builder.json5 + CSC_NAME="$CSC_NAME" npx electron-builder --mac --${ARCH} --dir + + # Find the .app bundle + APP_BUNDLE=$(find "${RELEASE_DIR}" -maxdepth 2 -name "*.app" -type d | grep -i "${ARCH}\|mac" | head -n1) + if [ -z "$APP_BUNDLE" ]; then + # Fallback: find any .app in the output + APP_BUNDLE=$(find "${RELEASE_DIR}" -maxdepth 2 -name "*.app" -type d | head -n1) + fi + + if [ -z "$APP_BUNDLE" ]; then + print_err "[${ARCH}] Could not find .app bundle in ${RELEASE_DIR}" + exit 1 + fi + print_ok "[${ARCH}] App bundle: $(basename "$APP_BUNDLE")" + + # ── Verify codesign on .app ─────────────────────────────────── + print_step "[${ARCH}] Verifying .app code signature..." + codesign --verify --deep --strict "$APP_BUNDLE" 2>&1 || print_warn "[${ARCH}] Deep verify had warnings (may be expected pre-notarization)" + print_ok "[${ARCH}] .app signature verified" + + # ── Create DMG ──────────────────────────────────────────────── + DMG_NAME="${APP_NAME}-Mac-${ARCH}-${VERSION}.dmg" + DMG_OUTPUT="${RELEASE_DIR}/${DMG_NAME}" + DMG_STAGING="${RELEASE_DIR}/dmg-staging-${ARCH}" + + print_step "[${ARCH}] Creating DMG..." + + rm -f "$DMG_OUTPUT" + rm -rf "$DMG_STAGING" + + # Stage: app + Applications shortcut for drag-to-install + mkdir -p "$DMG_STAGING" + cp -R "$APP_BUNDLE" "$DMG_STAGING/" + ln -s /Applications "$DMG_STAGING/Applications" + + hdiutil create \ + -srcfolder "$DMG_STAGING" \ + -volname "${APP_NAME}" \ + -fs HFS+ \ + -fsargs "-c c=64,a=16,e=16" \ + -format UDBZ \ + "$DMG_OUTPUT" + + print_ok "[${ARCH}] DMG created: ${DMG_NAME}" + rm -rf "$DMG_STAGING" + + # ── Sign DMG ────────────────────────────────────────────────── + print_step "[${ARCH}] Signing DMG..." + codesign --force --sign "$SIGN_IDENTITY" --timestamp "$DMG_OUTPUT" + print_ok "[${ARCH}] DMG signed" + + # ── Notarize DMG ────────────────────────────────────────────── + print_step "[${ARCH}] Notarizing DMG with Apple... (this may take several minutes)" + xcrun notarytool submit "$DMG_OUTPUT" \ + --keychain-profile "$NOTARY_PROFILE" \ + --wait + print_ok "[${ARCH}] DMG notarized" + + # ── Staple ──────────────────────────────────────────────────── + print_step "[${ARCH}] Stapling notarization ticket..." + xcrun stapler staple "$DMG_OUTPUT" + print_ok "[${ARCH}] Ticket stapled" + + # ── Validate ────────────────────────────────────────────────── + print_step "[${ARCH}] Validating stapled DMG..." + xcrun stapler validate "$DMG_OUTPUT" + print_ok "[${ARCH}] Validation passed" + +done + +# ── Clean up unpacked dirs (keep only DMGs) ─────────────────────────── +print_step "Cleaning up intermediate directories..." +find "${RELEASE_DIR}" -maxdepth 1 -type d ! -name "$(basename "$RELEASE_DIR")" -exec rm -rf {} + 2>/dev/null || true +print_ok "Cleanup complete" + +# ── Done ────────────────────────────────────────────────────────────── +echo "" +echo -e "${GREEN}${BOLD}════════════════════════════════════════════${NC}" +echo -e "${GREEN}${BOLD} Build & Notarization Complete!${NC}" +echo -e "${GREEN}${BOLD}════════════════════════════════════════════${NC}" +echo "" + +for ARCH in "${ARCHS[@]}"; do + DMG_NAME="${APP_NAME}-Mac-${ARCH}-${VERSION}.dmg" + DMG_PATH="${RELEASE_DIR}/${DMG_NAME}" + if [ -f "$DMG_PATH" ]; then + DMG_SIZE=$(du -h "$DMG_PATH" | cut -f1) + echo -e " 📦 ${BOLD}${ARCH}:${NC} ${DMG_PATH}" + echo -e " 📏 ${BOLD}Size:${NC} ${DMG_SIZE}" + echo "" + fi +done + +echo -e " ${GREEN}All DMGs are fully signed, notarized, and stapled!${NC}" +echo -e " ${GREEN}Ready for distribution outside the Mac App Store.${NC}" +echo "" diff --git a/scripts/i18n-check.mjs b/scripts/i18n-check.mjs index 3fd0331..b37af68 100644 --- a/scripts/i18n-check.mjs +++ b/scripts/i18n-check.mjs @@ -1,17 +1,15 @@ #!/usr/bin/env node /** * Validates that all locale translation files have identical key structures. - * Compares zh-CN and es against the en baseline for every namespace. + * Compares all locale folders (except en) against the en baseline for every namespace. * * Usage: node scripts/i18n-check.mjs */ - import fs from "node:fs"; import path from "node:path"; const LOCALES_DIR = path.resolve("src/i18n/locales"); const BASE_LOCALE = "en"; -const COMPARE_LOCALES = ["zh-CN", "es"]; function getKeys(obj, prefix = "") { const keys = []; @@ -34,12 +32,19 @@ const namespaces = fs .filter((f) => f.endsWith(".json")) .map((f) => f.replace(".json", "")); +const compareLocales = fs + .readdirSync(LOCALES_DIR, { withFileTypes: true }) + .filter((entry) => entry.isDirectory()) + .map((entry) => entry.name) + .filter((locale) => locale !== BASE_LOCALE) + .sort((a, b) => a.localeCompare(b)); + for (const namespace of namespaces) { const basePath = path.join(baseDir, `${namespace}.json`); const baseData = JSON.parse(fs.readFileSync(basePath, "utf-8")); const baseKeys = getKeys(baseData); - for (const locale of COMPARE_LOCALES) { + for (const locale of compareLocales) { const localePath = path.join(LOCALES_DIR, locale, `${namespace}.json`); if (!fs.existsSync(localePath)) { @@ -77,6 +82,6 @@ if (hasErrors) { process.exit(1); } else { console.log( - `i18n check PASSED — all ${COMPARE_LOCALES.length} locales match ${BASE_LOCALE} across ${namespaces.length} namespaces.`, + `i18n check PASSED — all ${compareLocales.length} locales match ${BASE_LOCALE} across ${namespaces.length} namespaces.`, ); } diff --git a/src/App.tsx b/src/App.tsx index 985ecc7..f5fa7d6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from "react"; +import { CountdownOverlay } from "./components/launch/CountdownOverlay.tsx"; import { LaunchWindow } from "./components/launch/LaunchWindow"; import { SourceSelector } from "./components/launch/SourceSelector"; import { Toaster } from "./components/ui/sonner"; @@ -9,22 +10,24 @@ import { ShortcutsProvider } from "./contexts/ShortcutsContext"; import { loadAllCustomFonts } from "./lib/customFonts"; export default function App() { - const [windowType, setWindowType] = useState(""); + const [windowType, setWindowType] = useState( + () => new URLSearchParams(window.location.search).get("windowType") || "", + ); useEffect(() => { - const params = new URLSearchParams(window.location.search); - const type = params.get("windowType") || ""; - setWindowType(type); - if (type === "hud-overlay" || type === "source-selector") { + const type = new URLSearchParams(window.location.search).get("windowType") || ""; + if (type !== windowType) { + setWindowType(type); + } + + if (type === "hud-overlay" || type === "source-selector" || type === "countdown-overlay") { document.body.style.background = "transparent"; document.documentElement.style.background = "transparent"; document.getElementById("root")?.style.setProperty("background", "transparent"); } - // HUD window is a small fixed-size BrowserWindow (`electron/windows.ts`), not a full-screen - // surface. Pin the document shell to that viewport and hide overflow so the renderer cannot - // introduce scrollbars. Without this, `h-full` in `LaunchWindow` has no definite height chain - // from `html`/`body`, and stray overflow can still appear on some hosts (see issue #305). + // HUD is a fixed-size BrowserWindow; pin the document shell and hide overflow + // so the renderer can't introduce scrollbars (see issue #305). if (type === "hud-overlay") { document.documentElement.style.height = "100%"; document.documentElement.style.overflow = "hidden"; @@ -36,7 +39,9 @@ export default function App() { root?.style.setProperty("min-height", "0"); root?.style.setProperty("overflow", "hidden"); } + }, [windowType]); + useEffect(() => { // Load custom fonts on app initialization loadAllCustomFonts().catch((error) => { console.error("Failed to load custom fonts:", error); @@ -49,6 +54,8 @@ export default function App() { return ; case "source-selector": return ; + case "countdown-overlay": + return ; case "editor": return ( diff --git a/src/components/launch/CountdownOverlay.tsx b/src/components/launch/CountdownOverlay.tsx new file mode 100644 index 0000000..71d12c5 --- /dev/null +++ b/src/components/launch/CountdownOverlay.tsx @@ -0,0 +1,30 @@ +import { useEffect, useState } from "react"; + +export function CountdownOverlay() { + const [value, setValue] = useState(null); + + useEffect(() => { + const unsubscribe = window.electronAPI.onCountdownOverlayValue((nextValue) => { + setValue(nextValue); + }); + + return () => unsubscribe(); + }, []); + + if (value === null) { + return null; + } + + return ( +
+
+
+ {value} +
+
+
+ ); +} diff --git a/src/components/launch/LaunchWindow.module.css b/src/components/launch/LaunchWindow.module.css index ff68c3d..132fa0a 100644 --- a/src/components/launch/LaunchWindow.module.css +++ b/src/components/launch/LaunchWindow.module.css @@ -6,3 +6,78 @@ .electronNoDrag { -webkit-app-region: no-drag; } + +.languageMenuScroll { + max-height: 16rem; + overflow-y: auto; + overflow-x: hidden; + overscroll-behavior: contain; + touch-action: pan-y; + -webkit-overflow-scrolling: touch; +} + +.languageMenuScroll::-webkit-scrollbar { + width: 8px; +} + +.languageMenuScroll::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.04); + border-radius: 999px; +} + +.languageMenuScroll::-webkit-scrollbar-thumb { + background: linear-gradient(180deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0.2)); + border-radius: 999px; + border: 1px solid rgba(255, 255, 255, 0.15); +} + +.languageMenuScroll::-webkit-scrollbar-thumb:hover { + background: linear-gradient(180deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.3)); +} + +.languageMenuContainer { + position: relative; + z-index: 20; +} + +.languageMenuPanel { + position: fixed; + right: 0; + top: 0; + width: 12rem; + padding: 0.375rem; + border-radius: 0.75rem; + border: 1px solid rgba(255, 255, 255, 0.14); + background: linear-gradient(160deg, rgba(28, 29, 42, 0.98), rgba(18, 19, 28, 0.98)); + box-shadow: 0 20px 45px rgba(0, 0, 0, 0.55); + backdrop-filter: blur(14px); + pointer-events: auto; + box-sizing: border-box; +} + +.languageMenuItem { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.5rem 0.625rem; + border-radius: 0.5rem; + font-size: 11px; + color: rgba(255, 255, 255, 0.88); + background: transparent; + border: 0; + cursor: pointer; + transition: background-color 120ms ease, color 120ms ease; +} + +.languageMenuItem:hover, +.languageMenuItem:focus-visible { + background: rgba(255, 255, 255, 0.1); + color: #ffffff; + outline: none; +} + +.languageMenuItemActive { + background: rgba(255, 255, 255, 0.12); + color: #ffffff; +} diff --git a/src/components/launch/LaunchWindow.tsx b/src/components/launch/LaunchWindow.tsx index 5c5ec92..bffbd9c 100644 --- a/src/components/launch/LaunchWindow.tsx +++ b/src/components/launch/LaunchWindow.tsx @@ -1,10 +1,12 @@ -import { ChevronDown, Languages } from "lucide-react"; -import { useEffect, useState } from "react"; -import { BsRecordCircle } from "react-icons/bs"; +import { Check, ChevronDown, Languages } from "lucide-react"; +import { useEffect, useRef, useState } from "react"; +import { createPortal } from "react-dom"; +import { BsPauseCircle, BsPlayCircle, BsRecordCircle } from "react-icons/bs"; import { FaRegStopCircle } from "react-icons/fa"; import { FaFolderOpen } from "react-icons/fa6"; import { FiMinus, FiX } from "react-icons/fi"; import { + MdCancel, MdMic, MdMicOff, MdMonitor, @@ -17,9 +19,7 @@ import { } from "react-icons/md"; import { RxDragHandleDots2 } from "react-icons/rx"; import { useI18n, useScopedT } from "@/contexts/I18nContext"; -import { type Locale, SUPPORTED_LOCALES } from "@/i18n/config"; -import { getLocaleName } from "@/i18n/loader"; -import { isMac as getIsMac } from "@/utils/platformUtils"; +import { getAvailableLocales, getLocaleName } from "@/i18n/loader"; import { useAudioLevelMeter } from "../../hooks/useAudioLevelMeter"; import { useCameraDevices } from "../../hooks/useCameraDevices"; import { useMicrophoneDevices } from "../../hooks/useMicrophoneDevices"; @@ -27,6 +27,7 @@ import { useScreenRecorder } from "../../hooks/useScreenRecorder"; import { requestCameraAccess } from "../../lib/requestCameraAccess"; import { formatTimePadded } from "../../utils/timeUtils"; import { AudioLevelMeter } from "../ui/audio-level-meter"; +import { Button } from "../ui/button"; import { Tooltip } from "../ui/tooltip"; import styles from "./LaunchWindow.module.css"; @@ -41,8 +42,11 @@ const ICON_CONFIG = { micOff: { icon: MdMicOff, size: ICON_SIZE }, webcamOn: { icon: MdVideocam, size: ICON_SIZE }, webcamOff: { icon: MdVideocamOff, size: ICON_SIZE }, + pause: { icon: BsPauseCircle, size: ICON_SIZE }, + resume: { icon: BsPlayCircle, size: ICON_SIZE }, stop: { icon: FaRegStopCircle, size: ICON_SIZE }, restart: { icon: MdRestartAlt, size: ICON_SIZE }, + cancel: { icon: MdCancel, size: ICON_SIZE }, record: { icon: BsRecordCircle, size: ICON_SIZE }, videoFile: { icon: MdVideoFile, size: ICON_SIZE }, folder: { icon: FaFolderOpen, size: ICON_SIZE }, @@ -63,22 +67,35 @@ const hudGroupClasses = const hudIconBtnClasses = "flex items-center justify-center p-2 rounded-full transition-all duration-150 cursor-pointer text-white hover:bg-white/10 hover:scale-[1.08] active:scale-95"; +const hudAuxIconBtnClasses = + "flex items-center justify-center p-1.5 rounded-full transition-colors duration-150 text-white/55 hover:bg-white/10 disabled:opacity-30 disabled:cursor-not-allowed"; + const windowBtnClasses = "flex items-center justify-center p-2 rounded-full transition-all duration-150 cursor-pointer opacity-50 hover:opacity-90 hover:bg-white/[0.08]"; +const hudSidebarClasses = "ml-0.5 pl-1.5 border-l border-white/10 flex items-center gap-0.5"; + export function LaunchWindow() { const t = useScopedT("launch"); - const { locale, setLocale } = useI18n(); - const [isMac, setIsMac] = useState(false); - - useEffect(() => { - getIsMac().then(setIsMac); - }, []); + const availableLocales = getAvailableLocales(); + const { + locale, + setLocale, + systemLocaleSuggestion, + acceptSystemLocaleSuggestion, + dismissSystemLocaleSuggestion, + resolveSystemLocaleSuggestion, + } = useI18n(); + const suggestedLanguageName = systemLocaleSuggestion ? getLocaleName(systemLocaleSuggestion) : ""; const { recording, + paused, + elapsedSeconds, toggleRecording, + togglePaused, restartRecording, + cancelRecording, microphoneEnabled, setMicrophoneEnabled, microphoneDeviceId, @@ -90,8 +107,6 @@ export function LaunchWindow() { webcamDeviceId, setWebcamDeviceId, } = useScreenRecorder(); - const [recordingStart, setRecordingStart] = useState(null); - const [elapsed, setElapsed] = useState(0); const showMicControls = microphoneEnabled && !recording; const showWebcamControls = webcamEnabled && !recording; @@ -103,6 +118,18 @@ export function LaunchWindow() { const [isWebcamHovered, setIsWebcamHovered] = useState(false); const [isWebcamFocused, setIsWebcamFocused] = useState(false); const webcamExpanded = isWebcamHovered || isWebcamFocused; + const [isLanguageMenuOpen, setIsLanguageMenuOpen] = useState(false); + const languageTriggerRef = useRef(null); + const languageMenuPanelRef = useRef(null); + const [languageMenuStyle, setLanguageMenuStyle] = useState<{ + right: number; + top: number; + maxHeight: number; + }>({ + right: 12, + top: 12, + maxHeight: 240, + }); const { devices: micDevices, @@ -146,25 +173,6 @@ export function LaunchWindow() { } }, [selectedCameraId, setWebcamDeviceId]); - useEffect(() => { - let timer: NodeJS.Timeout | null = null; - if (recording) { - if (!recordingStart) setRecordingStart(Date.now()); - timer = setInterval(() => { - if (recordingStart) { - setElapsed(Math.floor((Date.now() - recordingStart) / 1000)); - } - }, 1000); - } else { - setRecordingStart(null); - setElapsed(0); - if (timer) clearInterval(timer); - } - return () => { - if (timer) clearInterval(timer); - }; - }, [recording, recordingStart]); - useEffect(() => { if (!import.meta.env.DEV) { return; @@ -175,6 +183,71 @@ export function LaunchWindow() { }); }, []); + useEffect(() => { + if (!isLanguageMenuOpen) return; + + const handlePointerDown = (event: PointerEvent) => { + const target = event.target as Node; + const clickedTrigger = languageTriggerRef.current?.contains(target); + const clickedMenu = languageMenuPanelRef.current?.contains(target); + if (!clickedTrigger && !clickedMenu) { + setIsLanguageMenuOpen(false); + } + }; + + const handleEscape = (event: KeyboardEvent) => { + if (event.key === "Escape") { + setIsLanguageMenuOpen(false); + } + }; + + window.addEventListener("pointerdown", handlePointerDown); + window.addEventListener("keydown", handleEscape); + + return () => { + window.removeEventListener("pointerdown", handlePointerDown); + window.removeEventListener("keydown", handleEscape); + }; + }, [isLanguageMenuOpen]); + + useEffect(() => { + if (!isLanguageMenuOpen || !languageTriggerRef.current) return; + + const updatePosition = () => { + if (!languageTriggerRef.current) return; + const rect = languageTriggerRef.current.getBoundingClientRect(); + const gap = 8; + const viewportPadding = 8; + const availableHeight = Math.max(80, rect.top - viewportPadding - gap); + const top = Math.max(viewportPadding, rect.top - gap - availableHeight); + + setLanguageMenuStyle({ + right: Math.max(viewportPadding, window.innerWidth - rect.right), + top, + maxHeight: availableHeight, + }); + }; + + updatePosition(); + window.addEventListener("resize", updatePosition); + window.addEventListener("scroll", updatePosition, true); + + return () => { + window.removeEventListener("resize", updatePosition); + window.removeEventListener("scroll", updatePosition, true); + }; + }, [isLanguageMenuOpen]); + + useEffect(() => { + if (!isLanguageMenuOpen || !languageMenuPanelRef.current) return; + const id = requestAnimationFrame(() => { + if (languageMenuPanelRef.current) { + languageMenuPanelRef.current.scrollTop = 0; + } + }); + return () => cancelAnimationFrame(id); + }, [isLanguageMenuOpen]); + const [selectedSource, setSelectedSource] = useState("Screen"); const [hasSelectedSource, setHasSelectedSource] = useState(false); @@ -241,30 +314,48 @@ export function LaunchWindow() { }; return ( - // Root fills the HUD window only. Avoid `w-screen`/`h-screen` (`100vw`/`100vh`): `100vw` can - // exceed the inner layout width when scrollbars affect the viewport (notably on Windows), which - // showed up as a horizontal scrollbar once recording widened the toolbar (issue #305). + // Root fills the HUD window only. Avoid w-screen/h-screen (100vw/100vh): + // 100vw can exceed the inner layout width when scrollbars affect the + // viewport (notably on Windows), causing a horizontal scrollbar once the + // recording toolbar widened (issue #305).
- {/* Language switcher — top-left, beside traffic lights */} -
- - -
+
+ {t("systemLanguagePrompt.title")} +
+
+ {t("systemLanguagePrompt.description", { + language: suggestedLanguageName, + })} +
+
+ + +
+
+ )} {/* Device selectors — fixed above HUD bar, viewport-relative, never clipped */} {(showMicControls || showWebcamControls) && ( @@ -441,6 +532,7 @@ export function LaunchWindow() { onClick={async () => { await setWebcamEnabled(!webcamEnabled); }} + disabled={recording} title={webcamEnabled ? t("webcam.disableWebcam") : t("webcam.enableWebcam")} > {webcamEnabled @@ -451,75 +543,151 @@ export function LaunchWindow() { {/* Record/Stop group */} - {/* Restart recording */} {recording && ( - - - + + + + + + + + + )} - {/* Open video file */} - - - + {!recording && ( + <> + {/* Open video file */} + + + - {/* Open project */} - - - + {/* Open project */} + + + + + )} - {/* Window controls */} -
- - + {/* Right sidebar controls */} +
+
+ +
+ + {isLanguageMenuOpen + ? createPortal( +
event.stopPropagation()} + > + {availableLocales.map((loc) => ( + + ))} +
, + document.body, + ) + : null} + + {/* Window controls */} +
+ + +
diff --git a/src/components/launch/SourceSelector.module.css b/src/components/launch/SourceSelector.module.css index 51239ac..48d5507 100644 --- a/src/components/launch/SourceSelector.module.css +++ b/src/components/launch/SourceSelector.module.css @@ -2,15 +2,21 @@ background: linear-gradient(135deg, rgba(28, 28, 34, 0.92) 0%, rgba(18, 18, 22, 0.88) 100%); backdrop-filter: blur(20px) saturate(160%); -webkit-backdrop-filter: blur(20px) saturate(160%); - border-radius: 14px; - box-shadow: - 0 4px 16px 0 rgba(0, 0, 0, 0.32), - 0 1px 3px 0 rgba(0, 0, 0, 0.18) inset; - border: 1px solid rgba(60, 60, 80, 0.18); + border-radius: 30px; + corner-shape: squircle; + /* + Removed box-shadow here because electron doesn't round corners of the shadow, thereby leaving a square border shadow conflicting with the rounded corners of the SourceSelector. + The result is easily visible when you place a white window just behind the SourceSelector + */ + /* box-shadow: + 0 0px 16px 0 rgba(0, 0, 0, 0.32), + 0 1px 3px 0 rgba(0, 0, 0, 0.18) inset; */ + border: 1.5px solid rgba(60, 60, 80, 0.3); } .sourceCard { - border-radius: 12px; + corner-shape: squircle; + border-radius: 20px; background: linear-gradient(120deg, rgba(38, 38, 48, 0.98) 0%, rgba(24, 24, 32, 0.96) 100%); border: 1px solid rgba(60, 60, 80, 0.22); box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.18); @@ -28,7 +34,7 @@ } .selected { - border: 2px solid #34b27b; + border: 1.5px solid #34b27b; background: linear-gradient(120deg, rgba(52, 178, 123, 0.08) 0%, rgba(38, 38, 48, 0.98) 100%); box-shadow: 0 0 12px rgba(52, 178, 123, 0.15), @@ -70,30 +76,27 @@ } /* scrollbar */ -.sourceGridScroll { - scrollbar-width: thin; - scrollbar-color: rgba(52, 178, 123, 0.5) rgba(40, 40, 50, 0.6); -} .sourceGridScroll::-webkit-scrollbar { - width: 8px; + width: 3px; } .sourceGridScroll::-webkit-scrollbar-track { - background: rgba(30, 30, 38, 0.5); + background: rgba(30, 30, 38, 0.3); border-radius: 4px; - margin: 4px 0; } .sourceGridScroll::-webkit-scrollbar-thumb { - background: rgba(80, 80, 100, 0.6); - border-radius: 4px; + background: rgba(52, 178, 123, 0.5); + border-radius: 10px; } .sourceGridScroll::-webkit-scrollbar-thumb:hover { background: rgba(52, 178, 123, 0.6); + cursor: grab; } .sourceGridScroll::-webkit-scrollbar-thumb:active { background: rgba(52, 178, 123, 0.8); + cursor: grabbing; } diff --git a/src/components/launch/SourceSelector.tsx b/src/components/launch/SourceSelector.tsx index 5768c3a..a2aec55 100644 --- a/src/components/launch/SourceSelector.tsx +++ b/src/components/launch/SourceSelector.tsx @@ -65,7 +65,7 @@ export function SourceSelector() { style={{ minHeight: "100vh" }} >
-
+

{t("sourceSelector.loading")}

@@ -84,10 +84,10 @@ export function SourceSelector() { {source.name} {isSelected && ( -
+
@@ -111,16 +111,16 @@ export function SourceSelector() { defaultValue={screenSources.length === 0 ? "windows" : "screens"} className="flex-1 flex flex-col" > - + {t("sourceSelector.screens", { count: String(screenSources.length) })} {t("sourceSelector.windows", { count: String(windowSources.length) })} @@ -128,14 +128,14 @@ export function SourceSelector() {
{screenSources.map(renderSourceCard)}
{windowSources.map(renderSourceCard)}
@@ -143,18 +143,18 @@ export function SourceSelector() {
-
+
diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx index 85336fd..22456b2 100644 --- a/src/components/ui/accordion.tsx +++ b/src/components/ui/accordion.tsx @@ -52,4 +52,4 @@ const AccordionContent = React.forwardRef< )); AccordionContent.displayName = AccordionPrimitive.Content.displayName; -export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; +export { Accordion, AccordionContent, AccordionItem, AccordionTrigger }; diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index 2935ed4..0480764 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -52,4 +52,4 @@ const CardFooter = React.forwardRef void; +}; + +type ColorPickerProps = + | (BaseProps & { + clearBackgroundOption?: false; + translations: Record<"colorWheel" | "colorPalette", string>; + }) + | (BaseProps & { + clearBackgroundOption: true; + translations: Record<"colorWheel" | "colorPalette" | "clearBackground", string>; + }); + +export default function ColorPicker(props: ColorPickerProps) { + const { selectedColor, colorPalette, translations, onUpdateColor } = props; + const [colorMode, setColorMode] = useState<"wheel" | "palette">("wheel"); + const [hexInput, setHexInput] = useState(selectedColor); + const [transparentColorHSVA, setTransparentColorHSVA] = useState({ + h: 0, + s: 0, + v: 0, + a: 0, + }); + + useEffect(() => { + setHexInput(selectedColor); + }, [selectedColor]); + + const getTextColor = (color: string) => { + if (color === "transparent") return "#ffffff"; + const r = parseInt(color.slice(1, 3), 16); + const g = parseInt(color.slice(3, 5), 16); + const b = parseInt(color.slice(5, 7), 16); + const luminance = 0.299 * r + 0.587 * g + 0.114 * b; + if (luminance > 186) return "#000000"; + return "#ffffff"; + }; + + // Normalize the hex input. + // Adds a # at the beginning of the input if it's not there. + const normalizeHexDraft = (raw: string) => { + const trimmed = raw.trim(); + if (trimmed === "") return ""; + if (/^[0-9A-Fa-f]/.test(trimmed[0])) return `#${trimmed}`; + return trimmed; + }; + + const handleColorInputChange = (e: React.ChangeEvent) => { + const normalized = normalizeHexDraft(e.target.value); + setHexInput(normalized); + // Check if the normalized hex is a valid hex color. + // It should follow the format #RRGGBB or #RGB. + const isValidHexColor = + /^#[0-9A-Fa-f]{3}$/.test(normalized) || /^#[0-9A-Fa-f]{6}$/.test(normalized); + if (isValidHexColor) { + onUpdateColor(normalized); + } + }; + + const toTransparent = (color: string) => { + if (color === "transparent") return; + const hsva = hexToHsva(color); + hsva.a = 0; + return hsva; + }; + return ( +
+
+ + +
+ {colorMode === "wheel" && ( + <> +
+ {selectedColor} +
+ { + onUpdateColor(color.hex); + }} + style={{ + borderRadius: "8px", + }} + disableAlpha={true} + /> + + + )} + {colorMode === "palette" && ( + { + onUpdateColor(color.hex); + }} + style={{ + width: "100%", + borderRadius: "8px", + }} + /> + )} + {props.clearBackgroundOption === true && ( + + )} +
+ ); +} diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 0c3efbb..319cd8e 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -90,13 +90,13 @@ DialogDescription.displayName = DialogPrimitive.Description.displayName; export { Dialog, - DialogPortal, - DialogOverlay, - DialogTrigger, DialogClose, DialogContent, - DialogHeader, - DialogFooter, - DialogTitle, DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, }; diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx index c15187d..eb140b9 100644 --- a/src/components/ui/dropdown-menu.tsx +++ b/src/components/ui/dropdown-menu.tsx @@ -54,9 +54,11 @@ DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayNam const DropdownMenuContent = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, sideOffset = 4, ...props }, ref) => ( - + React.ComponentPropsWithoutRef & { + portalled?: boolean; + } +>(({ className, sideOffset = 4, portalled = true, ...props }, ref) => { + const content = ( - -)); + ); + + if (!portalled) { + return content; + } + + return {content}; +}); DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName; const DropdownMenuItem = React.forwardRef< @@ -169,18 +177,18 @@ DropdownMenuShortcut.displayName = "DropdownMenuShortcut"; export { DropdownMenu, - DropdownMenuTrigger, - DropdownMenuContent, - DropdownMenuItem, DropdownMenuCheckboxItem, - DropdownMenuRadioItem, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, DropdownMenuLabel, + DropdownMenuPortal, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, - DropdownMenuGroup, - DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, - DropdownMenuRadioGroup, + DropdownMenuTrigger, }; diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx index 8d72390..9341c8d 100644 --- a/src/components/ui/popover.tsx +++ b/src/components/ui/popover.tsx @@ -57,4 +57,4 @@ function PopoverArrow({ ); } -export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverArrow }; +export { Popover, PopoverAnchor, PopoverArrow, PopoverContent, PopoverTrigger }; diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx index 53e21e6..d151d16 100644 --- a/src/components/ui/select.tsx +++ b/src/components/ui/select.tsx @@ -62,34 +62,50 @@ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayNam const SelectContent = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, position = "popper", ...props }, ref) => ( - - - - & { + showScrollButtons?: boolean; + viewportClassName?: string; + } +>( + ( + { + className, + children, + position = "popper", + showScrollButtons = true, + viewportClassName, + ...props + }, + ref, + ) => ( + + - {children} - - - - -)); + {showScrollButtons ? : null} + + {children} + + {showScrollButtons ? : null} + + + ), +); SelectContent.displayName = SelectPrimitive.Content.displayName; const SelectLabel = React.forwardRef< @@ -141,13 +157,13 @@ SelectSeparator.displayName = SelectPrimitive.Separator.displayName; export { Select, - SelectGroup, - SelectValue, - SelectTrigger, SelectContent, - SelectLabel, + SelectGroup, SelectItem, - SelectSeparator, - SelectScrollUpButton, + SelectLabel, SelectScrollDownButton, + SelectScrollUpButton, + SelectSeparator, + SelectTrigger, + SelectValue, }; diff --git a/src/components/ui/tabs.tsx b/src/components/ui/tabs.tsx index dbee684..95e346a 100644 --- a/src/components/ui/tabs.tsx +++ b/src/components/ui/tabs.tsx @@ -50,4 +50,4 @@ const TabsContent = React.forwardRef< )); TabsContent.displayName = TabsPrimitive.Content.displayName; -export { Tabs, TabsList, TabsTrigger, TabsContent }; +export { Tabs, TabsContent, TabsList, TabsTrigger }; diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip.tsx index bd6687b..c5dfc12 100644 --- a/src/components/ui/tooltip.tsx +++ b/src/components/ui/tooltip.tsx @@ -67,4 +67,4 @@ function Tooltip({ ); } -export { TooltipProvider, TooltipRoot, TooltipTrigger, TooltipContent, Tooltip }; +export { Tooltip, TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger }; diff --git a/src/components/video-editor/AnnotationOverlay.tsx b/src/components/video-editor/AnnotationOverlay.tsx index 11548c7..f416c32 100644 --- a/src/components/video-editor/AnnotationOverlay.tsx +++ b/src/components/video-editor/AnnotationOverlay.tsx @@ -1,8 +1,40 @@ -import { useRef } from "react"; +import { type CSSProperties, type PointerEvent, useEffect, useRef, useState } from "react"; import { Rnd } from "react-rnd"; +import { + getBlurOverlayColor, + getMosaicGridOverlayColor, + getNormalizedMosaicBlockSize, +} from "@/lib/blurEffects"; import { cn } from "@/lib/utils"; import { getArrowComponent } from "./ArrowSvgs"; -import type { AnnotationRegion } from "./types"; +import { + type AnnotationRegion, + type BlurData, + DEFAULT_BLUR_BLOCK_SIZE, + DEFAULT_BLUR_DATA, + DEFAULT_BLUR_INTENSITY, +} from "./types"; + +const FREEHAND_POINT_THRESHOLD = 1; +type PreviewCanvasSource = { + width: number; + height: number; + clientWidth?: number; + clientHeight?: number; +}; + +function buildBlurPolygonClipPath(points: Array<{ x: number; y: number }>) { + if (points.length < 3) return undefined; + const polygon = points.map((point) => `${point.x}% ${point.y}%`).join(", "); + return `polygon(${polygon})`; +} + +function buildBlurFreehandPath(points: Array<{ x: number; y: number }>, closed = true) { + if (closed ? points.length < 3 : points.length < 2) return null; + const [firstPoint, ...rest] = points; + const path = `M ${firstPoint.x} ${firstPoint.y} ${rest.map((point) => `L ${point.x} ${point.y}`).join(" ")}`; + return closed ? `${path} Z` : path; +} interface AnnotationOverlayProps { annotation: AnnotationRegion; @@ -11,9 +43,13 @@ interface AnnotationOverlayProps { containerHeight: number; onPositionChange: (id: string, position: { x: number; y: number }) => void; onSizeChange: (id: string, size: { width: number; height: number }) => void; + onBlurDataChange?: (id: string, blurData: BlurData) => void; + onBlurDataCommit?: () => void; onClick: (id: string) => void; zIndex: number; isSelectedBoost: boolean; // Boost z-index when selected for easy editing + previewSourceCanvas?: PreviewCanvasSource | null; + previewFrameVersion?: number; } export function AnnotationOverlay({ @@ -23,16 +59,130 @@ export function AnnotationOverlay({ containerHeight, onPositionChange, onSizeChange, + onBlurDataChange, + onBlurDataCommit, onClick, zIndex, isSelectedBoost, + previewSourceCanvas, + previewFrameVersion, }: AnnotationOverlayProps) { - const x = (annotation.position.x / 100) * containerWidth; - const y = (annotation.position.y / 100) * containerHeight; - const width = (annotation.size.width / 100) * containerWidth; - const height = (annotation.size.height / 100) * containerHeight; - + const committedX = (annotation.position.x / 100) * containerWidth; + const committedY = (annotation.position.y / 100) * containerHeight; + const committedWidth = (annotation.size.width / 100) * containerWidth; + const committedHeight = (annotation.size.height / 100) * containerHeight; + const blurShape = annotation.type === "blur" ? (annotation.blurData?.shape ?? "rectangle") : null; + const isSelectedFreehandBlur = isSelected && blurShape === "freehand"; const isDraggingRef = useRef(false); + const isDrawingFreehandRef = useRef(false); + const freehandPointsRef = useRef>([]); + const [isFreehandDrawing, setIsFreehandDrawing] = useState(false); + const [draftFreehandPoints, setDraftFreehandPoints] = useState>( + [], + ); + const [livePointerPoint, setLivePointerPoint] = useState<{ x: number; y: number } | null>(null); + const mosaicCanvasRef = useRef(null); + const blurType = annotation.type === "blur" ? (annotation.blurData?.type ?? "blur") : "blur"; + const blurOverlayColor = + annotation.type === "blur" ? getBlurOverlayColor(annotation.blurData) : ""; + const mosaicGridOverlayColor = + annotation.type === "blur" ? getMosaicGridOverlayColor(annotation.blurData) : ""; + const [liveRect, setLiveRect] = useState({ + x: committedX, + y: committedY, + width: committedWidth, + height: committedHeight, + }); + + useEffect(() => { + setLiveRect({ + x: committedX, + y: committedY, + width: committedWidth, + height: committedHeight, + }); + }, [committedHeight, committedWidth, committedX, committedY]); + + const { x, y, width, height } = liveRect; + + useEffect(() => { + if (annotation.type !== "blur" || blurType !== "mosaic") { + return; + } + void previewFrameVersion; + + const canvas = mosaicCanvasRef.current; + const sourceCanvas = previewSourceCanvas; + if (!canvas || !sourceCanvas) { + return; + } + + const sourceWidth = sourceCanvas.width; + const sourceHeight = sourceCanvas.height; + const sourceClientWidth = sourceCanvas.clientWidth || containerWidth || sourceWidth; + const sourceClientHeight = sourceCanvas.clientHeight || containerHeight || sourceHeight; + if ( + sourceWidth <= 0 || + sourceHeight <= 0 || + sourceClientWidth <= 0 || + sourceClientHeight <= 0 + ) { + return; + } + + const drawWidth = Math.max(1, Math.round(width)); + const drawHeight = Math.max(1, Math.round(height)); + if (drawWidth <= 0 || drawHeight <= 0) { + return; + } + + canvas.width = drawWidth; + canvas.height = drawHeight; + + const context = canvas.getContext("2d", { willReadFrequently: true }); + if (!context) { + return; + } + + const scaleX = sourceWidth / sourceClientWidth; + const scaleY = sourceHeight / sourceClientHeight; + const sourceX = Math.max(0, Math.floor(x * scaleX)); + const sourceY = Math.max(0, Math.floor(y * scaleY)); + const sourceSampleWidth = Math.max(1, Math.ceil(drawWidth * scaleX)); + const sourceSampleHeight = Math.max(1, Math.ceil(drawHeight * scaleY)); + const clampedSampleWidth = Math.max(1, Math.min(sourceSampleWidth, sourceWidth - sourceX)); + const clampedSampleHeight = Math.max(1, Math.min(sourceSampleHeight, sourceHeight - sourceY)); + const blockSize = getNormalizedMosaicBlockSize(annotation.blurData); + const downscaledWidth = Math.max(1, Math.round(drawWidth / blockSize)); + const downscaledHeight = Math.max(1, Math.round(drawHeight / blockSize)); + canvas.width = downscaledWidth; + canvas.height = downscaledHeight; + + context.clearRect(0, 0, downscaledWidth, downscaledHeight); + context.imageSmoothingEnabled = true; + context.drawImage( + sourceCanvas as CanvasImageSource, + sourceX, + sourceY, + clampedSampleWidth, + clampedSampleHeight, + 0, + 0, + downscaledWidth, + downscaledHeight, + ); + }, [ + annotation, + blurType, + containerHeight, + containerWidth, + height, + previewFrameVersion, + previewSourceCanvas, + width, + x, + y, + ]); const renderArrow = () => { const direction = annotation.figureData?.arrowDirection || "right"; @@ -43,6 +193,95 @@ export function AnnotationOverlay({ return ; }; + const normalizePoint = (event: PointerEvent) => { + const rect = event.currentTarget.getBoundingClientRect(); + const x = ((event.clientX - rect.left) / rect.width) * 100; + const y = ((event.clientY - rect.top) / rect.height) * 100; + return { + x: Math.max(0, Math.min(100, x)), + y: Math.max(0, Math.min(100, y)), + }; + }; + + const appendFreehandPoint = (point: { x: number; y: number }) => { + const points = freehandPointsRef.current; + const lastPoint = points[points.length - 1]; + if (!lastPoint) { + points.push(point); + return; + } + const dx = point.x - lastPoint.x; + const dy = point.y - lastPoint.y; + // Sample freehand points in annotation-space percent units to avoid overly dense paths. + if (Math.hypot(dx, dy) >= FREEHAND_POINT_THRESHOLD) { + points.push(point); + } + }; + + const handleFreehandPointerDown = (event: PointerEvent) => { + if ( + !isSelected || + annotation.type !== "blur" || + annotation.blurData?.shape !== "freehand" || + !onBlurDataChange + ) { + return; + } + event.preventDefault(); + event.stopPropagation(); + event.currentTarget.setPointerCapture(event.pointerId); + isDrawingFreehandRef.current = true; + setIsFreehandDrawing(true); + const point = normalizePoint(event); + freehandPointsRef.current = [point]; + setDraftFreehandPoints([point]); + setLivePointerPoint(point); + }; + + const handleFreehandPointerMove = (event: PointerEvent) => { + if (!isDrawingFreehandRef.current) return; + event.preventDefault(); + event.stopPropagation(); + const point = normalizePoint(event); + setLivePointerPoint(point); + appendFreehandPoint(point); + setDraftFreehandPoints([...freehandPointsRef.current]); + }; + + const finishFreehandPointer = (event: PointerEvent) => { + if (!isDrawingFreehandRef.current || !onBlurDataChange) return; + isDrawingFreehandRef.current = false; + setIsFreehandDrawing(false); + try { + event.currentTarget.releasePointerCapture(event.pointerId); + } catch { + // no-op if already released + } + const points = [...freehandPointsRef.current]; + if (livePointerPoint) { + const last = points[points.length - 1]; + if (!last || Math.hypot(last.x - livePointerPoint.x, last.y - livePointerPoint.y) > 0.001) { + points.push(livePointerPoint); + } + } + if (points.length >= 3) { + const closedPoints = [...points]; + const first = closedPoints[0]; + const last = closedPoints[closedPoints.length - 1]; + if (Math.hypot(last.x - first.x, last.y - first.y) > 0.001) { + closedPoints.push({ ...first }); + } + onBlurDataChange(annotation.id, { + ...(annotation.blurData || { ...DEFAULT_BLUR_DATA, shape: "freehand" }), + shape: "freehand", + freehandPoints: closedPoints, + }); + setDraftFreehandPoints(closedPoints); + onBlurDataCommit?.(); + } + setLivePointerPoint(null); + }; + const renderContent = () => { switch (annotation.type) { case "text": @@ -113,6 +352,149 @@ export function AnnotationOverlay({
{renderArrow()}
); + case "blur": { + const shape = annotation.blurData?.shape ?? "rectangle"; + const blurIntensity = Math.max( + 1, + Math.round(annotation.blurData?.intensity ?? DEFAULT_BLUR_INTENSITY), + ); + const blockSize = Math.max( + 1, + Math.round(annotation.blurData?.blockSize ?? DEFAULT_BLUR_BLOCK_SIZE), + ); + const activeFreehandPoints = + shape === "freehand" + ? isFreehandDrawing + ? draftFreehandPoints + : (annotation.blurData?.freehandPoints ?? []) + : []; + const drawingPoints = + isFreehandDrawing && livePointerPoint + ? (() => { + const last = activeFreehandPoints[activeFreehandPoints.length - 1]; + if (!last) return [livePointerPoint]; + const dx = livePointerPoint.x - last.x; + const dy = livePointerPoint.y - last.y; + return Math.hypot(dx, dy) > 0.01 + ? [...activeFreehandPoints, livePointerPoint] + : activeFreehandPoints; + })() + : activeFreehandPoints; + const clipPath = + shape === "freehand" ? buildBlurPolygonClipPath(activeFreehandPoints) : undefined; + const freehandPath = + shape === "freehand" + ? buildBlurFreehandPath( + isFreehandDrawing ? drawingPoints : activeFreehandPoints, + !isFreehandDrawing, + ) + : null; + const currentPointerPoint = isFreehandDrawing + ? livePointerPoint || drawingPoints[drawingPoints.length - 1] || null + : null; + const shapeBorderRadius = shape === "oval" ? "50%" : shape === "rectangle" ? "8px" : "0"; + const shouldShowFreehandBlurFill = + shape !== "freehand" || (!!clipPath && !isFreehandDrawing); + const shapeMaskStyle: CSSProperties = { + borderRadius: shapeBorderRadius, + clipPath: isFreehandDrawing ? undefined : clipPath, + WebkitClipPath: isFreehandDrawing ? undefined : clipPath, + }; + const isFreehandSelected = isSelectedFreehandBlur; + return ( +
+
+
+ {blurType === "mosaic" && shouldShowFreehandBlurFill && ( + + )} + {blurType === "mosaic" && shouldShowFreehandBlurFill && ( +
+ )} + {blurType === "mosaic" && ( +
+ )} + {isSelected && shape !== "freehand" && ( +
+ )} +
+ {isSelected && shape === "freehand" && freehandPath && ( + + + {currentPointerPoint && ( + + )} + + )} + {isFreehandSelected && ( +
+ )} +
+ ); + } + default: return null; } @@ -125,7 +507,19 @@ export function AnnotationOverlay({ onDragStart={() => { isDraggingRef.current = true; }} + onDrag={(_e, d) => { + setLiveRect((prev) => ({ + ...prev, + x: d.x, + y: d.y, + })); + }} onDragStop={(_e, d) => { + setLiveRect((prev) => ({ + ...prev, + x: d.x, + y: d.y, + })); const xPercent = (d.x / containerWidth) * 100; const yPercent = (d.y / containerHeight) * 100; onPositionChange(annotation.id, { x: xPercent, y: yPercent }); @@ -135,7 +529,21 @@ export function AnnotationOverlay({ isDraggingRef.current = false; }, 100); }} + onResize={(_e, _direction, ref, _delta, position) => { + setLiveRect({ + x: position.x, + y: position.y, + width: ref.offsetWidth, + height: ref.offsetHeight, + }); + }} onResizeStop={(_e, _direction, ref, _delta, position) => { + setLiveRect({ + x: position.x, + y: position.y, + width: ref.offsetWidth, + height: ref.offsetHeight, + }); const xPercent = (position.x / containerWidth) * 100; const yPercent = (position.y / containerHeight) * 100; const widthPercent = (ref.offsetWidth / containerWidth) * 100; @@ -149,18 +557,23 @@ export function AnnotationOverlay({ }} bounds="parent" className={cn( - "cursor-move transition-all", - isSelected && "ring-2 ring-[#34B27B] ring-offset-2 ring-offset-transparent", + "cursor-move", + isSelected && + annotation.type !== "blur" && + "ring-2 ring-[#34B27B] ring-offset-2 ring-offset-transparent", )} style={{ zIndex: isSelectedBoost ? zIndex + 1000 : zIndex, // Boost selected annotation to ensure it's on top pointerEvents: isSelected ? "auto" : "none", - border: isSelected ? "2px solid rgba(52, 178, 123, 0.8)" : "none", - backgroundColor: isSelected ? "rgba(52, 178, 123, 0.1)" : "transparent", - boxShadow: isSelected ? "0 0 0 1px rgba(52, 178, 123, 0.35)" : "none", + border: + isSelected && annotation.type !== "blur" ? "2px solid rgba(52, 178, 123, 0.8)" : "none", + backgroundColor: + isSelected && annotation.type !== "blur" ? "rgba(52, 178, 123, 0.1)" : "transparent", + boxShadow: + isSelected && annotation.type !== "blur" ? "0 0 0 1px rgba(52, 178, 123, 0.35)" : "none", }} - enableResizing={isSelected} - disableDragging={!isSelected} + enableResizing={isSelected && !isSelectedFreehandBlur} + disableDragging={!isSelected || isSelectedFreehandBlur} resizeHandleStyles={{ topLeft: { width: "12px", @@ -206,11 +619,13 @@ export function AnnotationOverlay({ >
{renderContent()} diff --git a/src/components/video-editor/AnnotationSettingsPanel.tsx b/src/components/video-editor/AnnotationSettingsPanel.tsx index b289392..3f8064e 100644 --- a/src/components/video-editor/AnnotationSettingsPanel.tsx +++ b/src/components/video-editor/AnnotationSettingsPanel.tsx @@ -5,6 +5,7 @@ import { AlignRight, Bold, ChevronDown, + Copy, Image as ImageIcon, Info, Italic, @@ -30,9 +31,15 @@ import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; import { useScopedT } from "@/contexts/I18nContext"; import { type CustomFont, getCustomFonts } from "@/lib/customFonts"; import { cn } from "@/lib/utils"; +import ColorPicker from "../ui/color-picker"; import { AddCustomFontDialog } from "./AddCustomFontDialog"; import { getArrowComponent } from "./ArrowSvgs"; -import type { AnnotationRegion, AnnotationType, ArrowDirection, FigureData } from "./types"; +import { + type AnnotationRegion, + type AnnotationType, + type ArrowDirection, + type FigureData, +} from "./types"; interface AnnotationSettingsPanelProps { annotation: AnnotationRegion; @@ -40,6 +47,7 @@ interface AnnotationSettingsPanelProps { onTypeChange: (type: AnnotationType) => void; onStyleChange: (style: Partial) => void; onFigureDataChange?: (figureData: FigureData) => void; + onDuplicate?: () => void; onDelete: () => void; } @@ -62,12 +70,12 @@ export function AnnotationSettingsPanel({ onTypeChange, onStyleChange, onFigureDataChange, + onDuplicate, onDelete, }: AnnotationSettingsPanelProps) { const t = useScopedT("settings"); const fileInputRef = useRef(null); const [customFonts, setCustomFonts] = useState([]); - const fontStyleLabels: Record = { classic: t("fontStyles.classic"), editor: t("fontStyles.editor"), @@ -380,15 +388,19 @@ export function AnnotationSettingsPanel({ - - { - onStyleChange({ color: color.hex }); + + { + onStyleChange({ color: color }); }} /> @@ -419,31 +431,23 @@ export function AnnotationSettingsPanel({ - - { - onStyleChange({ backgroundColor: color.hex }); + + { + onStyleChange({ backgroundColor: color }); }} /> -
@@ -597,15 +601,28 @@ export function AnnotationSettingsPanel({ - +
+ + + +
diff --git a/src/components/video-editor/BlurSettingsPanel.tsx b/src/components/video-editor/BlurSettingsPanel.tsx new file mode 100644 index 0000000..09bfe3a --- /dev/null +++ b/src/components/video-editor/BlurSettingsPanel.tsx @@ -0,0 +1,247 @@ +import { Info, Trash2 } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Slider } from "@/components/ui/slider"; +import { useScopedT } from "@/contexts/I18nContext"; +import { getBlurOverlayColor } from "@/lib/blurEffects"; +import { cn } from "@/lib/utils"; +import { + type AnnotationRegion, + type BlurColor, + type BlurData, + type BlurShape, + DEFAULT_BLUR_BLOCK_SIZE, + DEFAULT_BLUR_DATA, + MAX_BLUR_BLOCK_SIZE, + MAX_BLUR_INTENSITY, + MIN_BLUR_BLOCK_SIZE, + MIN_BLUR_INTENSITY, +} from "./types"; + +interface BlurSettingsPanelProps { + blurRegion: AnnotationRegion; + onBlurDataChange: (blurData: BlurData) => void; + onBlurDataCommit?: () => void; + onDelete: () => void; +} + +export function BlurSettingsPanel({ + blurRegion, + onBlurDataChange, + onBlurDataCommit, + onDelete, +}: BlurSettingsPanelProps) { + const t = useScopedT("settings"); + + const blurShapeOptions: Array<{ value: BlurShape; labelKey: string }> = [ + { value: "rectangle", labelKey: "blurShapeRectangle" }, + { value: "oval", labelKey: "blurShapeOval" }, + ]; + const blurColorOptions: Array<{ value: BlurColor; labelKey: string }> = [ + { value: "white", labelKey: "blurColorWhite" }, + { value: "black", labelKey: "blurColorBlack" }, + ]; + + return ( +
+
+
+ {t("annotation.blurShape")} + + {t("annotation.active")} + +
+ +
+ {blurShapeOptions.map((shape) => { + const activeShape = blurRegion.blurData?.shape || DEFAULT_BLUR_DATA.shape; + const isActive = activeShape === shape.value; + return ( + + ); + })} +
+ +
+ + +
+ +
+ +
+ {blurColorOptions.map((option) => { + const activeColor = blurRegion.blurData?.color ?? DEFAULT_BLUR_DATA.color; + const isActive = activeColor === option.value; + return ( + + ); + })} +
+
+ +
+
+ + {blurRegion.blurData?.type === "mosaic" + ? t("annotation.mosaicBlockSize") + : t("annotation.blurIntensity")} + + + {Math.round( + blurRegion.blurData?.type === "mosaic" + ? (blurRegion.blurData?.blockSize ?? DEFAULT_BLUR_BLOCK_SIZE) + : (blurRegion.blurData?.intensity ?? DEFAULT_BLUR_DATA.intensity), + )} + px + +
+ { + onBlurDataChange({ + ...DEFAULT_BLUR_DATA, + ...blurRegion.blurData, + ...(blurRegion.blurData?.type === "mosaic" + ? { blockSize: values[0] } + : { intensity: values[0] }), + }); + }} + onValueCommit={() => onBlurDataCommit?.()} + min={blurRegion.blurData?.type === "mosaic" ? MIN_BLUR_BLOCK_SIZE : MIN_BLUR_INTENSITY} + max={blurRegion.blurData?.type === "mosaic" ? MAX_BLUR_BLOCK_SIZE : MAX_BLUR_INTENSITY} + step={1} + className="w-full [&_[role=slider]]:bg-[#34B27B] [&_[role=slider]]:border-[#34B27B] [&_[role=slider]]:h-3 [&_[role=slider]]:w-3" + /> +
+ + + +
+
+ + {t("annotation.shortcutsAndTips")} +
+
    +
  • {t("annotation.tipMovePlayhead")}
  • +
+
+
+
+ ); +} diff --git a/src/components/video-editor/KeyboardShortcutsHelp.tsx b/src/components/video-editor/KeyboardShortcutsHelp.tsx index 5287365..b90b377 100644 --- a/src/components/video-editor/KeyboardShortcutsHelp.tsx +++ b/src/components/video-editor/KeyboardShortcutsHelp.tsx @@ -37,8 +37,10 @@ export function KeyboardShortcutsHelp() {
{FIXED_SHORTCUTS.map((fixed) => ( -
- {fixed.label} +
+ + {t(`fixedActions.${fixed.i18nKey}`, { defaultValue: fixed.label })} + {isMac ? fixed.display diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index 7e556b8..5cac573 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -1,6 +1,6 @@ -import Block from "@uiw/react-color-block"; import { Bug, + ChevronDown, Crop, Download, Film, @@ -14,7 +14,7 @@ import { Upload, X, } from "lucide-react"; -import { useCallback, useEffect, useRef, useState } from "react"; +import { useCallback, useMemo, useRef, useState } from "react"; import { toast } from "sonner"; import { Accordion, @@ -23,6 +23,7 @@ import { AccordionTrigger, } from "@/components/ui/accordion"; import { Button } from "@/components/ui/button"; +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Select, SelectContent, @@ -34,34 +35,96 @@ import { Slider } from "@/components/ui/slider"; import { Switch } from "@/components/ui/switch"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { useScopedT } from "@/contexts/I18nContext"; -import { getAssetPath } from "@/lib/assetPath"; import { WEBCAM_LAYOUT_PRESETS } from "@/lib/compositeLayout"; import type { ExportFormat, ExportQuality, GifFrameRate, GifSizePreset } from "@/lib/exporter"; import { GIF_FRAME_RATES, GIF_SIZE_PRESETS } from "@/lib/exporter"; import { cn } from "@/lib/utils"; +import { resolveImageWallpaperUrl, WALLPAPER_PATHS } from "@/lib/wallpaper"; import { type AspectRatio, isPortraitAspectRatio } from "@/utils/aspectRatioUtils"; import { getTestId } from "@/utils/getTestId"; +import ColorPicker from "../ui/color-picker"; import { AnnotationSettingsPanel } from "./AnnotationSettingsPanel"; +import { BlurSettingsPanel } from "./BlurSettingsPanel"; import { CropControl } from "./CropControl"; import { KeyboardShortcutsHelp } from "./KeyboardShortcutsHelp"; import type { AnnotationRegion, AnnotationType, + BlurData, CropRegion, FigureData, PlaybackSpeed, WebcamLayoutPreset, WebcamMaskShape, + WebcamSizePreset, ZoomDepth, ZoomFocusMode, } from "./types"; -import { SPEED_OPTIONS } from "./types"; +import { DEFAULT_WEBCAM_SIZE_PRESET, MAX_PLAYBACK_SPEED, SPEED_OPTIONS } from "./types"; + +function CustomSpeedInput({ + value, + onChange, + onError, +}: { + value: number; + onChange: (val: number) => void; + onError: () => void; +}) { + const isPreset = SPEED_OPTIONS.some((o) => o.speed === value); + const [draft, setDraft] = useState(isPreset ? "" : String(Math.round(value))); + const [isFocused, setIsFocused] = useState(false); + + const prevValue = useRef(value); + if (!isFocused && prevValue.current !== value) { + prevValue.current = value; + setDraft(isPreset ? "" : String(Math.round(value))); + } + + const handleChange = useCallback( + (e: React.ChangeEvent) => { + const digits = e.target.value.replace(/\D/g, ""); + if (digits === "") { + setDraft(""); + return; + } + const num = Number(digits); + if (num > MAX_PLAYBACK_SPEED) { + onError(); + return; + } + setDraft(digits); + if (num >= 1) onChange(num); + }, + [onChange, onError], + ); + + const handleBlur = useCallback(() => { + setIsFocused(false); + if (!draft || Number(draft) < 1) { + setDraft(isPreset ? "" : String(Math.round(value))); + } + }, [draft, isPreset, value]); + + return ( +
+ setIsFocused(true)} + onChange={handleChange} + onBlur={handleBlur} + onKeyDown={(e) => e.key === "Enter" && (e.target as HTMLInputElement).blur()} + className="w-12 bg-white/5 border border-white/10 rounded-md px-1 py-0.5 text-[11px] font-semibold text-[#d97706] text-center focus:outline-none focus:border-[#d97706]/40" + /> + × +
+ ); +} -const WALLPAPER_COUNT = 18; -const WALLPAPER_RELATIVE = Array.from( - { length: WALLPAPER_COUNT }, - (_, i) => `wallpapers/wallpaper${i + 1}.jpg`, -); const GRADIENTS = [ "linear-gradient( 111.6deg, rgba(114,167,232,1) 9.4%, rgba(253,129,82,1) 43.9%, rgba(253,129,82,1) 54.8%, rgba(249,202,86,1) 86.3% )", "linear-gradient(120deg, #d4fc79 0%, #96e6a1 100%)", @@ -90,6 +153,12 @@ const GRADIENTS = [ ]; interface SettingsPanelProps { + cursorHighlight?: import("./videoPlayback/cursorHighlight").CursorHighlightConfig; + onCursorHighlightChange?: ( + next: import("./videoPlayback/cursorHighlight").CursorHighlightConfig, + ) => void; + // macOS only — gates the "Only on clicks" toggle (needs uiohook). + cursorHighlightSupportsClicks?: boolean; selected: string; onWallpaperChange: (path: string) => void; selectedZoomDepth?: ZoomDepth | null; @@ -132,7 +201,11 @@ interface SettingsPanelProps { onGifSizePresetChange?: (preset: GifSizePreset) => void; gifOutputDimensions?: { width: number; height: number }; onExport?: () => void; - unsavedExport?: { arrayBuffer: ArrayBuffer; fileName: string; format: string } | null; + unsavedExport?: { + arrayBuffer: ArrayBuffer; + fileName: string; + format: string; + } | null; onSaveUnsavedExport?: () => void; selectedAnnotationId?: string | null; annotationRegions?: AnnotationRegion[]; @@ -140,7 +213,13 @@ interface SettingsPanelProps { onAnnotationTypeChange?: (id: string, type: AnnotationType) => void; onAnnotationStyleChange?: (id: string, style: Partial) => void; onAnnotationFigureDataChange?: (id: string, figureData: FigureData) => void; + onAnnotationDuplicate?: (id: string) => void; onAnnotationDelete?: (id: string) => void; + selectedBlurId?: string | null; + blurRegions?: AnnotationRegion[]; + onBlurDataChange?: (id: string, blurData: BlurData) => void; + onBlurDataCommit?: () => void; + onBlurDelete?: (id: string) => void; selectedSpeedId?: string | null; selectedSpeedValue?: PlaybackSpeed | null; onSpeedChange?: (speed: PlaybackSpeed) => void; @@ -150,6 +229,9 @@ interface SettingsPanelProps { onWebcamLayoutPresetChange?: (preset: WebcamLayoutPreset) => void; webcamMaskShape?: import("./types").WebcamMaskShape; onWebcamMaskShapeChange?: (shape: import("./types").WebcamMaskShape) => void; + webcamSizePreset?: WebcamSizePreset; + onWebcamSizePresetChange?: (size: WebcamSizePreset) => void; + onWebcamSizePresetCommit?: () => void; } export default SettingsPanel; @@ -164,6 +246,9 @@ const ZOOM_DEPTH_OPTIONS: Array<{ depth: ZoomDepth; label: string }> = [ ]; export function SettingsPanel({ + cursorHighlight, + onCursorHighlightChange, + cursorHighlightSupportsClicks = false, selected, onWallpaperChange, selectedZoomDepth, @@ -213,7 +298,13 @@ export function SettingsPanel({ onAnnotationTypeChange, onAnnotationStyleChange, onAnnotationFigureDataChange, + onAnnotationDuplicate, onAnnotationDelete, + selectedBlurId, + blurRegions = [], + onBlurDataChange, + onBlurDataCommit, + onBlurDelete, selectedSpeedId, selectedSpeedValue, onSpeedChange, @@ -223,26 +314,17 @@ export function SettingsPanel({ onWebcamLayoutPresetChange, webcamMaskShape = "rectangle", onWebcamMaskShapeChange, + webcamSizePreset = DEFAULT_WEBCAM_SIZE_PRESET, + onWebcamSizePresetChange, + onWebcamSizePresetCommit, }: SettingsPanelProps) { const t = useScopedT("settings"); - const [wallpaperPaths, setWallpaperPaths] = useState([]); + // Resolved URLs are for DOM rendering only (backgroundImage). The canonical + // `/wallpapers/wallpaperN.jpg` form in WALLPAPER_PATHS is what gets persisted + // on click — never the machine-specific file:// URL. + const wallpaperPreviewUrls = useMemo(() => WALLPAPER_PATHS.map(resolveImageWallpaperUrl), []); const [customImages, setCustomImages] = useState([]); const fileInputRef = useRef(null); - - useEffect(() => { - let mounted = true; - (async () => { - try { - const resolved = await Promise.all(WALLPAPER_RELATIVE.map((p) => getAssetPath(p))); - if (mounted) setWallpaperPaths(resolved); - } catch (_err) { - if (mounted) setWallpaperPaths(WALLPAPER_RELATIVE.map((p) => `/${p}`)); - } - })(); - return () => { - mounted = false; - }; - }, []); const colorPalette = [ "#FF0000", "#FFD700", @@ -268,6 +350,7 @@ export function SettingsPanel({ const cropSnapshotRef = useRef(null); const [cropAspectLocked, setCropAspectLocked] = useState(false); const [cropAspectRatio, setCropAspectRatio] = useState(""); + const isPortraitCanvas = isPortraitAspectRatio(aspectRatio); const videoWidth = videoElement?.videoWidth || 1920; const videoHeight = videoElement?.videoHeight || 1080; @@ -424,7 +507,7 @@ export function SettingsPanel({ setCustomImages((prev) => prev.filter((img) => img !== imageUrl)); // If the removed image was selected, clear selection if (selected === imageUrl) { - onWallpaperChange(wallpaperPaths[0] || WALLPAPER_RELATIVE[0]); + onWallpaperChange(WALLPAPER_PATHS[0]); } }; @@ -446,6 +529,9 @@ export function SettingsPanel({ const selectedAnnotation = selectedAnnotationId ? annotationRegions.find((a) => a.id === selectedAnnotationId) : null; + const selectedBlur = selectedBlurId + ? blurRegions.find((region) => region.id === selectedBlurId) + : null; // If an annotation is selected, show annotation settings instead if ( @@ -466,11 +552,25 @@ export function SettingsPanel({ ? (figureData) => onAnnotationFigureDataChange(selectedAnnotation.id, figureData) : undefined } + onDuplicate={ + onAnnotationDuplicate ? () => onAnnotationDuplicate(selectedAnnotation.id) : undefined + } onDelete={() => onAnnotationDelete(selectedAnnotation.id)} /> ); } + if (selectedBlur && onBlurDataChange && onBlurDelete) { + return ( + onBlurDataChange(selectedBlur.id, blurData)} + onBlurDataCommit={onBlurDataCommit} + onDelete={() => onBlurDelete(selectedBlur.id)} + /> + ); + } + return (
@@ -584,7 +684,7 @@ export function SettingsPanel({ )}
-
+
{SPEED_OPTIONS.map((option) => { const isActive = selectedSpeedValue === option.speed; return ( @@ -609,6 +709,29 @@ export function SettingsPanel({ ); })}
+
+
+ + {t("speed.customPlaybackSpeed")} + + {selectedSpeedId ? ( + onSpeedChange?.(val)} + onError={() => toast.error(t("speed.maxSpeedError"))} + /> + ) : ( +
+
+ -- +
+ × +
+ )} +
+
{!selectedSpeedId && (

{t("speed.selectRegion")}

)} @@ -656,15 +779,17 @@ export function SettingsPanel({ - {WEBCAM_LAYOUT_PRESETS.filter( - (preset) => - preset.value === "picture-in-picture" || - isPortraitAspectRatio(aspectRatio), - ).map((preset) => ( + {WEBCAM_LAYOUT_PRESETS.filter((preset) => { + if (preset.value === "picture-in-picture") return true; + if (preset.value === "vertical-stack") return isPortraitCanvas; + return !isPortraitCanvas; + }).map((preset) => ( {preset.value === "picture-in-picture" ? t("layout.pictureInPicture") - : t("layout.verticalStack")} + : preset.value === "vertical-stack" + ? t("layout.verticalStack") + : t("layout.dualFrame")} ))} @@ -751,6 +876,27 @@ export function SettingsPanel({
)} + {webcamLayoutPreset === "picture-in-picture" && ( +
+
+
+ {t("layout.webcamSize")} +
+
+ {webcamSizePreset}% +
+
+ onWebcamSizePresetChange?.(values[0])} + onValueCommit={() => onWebcamSizePresetCommit?.()} + min={10} + max={50} + step={1} + className="w-full" + /> +
+ )} )} @@ -856,6 +1002,181 @@ export function SettingsPanel({
+ {cursorHighlight && onCursorHighlightChange && ( +
+
+
Cursor highlight
+ +
+
+ {(["dot", "ring"] as const).map((style) => ( + + ))} +
+
+
+
Size
+ + {cursorHighlight.sizePx}px + +
+ + onCursorHighlightChange({ ...cursorHighlight, sizePx: values[0] }) + } + min={10} + max={36} + step={1} + className="w-full [&_[role=slider]]:bg-[#34B27B] [&_[role=slider]]:border-[#34B27B] [&_[role=slider]]:h-3 [&_[role=slider]]:w-3" + /> +
+ {cursorHighlightSupportsClicks && ( +
+
Only on clicks
+ +
+ )} +
+
Color
+ + + + + + + onCursorHighlightChange({ ...cursorHighlight, color }) + } + /> + + +
+
+
+
Offset X (window recordings)
+ + {(cursorHighlight.offsetXNorm * 100).toFixed(1)}% + +
+ + onCursorHighlightChange({ + ...cursorHighlight, + offsetXNorm: values[0], + }) + } + min={-0.25} + max={0.25} + step={0.005} + className="w-full [&_[role=slider]]:bg-[#34B27B] [&_[role=slider]]:border-[#34B27B] [&_[role=slider]]:h-3 [&_[role=slider]]:w-3" + /> +
+
+
+
Offset Y
+ + {(cursorHighlight.offsetYNorm * 100).toFixed(1)}% + +
+ + onCursorHighlightChange({ + ...cursorHighlight, + offsetYNorm: values[0], + }) + } + min={-0.25} + max={0.25} + step={0.005} + className="w-full [&_[role=slider]]:bg-[#34B27B] [&_[role=slider]]:border-[#34B27B] [&_[role=slider]]:h-3 [&_[role=slider]]:w-3" + /> +
+
+ )} + -
- {hasConflict && conflict?.conflictWith.type === "configurable" && ( -
- - ⚠{" "} - {t("alreadyUsedBy", { action: t(`actions.${conflict.conflictWith.action}`) })} - -
- - -
+
+
+

+ {t("configurable")} +

+ {SHORTCUT_ACTIONS.map((action) => { + const isCapturing = captureFor === action; + const hasConflict = conflict?.forAction === action; + return ( +
+
+ {t(`actions.${action}`)} +
- )} + {hasConflict && conflict?.conflictWith.type === "configurable" && ( +
+ + ⚠{" "} + {t("alreadyUsedBy", { + action: t(`actions.${conflict.conflictWith.action}`), + })} + +
+ + +
+
+ )} +
+ ); + })} +
+ +
+

+ {t("fixed")} +

+ {FIXED_SHORTCUTS.map(({ i18nKey, label, display }) => ( +
+ + {t(`fixedActions.${i18nKey}`, { defaultValue: label })} + + + {display} +
- ); - })} + ))} +
+ +

{t("helpText")}

-
-

- {t("fixed")} -

- {FIXED_SHORTCUTS.map(({ label, display }) => ( -
- {label} - - {display} - -
- ))} -
- -

{t("helpText")}

- - +
@@ -1418,6 +1738,34 @@ export default function VideoEditor() { return (
+ + + + {t("newRecording.title")} + {t("newRecording.description")} + + + + + + + +
- {SUPPORTED_LOCALES.map((loc) => ( + {availableLocales.map((loc) => ( ))}
+
@@ -1580,18 +1946,25 @@ export default function VideoEditor() { onSpeedDelete={handleSpeedDelete} selectedSpeedId={selectedSpeedId} onSelectSpeed={handleSelectSpeed} - annotationRegions={annotationRegions} + annotationRegions={annotationOnlyRegions} onAnnotationAdded={handleAnnotationAdded} onAnnotationSpanChange={handleAnnotationSpanChange} onAnnotationDelete={handleAnnotationDelete} selectedAnnotationId={selectedAnnotationId} onSelectAnnotation={handleSelectAnnotation} + blurRegions={blurRegions} + onBlurAdded={handleBlurAdded} + onBlurSpanChange={handleAnnotationSpanChange} + onBlurDelete={handleAnnotationDelete} + selectedBlurId={selectedBlurId} + onSelectBlur={handleSelectBlur} aspectRatio={aspectRatio} onAspectRatioChange={(ar) => pushState({ aspectRatio: ar, webcamLayoutPreset: - !isPortraitAspectRatio(ar) && webcamLayoutPreset === "vertical-stack" + (isPortraitAspectRatio(ar) && webcamLayoutPreset === "dual-frame") || + (!isPortraitAspectRatio(ar) && webcamLayoutPreset === "vertical-stack") ? "picture-in-picture" : webcamLayoutPreset, }) @@ -1605,6 +1978,9 @@ export default function VideoEditor() { {/* Right section: settings panel */}
pushState({ cursorHighlight: next })} + cursorHighlightSupportsClicks={isMac} selected={wallpaper} onWallpaperChange={(w) => pushState({ wallpaper: w })} selectedZoomDepth={ @@ -1644,11 +2020,14 @@ export default function VideoEditor() { onWebcamLayoutPresetChange={(preset) => pushState({ webcamLayoutPreset: preset, - webcamPosition: preset === "vertical-stack" ? null : webcamPosition, + webcamPosition: preset === "picture-in-picture" ? webcamPosition : null, }) } webcamMaskShape={webcamMaskShape} onWebcamMaskShapeChange={(shape) => pushState({ webcamMaskShape: shape })} + webcamSizePreset={webcamSizePreset} + onWebcamSizePresetChange={(v) => updateState({ webcamSizePreset: v })} + onWebcamSizePresetCommit={commitState} videoElement={videoPlaybackRef.current?.video || null} exportQuality={exportQuality} onExportQualityChange={setExportQuality} @@ -1675,12 +2054,18 @@ export default function VideoEditor() { )} onExport={handleOpenExportDialog} selectedAnnotationId={selectedAnnotationId} - annotationRegions={annotationRegions} + annotationRegions={annotationOnlyRegions} onAnnotationContentChange={handleAnnotationContentChange} onAnnotationTypeChange={handleAnnotationTypeChange} onAnnotationStyleChange={handleAnnotationStyleChange} onAnnotationFigureDataChange={handleAnnotationFigureDataChange} + onAnnotationDuplicate={handleAnnotationDuplicate} onAnnotationDelete={handleAnnotationDelete} + selectedBlurId={selectedBlurId} + blurRegions={blurRegions} + onBlurDataChange={handleBlurDataPanelChange} + onBlurDataCommit={commitState} + onBlurDelete={handleAnnotationDelete} selectedSpeedId={selectedSpeedId} selectedSpeedValue={ selectedSpeedId diff --git a/src/components/video-editor/VideoPlayback.tsx b/src/components/video-editor/VideoPlayback.tsx index d659afe..a69c8d7 100644 --- a/src/components/video-editor/VideoPlayback.tsx +++ b/src/components/video-editor/VideoPlayback.tsx @@ -18,13 +18,14 @@ import { useRef, useState, } from "react"; -import { getAssetPath } from "@/lib/assetPath"; import { getWebcamLayoutCssBoxShadow, type Size, type StyledRenderRect, type WebcamLayoutPreset, + type WebcamSizePreset, } from "@/lib/compositeLayout"; +import { classifyWallpaper, DEFAULT_WALLPAPER, resolveImageWallpaperUrl } from "@/lib/wallpaper"; import { getCssClipPath } from "@/lib/webcamMaskShapes"; import { type AspectRatio, @@ -34,6 +35,7 @@ import { import { AnnotationOverlay } from "./AnnotationOverlay"; import { type AnnotationRegion, + type BlurData, type SpeedRegion, type TrimRegion, ZOOM_DEPTH_SCALES, @@ -49,7 +51,17 @@ import { ZOOM_SCALE_DEADZONE, ZOOM_TRANSLATION_DEADZONE_PX, } from "./videoPlayback/constants"; -import { adaptiveSmoothFactor, smoothCursorFocus } from "./videoPlayback/cursorFollowUtils"; +import { + adaptiveSmoothFactor, + interpolateCursorAt, + smoothCursorFocus, +} from "./videoPlayback/cursorFollowUtils"; +import { + type CursorHighlightConfig, + clickEmphasisAlpha, + DEFAULT_CURSOR_HIGHLIGHT, + drawCursorHighlightGraphics, +} from "./videoPlayback/cursorHighlight"; import { clampFocusToStage as clampFocusToStageUtil } from "./videoPlayback/focusUtils"; import { layoutVideoContent as layoutVideoContentUtil } from "./videoPlayback/layoutUtils"; import { clamp01 } from "./videoPlayback/mathUtils"; @@ -69,6 +81,7 @@ interface VideoPlaybackProps { webcamVideoPath?: string; webcamLayoutPreset: WebcamLayoutPreset; webcamMaskShape?: import("./types").WebcamMaskShape; + webcamSizePreset?: WebcamSizePreset; webcamPosition?: { cx: number; cy: number } | null; onWebcamPositionChange?: (position: { cx: number; cy: number }) => void; onWebcamPositionDragEnd?: () => void; @@ -99,7 +112,16 @@ interface VideoPlaybackProps { onSelectAnnotation?: (id: string | null) => void; onAnnotationPositionChange?: (id: string, position: { x: number; y: number }) => void; onAnnotationSizeChange?: (id: string, size: { width: number; height: number }) => void; + blurRegions?: AnnotationRegion[]; + selectedBlurId?: string | null; + onSelectBlur?: (id: string | null) => void; + onBlurPositionChange?: (id: string, position: { x: number; y: number }) => void; + onBlurSizeChange?: (id: string, size: { width: number; height: number }) => void; + onBlurDataChange?: (id: string, blurData: BlurData) => void; + onBlurDataCommit?: () => void; cursorTelemetry?: import("./types").CursorTelemetryPoint[]; + cursorHighlight?: CursorHighlightConfig; + cursorClickTimestamps?: number[]; } export interface VideoPlaybackRef { @@ -119,6 +141,7 @@ const VideoPlayback = forwardRef( webcamVideoPath, webcamLayoutPreset, webcamMaskShape, + webcamSizePreset, webcamPosition, onWebcamPositionChange, onWebcamPositionDragEnd, @@ -149,7 +172,16 @@ const VideoPlayback = forwardRef( onSelectAnnotation, onAnnotationPositionChange, onAnnotationSizeChange, + blurRegions = [], + selectedBlurId, + onSelectBlur, + onBlurPositionChange, + onBlurSizeChange, + onBlurDataChange, + onBlurDataCommit, cursorTelemetry = [], + cursorHighlight = DEFAULT_CURSOR_HIGHLIGHT, + cursorClickTimestamps = [], }, ref, ) => { @@ -163,13 +195,19 @@ const VideoPlayback = forwardRef( const timeUpdateAnimationRef = useRef(null); const [pixiReady, setPixiReady] = useState(false); const [videoReady, setVideoReady] = useState(false); + const [overlaySize, setOverlaySize] = useState({ width: 800, height: 600 }); + const [overlayElement, setOverlayElement] = useState(null); const overlayRef = useRef(null); + const focusIndicatorRef = useRef(null); const [webcamLayout, setWebcamLayout] = useState(null); const [webcamDimensions, setWebcamDimensions] = useState(null); const currentTimeRef = useRef(0); const zoomRegionsRef = useRef([]); const cursorTelemetryRef = useRef([]); + const cursorHighlightRef = useRef(DEFAULT_CURSOR_HIGHLIGHT); + const cursorClickTimestampsRef = useRef([]); + const cursorHighlightGraphicsRef = useRef(null); const selectedZoomIdRef = useRef(null); const animationStateRef = useRef({ scale: 1, @@ -195,7 +233,10 @@ const VideoPlayback = forwardRef( const isPlayingRef = useRef(isPlaying); const isSeekingRef = useRef(false); const allowPlaybackRef = useRef(false); - const lockedVideoDimensionsRef = useRef<{ width: number; height: number } | null>(null); + const lockedVideoDimensionsRef = useRef<{ + width: number; + height: number; + } | null>(null); const layoutVideoContentRef = useRef<(() => void) | null>(null); const trimRegionsRef = useRef([]); const speedRegionsRef = useRef([]); @@ -283,6 +324,7 @@ const VideoPlayback = forwardRef( padding, webcamDimensions, webcamLayoutPreset, + webcamSizePreset, webcamPosition, webcamMaskShape, }); @@ -314,6 +356,7 @@ const VideoPlayback = forwardRef( padding, webcamDimensions, webcamLayoutPreset, + webcamSizePreset, webcamPosition, webcamMaskShape, ]); @@ -322,6 +365,11 @@ const VideoPlayback = forwardRef( layoutVideoContentRef.current = layoutVideoContent; }, [layoutVideoContent]); + const setOverlayRefs = useCallback((node: HTMLDivElement | null) => { + overlayRef.current = node; + setOverlayElement(node); + }, []); + const selectedZoom = useMemo(() => { if (!selectedZoomId) return null; return zoomRegions.find((region) => region.id === selectedZoomId) ?? null; @@ -338,7 +386,10 @@ const VideoPlayback = forwardRef( if (!vid) return; try { allowPlaybackRef.current = true; - await vid.play(); + await vid.play().catch((err) => { + console.log("PLAY ERROR:", err); + throw err; + }); } catch (error) { allowPlaybackRef.current = false; throw error; @@ -481,6 +532,17 @@ const VideoPlayback = forwardRef( cursorTelemetryRef.current = cursorTelemetry; }, [cursorTelemetry]); + useEffect(() => { + cursorHighlightRef.current = cursorHighlight; + if (cursorHighlightGraphicsRef.current) { + drawCursorHighlightGraphics(cursorHighlightGraphicsRef.current, cursorHighlight); + } + }, [cursorHighlight]); + + useEffect(() => { + cursorClickTimestampsRef.current = cursorClickTimestamps; + }, [cursorClickTimestamps]); + useEffect(() => { selectedZoomIdRef.current = selectedZoomId; }, [selectedZoomId]); @@ -511,84 +573,24 @@ const VideoPlayback = forwardRef( useEffect(() => { if (!pixiReady || !videoReady) return; + const el = overlayRef.current; + if (!el) return; - const app = appRef.current; - const cameraContainer = cameraContainerRef.current; - const video = videoRef.current; + // Seed immediately so overlays never start at 800×600 + setOverlaySize({ width: el.clientWidth, height: el.clientHeight }); - if (!app || !cameraContainer || !video) return; - - const tickerWasStarted = app.ticker?.started || false; - if (tickerWasStarted && app.ticker) { - app.ticker.stop(); - } - - const wasPlaying = !video.paused; - if (wasPlaying) { - video.pause(); - } - - animationStateRef.current = { - scale: 1, - focusX: DEFAULT_FOCUS.cx, - focusY: DEFAULT_FOCUS.cy, - progress: 0, - x: 0, - y: 0, - appliedScale: 1, - }; - - // Reset motion blur state for clean transitions - motionBlurStateRef.current = createMotionBlurState(); - - if (blurFilterRef.current) { - blurFilterRef.current.blur = 0; - } - - requestAnimationFrame(() => { - const container = cameraContainerRef.current; - const videoStage = videoContainerRef.current; - const sprite = videoSpriteRef.current; - const currentApp = appRef.current; - if (!container || !videoStage || !sprite || !currentApp) { - return; - } - - container.scale.set(1); - container.position.set(0, 0); - videoStage.scale.set(1); - videoStage.position.set(0, 0); - sprite.scale.set(1); - sprite.position.set(0, 0); - - layoutVideoContent(); - - applyZoomTransform({ - cameraContainer: container, - blurFilter: blurFilterRef.current, - stageSize: stageSizeRef.current, - baseMask: baseMaskRef.current, - zoomScale: 1, - focusX: DEFAULT_FOCUS.cx, - focusY: DEFAULT_FOCUS.cy, - motionIntensity: 0, - isPlaying: false, - motionBlurAmount: motionBlurAmountRef.current, - }); - - requestAnimationFrame(() => { - const finalApp = appRef.current; - if (wasPlaying && video) { - video.play().catch(() => { - // Ignore autoplay restoration failures. - }); - } - if (tickerWasStarted && finalApp?.ticker) { - finalApp.ticker.start(); - } + const observer = new ResizeObserver((entries) => { + if (!entries[0]) return; + const { width, height } = entries[0].contentRect; + setOverlaySize((prev) => { + if (prev.width === width && prev.height === height) return prev; + return { width, height }; }); }); - }, [pixiReady, videoReady, layoutVideoContent]); + + observer.observe(el); + return () => observer.disconnect(); + }, [pixiReady, videoReady]); useEffect(() => { if (!pixiReady || !videoReady) return; @@ -615,7 +617,8 @@ const VideoPlayback = forwardRef( }, [selectedZoom, pixiReady, videoReady, updateOverlayForRegion]); useEffect(() => { - const overlayEl = overlayRef.current; + if (!pixiReady || !videoReady) return; + const overlayEl = overlayElement; if (!overlayEl) return; if (!selectedZoom) { overlayEl.style.cursor = "default"; @@ -624,7 +627,34 @@ const VideoPlayback = forwardRef( } overlayEl.style.cursor = isPlaying ? "not-allowed" : "grab"; overlayEl.style.pointerEvents = isPlaying ? "none" : "auto"; - }, [selectedZoom, isPlaying]); + }, [selectedZoom, isPlaying, pixiReady, videoReady, overlayElement]); + + useEffect(() => { + const overlayEl = overlayElement; + if (!overlayEl) return; + + const updateOverlaySize = () => { + const width = overlayEl.clientWidth || 800; + const height = overlayEl.clientHeight || 600; + setOverlaySize((prev) => { + if (prev.width === width && prev.height === height) return prev; + return { width, height }; + }); + }; + + updateOverlaySize(); + + if (typeof ResizeObserver !== "undefined") { + const observer = new ResizeObserver(() => { + updateOverlaySize(); + }); + observer.observe(overlayEl); + return () => observer.disconnect(); + } + + window.addEventListener("resize", updateOverlaySize); + return () => window.removeEventListener("resize", updateOverlaySize); + }, [overlayElement]); useEffect(() => { const container = containerRef.current; @@ -648,7 +678,11 @@ const VideoPlayback = forwardRef( app.ticker.maxFPS = 60; if (!mounted) { - app.destroy(true, { children: true, texture: true, textureSource: true }); + app.destroy(true, { + children: true, + texture: true, + textureSource: true, + }); return; } @@ -672,7 +706,11 @@ const VideoPlayback = forwardRef( mounted = false; setPixiReady(false); if (app && app.renderer) { - app.destroy(true, { children: true, texture: true, textureSource: true }); + app.destroy(true, { + children: true, + texture: true, + textureSource: true, + }); } appRef.current = null; cameraContainerRef.current = null; @@ -728,6 +766,12 @@ const VideoPlayback = forwardRef( videoContainer.mask = maskGraphics; maskGraphicsRef.current = maskGraphics; + const cursorHighlightGraphics = new Graphics(); + cursorHighlightGraphics.visible = false; + videoContainer.addChild(cursorHighlightGraphics); + cursorHighlightGraphicsRef.current = cursorHighlightGraphics; + drawCursorHighlightGraphics(cursorHighlightGraphics, cursorHighlightRef.current); + animationStateRef.current = { scale: 1, focusX: DEFAULT_FOCUS.cx, @@ -743,7 +787,6 @@ const VideoPlayback = forwardRef( blurFilter.resolution = app.renderer.resolution; blurFilter.blur = 0; const motionBlurFilter = new MotionBlurFilter([0, 0], 5, 0); - videoContainer.filters = [blurFilter, motionBlurFilter]; blurFilterRef.current = blurFilter; motionBlurFilterRef.current = motionBlurFilter; @@ -788,10 +831,15 @@ const VideoPlayback = forwardRef( videoContainer.removeChild(maskGraphics); maskGraphics.destroy(); } + if (cursorHighlightGraphicsRef.current) { + videoContainer.removeChild(cursorHighlightGraphicsRef.current); + cursorHighlightGraphicsRef.current.destroy(); + cursorHighlightGraphicsRef.current = null; + } videoContainer.mask = null; maskGraphicsRef.current = null; if (blurFilterRef.current) { - videoContainer.filters = []; + videoContainer.filters = null; blurFilterRef.current.destroy(); blurFilterRef.current = null; } @@ -848,17 +896,15 @@ const VideoPlayback = forwardRef( state.appliedScale = appliedTransform.scale; }; + let lastMotionBlurActive: boolean | null = null; const ticker = () => { - const bm = baseMaskRef.current; - const ss = stageSizeRef.current; - const viewportRatio = - bm.width > 0 && bm.height > 0 - ? { widthRatio: ss.width / bm.width, heightRatio: ss.height / bm.height } - : undefined; const { region, strength, blendedScale, transition } = findDominantRegion( zoomRegionsRef.current, currentTimeRef.current, - { connectZooms: true, cursorTelemetry: cursorTelemetryRef.current, viewportRatio }, + { + connectZooms: true, + cursorTelemetry: cursorTelemetryRef.current, + }, ); const defaultFocus = DEFAULT_FOCUS; @@ -1008,6 +1054,56 @@ const VideoPlayback = forwardRef( motionIntensity, motionVector, ); + + const cursorGraphics = cursorHighlightGraphicsRef.current; + const cursorConfig = cursorHighlightRef.current; + const lockedDims = lockedVideoDimensionsRef.current; + if (cursorGraphics) { + if (cursorConfig.enabled && lockedDims && cursorTelemetryRef.current.length > 0) { + const emphasisAlpha = clickEmphasisAlpha( + currentTimeRef.current, + cursorClickTimestampsRef.current, + cursorConfig, + ); + const cursorPoint = + emphasisAlpha > 0 + ? interpolateCursorAt(cursorTelemetryRef.current, currentTimeRef.current) + : null; + if (cursorPoint) { + const baseScale = baseScaleRef.current; + const baseOffset = baseOffsetRef.current; + const cx = cursorPoint.cx + cursorConfig.offsetXNorm; + const cy = cursorPoint.cy + cursorConfig.offsetYNorm; + cursorGraphics.position.set( + baseOffset.x + cx * lockedDims.width * baseScale, + baseOffset.y + cy * lockedDims.height * baseScale, + ); + cursorGraphics.alpha = emphasisAlpha; + cursorGraphics.visible = true; + } else { + cursorGraphics.visible = false; + } + } else { + cursorGraphics.visible = false; + } + } + + const isMotionBlurActive = (motionBlurAmountRef.current || 0) > 0 && isPlayingRef.current; + + if (isMotionBlurActive !== lastMotionBlurActive && videoContainerRef.current) { + if (isMotionBlurActive) { + if (blurFilterRef.current && motionBlurFilterRef.current) { + videoContainerRef.current.filters = [ + blurFilterRef.current, + motionBlurFilterRef.current, + ]; + lastMotionBlurActive = true; + } + } else { + videoContainerRef.current.filters = null; + lastMotionBlurActive = false; + } + } }; app.ticker.add(ticker); @@ -1045,7 +1141,17 @@ const VideoPlayback = forwardRef( videoReadyRafRef.current = requestAnimationFrame(waitForRenderableFrame); }; - const [resolvedWallpaper, setResolvedWallpaper] = useState(null); + const resolvedWallpaper = useMemo(() => { + const source = wallpaper || DEFAULT_WALLPAPER; + const classified = classifyWallpaper(source); + if (classified.kind !== "image") return classified.value; + try { + return resolveImageWallpaperUrl(classified.path); + } catch (err) { + console.warn("[VideoPlayback] wallpaper resolve failed:", err); + return null; + } + }, [wallpaper]); const webcamCssBoxShadow = useMemo( () => getWebcamLayoutCssBoxShadow(webcamLayoutPreset), [webcamLayoutPreset], @@ -1113,58 +1219,6 @@ const VideoPlayback = forwardRef( webcamVideo.currentTime = 0; }, [webcamVideoPath]); - useEffect(() => { - let mounted = true; - (async () => { - try { - if (!wallpaper) { - const def = await getAssetPath("wallpapers/wallpaper1.jpg"); - if (mounted) setResolvedWallpaper(def); - return; - } - - if ( - wallpaper.startsWith("#") || - wallpaper.startsWith("linear-gradient") || - wallpaper.startsWith("radial-gradient") - ) { - if (mounted) setResolvedWallpaper(wallpaper); - return; - } - - // If it's a data URL (custom uploaded image), use as-is - if (wallpaper.startsWith("data:")) { - if (mounted) setResolvedWallpaper(wallpaper); - return; - } - - // If it's an absolute web/http or file path, use as-is - if ( - wallpaper.startsWith("http") || - wallpaper.startsWith("file://") || - wallpaper.startsWith("/") - ) { - // If it's an absolute server path (starts with '/'), resolve via getAssetPath as well - if (wallpaper.startsWith("/")) { - const rel = wallpaper.replace(/^\//, ""); - const p = await getAssetPath(rel); - if (mounted) setResolvedWallpaper(p); - return; - } - if (mounted) setResolvedWallpaper(wallpaper); - return; - } - const p = await getAssetPath(wallpaper.replace(/^\//, "")); - if (mounted) setResolvedWallpaper(p); - } catch (_err) { - if (mounted) setResolvedWallpaper(wallpaper || "/wallpapers/wallpaper1.jpg"); - } - })(); - return () => { - mounted = false; - }; - }, [wallpaper]); - useEffect(() => { return () => { if (videoReadyRafRef.current) { @@ -1264,9 +1318,9 @@ const VideoPlayback = forwardRef( {/* Only render overlay after PIXI and video are fully initialized */} {pixiReady && videoReady && (
( style={{ display: "none", pointerEvents: "none" }} /> {(() => { - const filtered = (annotationRegions || []).filter((annotation) => { + const filteredAnnotations = (annotationRegions || []).filter((annotation) => { if (typeof annotation.startMs !== "number" || typeof annotation.endMs !== "number") return false; if (annotation.id === selectedAnnotationId) return true; const timeMs = Math.round(currentTime * 1000); - return timeMs >= annotation.startMs && timeMs <= annotation.endMs; + return timeMs >= annotation.startMs && timeMs < annotation.endMs; }); - // Sort by z-index (lowest to highest) so higher z-index renders on top - const sorted = [...filtered].sort((a, b) => a.zIndex - b.zIndex); + const filteredBlurRegions = (blurRegions || []).filter((blurRegion) => { + if (typeof blurRegion.startMs !== "number" || typeof blurRegion.endMs !== "number") + return false; + + if (blurRegion.id === selectedBlurId) return true; + + const timeMs = Math.round(currentTime * 1000); + return timeMs >= blurRegion.startMs && timeMs < blurRegion.endMs; + }); + + const sorted = [ + ...filteredAnnotations.map((annotation) => ({ + kind: "annotation" as const, + region: annotation, + })), + ...filteredBlurRegions.map((blurRegion) => ({ + kind: "blur" as const, + region: blurRegion, + })), + ].sort((a, b) => a.region.zIndex - b.region.zIndex); + const previewSnapshotCanvas = + filteredBlurRegions.length > 0 + ? (() => { + const app = appRef.current; + if (!app?.renderer?.extract) return null; + try { + return app.renderer.extract.canvas(app.stage); + } catch { + return null; + } + })() + : null; // Handle click-through cycling: when clicking same annotation, cycle to next const handleAnnotationClick = (clickedId: string) => { if (!onSelectAnnotation) return; // If clicking on already selected annotation and there are multiple overlapping - if (clickedId === selectedAnnotationId && sorted.length > 1) { + if (clickedId === selectedAnnotationId && filteredAnnotations.length > 1) { // Find current index and cycle to next - const currentIndex = sorted.findIndex((a) => a.id === clickedId); - const nextIndex = (currentIndex + 1) % sorted.length; - onSelectAnnotation(sorted[nextIndex].id); + const currentIndex = filteredAnnotations.findIndex((a) => a.id === clickedId); + const nextIndex = (currentIndex + 1) % filteredAnnotations.length; + onSelectAnnotation(filteredAnnotations[nextIndex].id); } else { // First click or clicking different annotation onSelectAnnotation(clickedId); } }; - return sorted.map((annotation) => ( + const handleBlurClick = (clickedId: string) => { + if (!onSelectBlur) return; + + if (clickedId === selectedBlurId && filteredBlurRegions.length > 1) { + const currentIndex = filteredBlurRegions.findIndex((a) => a.id === clickedId); + const nextIndex = (currentIndex + 1) % filteredBlurRegions.length; + onSelectBlur(filteredBlurRegions[nextIndex].id); + } else { + onSelectBlur(clickedId); + } + }; + + return sorted.map((item) => ( onAnnotationPositionChange?.(id, position)} - onSizeChange={(id, size) => onAnnotationSizeChange?.(id, size)} - onClick={handleAnnotationClick} - zIndex={annotation.zIndex} - isSelectedBoost={annotation.id === selectedAnnotationId} + key={ + item.kind === "blur" + ? `${item.region.id}-${overlaySize.width}-${overlaySize.height}-${item.region.blurData?.type ?? "blur"}-${item.region.blurData?.shape ?? "rectangle"}-${item.region.blurData?.color ?? "white"}-${Math.round(item.region.blurData?.blockSize ?? 0)}-${Math.round(item.region.blurData?.intensity ?? 0)}-${(item.region.blurData?.freehandPoints ?? []).map((p) => `${Math.round(p.x)}_${Math.round(p.y)}`).join("-")}` + : `${item.region.id}-${overlaySize.width}-${overlaySize.height}` + } + annotation={item.region} + isSelected={ + item.kind === "blur" + ? item.region.id === selectedBlurId + : item.region.id === selectedAnnotationId + } + containerWidth={overlaySize.width} + containerHeight={overlaySize.height} + onPositionChange={(id, position) => + item.kind === "blur" + ? onBlurPositionChange?.(id, position) + : onAnnotationPositionChange?.(id, position) + } + onSizeChange={(id, size) => + item.kind === "blur" + ? onBlurSizeChange?.(id, size) + : onAnnotationSizeChange?.(id, size) + } + onBlurDataChange={ + item.kind === "blur" + ? (id, blurData) => onBlurDataChange?.(id, blurData) + : undefined + } + onBlurDataCommit={item.kind === "blur" ? onBlurDataCommit : undefined} + onClick={item.kind === "blur" ? handleBlurClick : handleAnnotationClick} + zIndex={item.region.zIndex} + isSelectedBoost={ + item.kind === "blur" + ? item.region.id === selectedBlurId + : item.region.id === selectedAnnotationId + } + previewSourceCanvas={previewSnapshotCanvas} + previewFrameVersion={Math.round(currentTime * 1000)} /> )); })()} diff --git a/src/components/video-editor/projectPersistence.test.ts b/src/components/video-editor/projectPersistence.test.ts index 3243aca..8a17b9e 100644 --- a/src/components/video-editor/projectPersistence.test.ts +++ b/src/components/video-editor/projectPersistence.test.ts @@ -1,6 +1,8 @@ import { describe, expect, it } from "vitest"; import { createProjectData, + createProjectSnapshot, + hasProjectUnsavedChanges, normalizeProjectEditor, PROJECT_VERSION, resolveProjectMedia, @@ -42,6 +44,7 @@ describe("projectPersistence media compatibility", () => { aspectRatio: "16:9", webcamLayoutPreset: "picture-in-picture", webcamMaskShape: "circle", + webcamPosition: null, exportQuality: "good", exportFormat: "mp4", gifFrameRate: 15, @@ -64,4 +67,192 @@ describe("projectPersistence media compatibility", () => { normalizeProjectEditor({ webcamMaskShape: "not-a-real-shape" as never }).webcamMaskShape, ).toBe("rectangle"); }); + + it("normalizes blur region type and mosaic block size safely", () => { + const editor = normalizeProjectEditor({ + annotationRegions: [ + { + id: "annotation-1", + startMs: 0, + endMs: 500, + type: "blur", + content: "", + position: { x: 10, y: 10 }, + size: { width: 20, height: 20 }, + style: { + color: "#fff", + backgroundColor: "transparent", + fontSize: 32, + fontFamily: "Inter", + fontWeight: "bold", + fontStyle: "normal", + textDecoration: "none", + textAlign: "center", + }, + zIndex: 1, + blurData: { + type: "mosaic", + shape: "rectangle", + color: "black", + intensity: 999, + blockSize: 999, + }, + }, + { + id: "annotation-2", + startMs: 0, + endMs: 500, + type: "blur", + content: "", + position: { x: 10, y: 10 }, + size: { width: 20, height: 20 }, + style: { + color: "#fff", + backgroundColor: "transparent", + fontSize: 32, + fontFamily: "Inter", + fontWeight: "bold", + fontStyle: "normal", + textDecoration: "none", + textAlign: "center", + }, + zIndex: 2, + blurData: { + type: "invalid" as never, + shape: "rectangle", + color: "invalid" as never, + intensity: 10, + blockSize: 0, + }, + }, + ], + }); + + expect(editor.annotationRegions[0].blurData?.type).toBe("mosaic"); + expect(editor.annotationRegions[0].blurData?.color).toBe("black"); + expect(editor.annotationRegions[0].blurData?.intensity).toBe(40); + expect(editor.annotationRegions[0].blurData?.blockSize).toBe(48); + expect(editor.annotationRegions[1].blurData?.type).toBe("blur"); + expect(editor.annotationRegions[1].blurData?.color).toBe("white"); + expect(editor.annotationRegions[1].blurData?.blockSize).toBe(4); + }); + + it("accepts the dual frame webcam layout preset", () => { + expect(normalizeProjectEditor({ webcamLayoutPreset: "dual-frame" }).webcamLayoutPreset).toBe( + "dual-frame", + ); + }); + + it("falls back from dual frame to picture in picture for portrait aspect ratios", () => { + expect( + normalizeProjectEditor({ + aspectRatio: "9:16", + webcamLayoutPreset: "dual-frame", + }).webcamLayoutPreset, + ).toBe("picture-in-picture"); + }); + + it("clears webcamPosition when the normalized preset is not picture in picture", () => { + expect( + normalizeProjectEditor({ + webcamLayoutPreset: "dual-frame", + webcamPosition: { cx: 0.2, cy: 0.8 }, + }).webcamPosition, + ).toBeNull(); + }); +}); + +it("creates stable snapshots for identical project state", () => { + const media = { + screenVideoPath: "/tmp/screen.webm", + webcamVideoPath: "/tmp/webcam.webm", + }; + const editor = normalizeProjectEditor({ + wallpaper: "/wallpapers/wallpaper1.jpg", + shadowIntensity: 0, + showBlur: false, + motionBlurAmount: 0, + borderRadius: 0, + padding: 50, + cropRegion: { x: 0, y: 0, width: 1, height: 1 }, + zoomRegions: [], + trimRegions: [], + speedRegions: [], + annotationRegions: [], + aspectRatio: "16:9", + webcamLayoutPreset: "picture-in-picture", + webcamMaskShape: "circle", + exportQuality: "good", + exportFormat: "mp4", + gifFrameRate: 15, + gifLoop: true, + gifSizePreset: "medium", + }); + + expect(createProjectSnapshot(media, editor)).toBe(createProjectSnapshot(media, editor)); +}); + +it("detects unsaved changes from differing snapshots", () => { + expect(hasProjectUnsavedChanges(null, null)).toBe(false); + expect(hasProjectUnsavedChanges("same", "same")).toBe(false); + expect(hasProjectUnsavedChanges("current", "baseline")).toBe(true); +}); + +describe("wallpaper legacy normalization", () => { + it("rewrites pre-fix packaged paths (resources/assets/wallpapers/…)", () => { + const normalized = normalizeProjectEditor({ + wallpaper: "file:///opt/Openscreen/resources/assets/wallpapers/wallpaper5.jpg", + }); + expect(normalized.wallpaper).toBe("/wallpapers/wallpaper5.jpg"); + }); + + it("rewrites new packaged layout (resources/wallpapers/…)", () => { + const normalized = normalizeProjectEditor({ + wallpaper: "file:///opt/Openscreen/resources/wallpapers/wallpaper3.jpg", + }); + expect(normalized.wallpaper).toBe("/wallpapers/wallpaper3.jpg"); + }); + + it("rewrites unpackaged dev layout (public/wallpapers/…)", () => { + const normalized = normalizeProjectEditor({ + wallpaper: "file:///home/user/project/public/wallpapers/wallpaper1.jpg", + }); + expect(normalized.wallpaper).toBe("/wallpapers/wallpaper1.jpg"); + }); + + it("rewrites Windows-style file URLs with drive letter", () => { + const normalized = normalizeProjectEditor({ + wallpaper: "file:///C:/Users/me/openscreen/resources/wallpapers/wallpaper2.jpg", + }); + expect(normalized.wallpaper).toBe("/wallpapers/wallpaper2.jpg"); + }); + + it("leaves canonical relative paths untouched", () => { + const normalized = normalizeProjectEditor({ wallpaper: "/wallpapers/wallpaper2.jpg" }); + expect(normalized.wallpaper).toBe("/wallpapers/wallpaper2.jpg"); + }); + + it("leaves data URIs untouched", () => { + const dataUri = "data:image/png;base64,AAA"; + expect(normalizeProjectEditor({ wallpaper: dataUri }).wallpaper).toBe(dataUri); + }); + + it("leaves colors and gradients untouched", () => { + expect(normalizeProjectEditor({ wallpaper: "#1a1a2e" }).wallpaper).toBe("#1a1a2e"); + expect( + normalizeProjectEditor({ wallpaper: "linear-gradient(90deg, red, blue)" }).wallpaper, + ).toBe("linear-gradient(90deg, red, blue)"); + }); + + it("does NOT rewrite user files outside the known install layout", () => { + const userPath = "file:///home/user/Pictures/wallpapers/wallpaper1.jpg"; + expect(normalizeProjectEditor({ wallpaper: userPath }).wallpaper).toBe(userPath); + }); + + it("falls back to default for bundled paths outside WALLPAPER_PATHS", () => { + const normalized = normalizeProjectEditor({ + wallpaper: "file:///opt/Openscreen/resources/wallpapers/wallpaper99.jpg", + }); + expect(normalized.wallpaper).toBe("/wallpapers/wallpaper1.jpg"); + }); }); diff --git a/src/components/video-editor/projectPersistence.ts b/src/components/video-editor/projectPersistence.ts index d7111b1..beabbe4 100644 --- a/src/components/video-editor/projectPersistence.ts +++ b/src/components/video-editor/projectPersistence.ts @@ -1,34 +1,60 @@ +import { normalizeBlurColor, normalizeBlurType } from "@/lib/blurEffects"; import type { ExportFormat, ExportQuality, GifFrameRate, GifSizePreset } from "@/lib/exporter"; import type { ProjectMedia } from "@/lib/recordingSession"; import { normalizeProjectMedia } from "@/lib/recordingSession"; -import { ASPECT_RATIOS, type AspectRatio } from "@/utils/aspectRatioUtils"; +import { DEFAULT_WALLPAPER, WALLPAPER_PATHS } from "@/lib/wallpaper"; +import { ASPECT_RATIOS, type AspectRatio, isPortraitAspectRatio } from "@/utils/aspectRatioUtils"; import { type AnnotationRegion, type CropRegion, + clampPlaybackSpeed, DEFAULT_ANNOTATION_POSITION, DEFAULT_ANNOTATION_SIZE, DEFAULT_ANNOTATION_STYLE, + DEFAULT_BLUR_BLOCK_SIZE, + DEFAULT_BLUR_DATA, + DEFAULT_BLUR_FREEHAND_POINTS, + DEFAULT_BLUR_INTENSITY, DEFAULT_CROP_REGION, DEFAULT_FIGURE_DATA, DEFAULT_PLAYBACK_SPEED, DEFAULT_WEBCAM_LAYOUT_PRESET, DEFAULT_WEBCAM_MASK_SHAPE, DEFAULT_WEBCAM_POSITION, + DEFAULT_WEBCAM_SIZE_PRESET, DEFAULT_ZOOM_DEPTH, + MAX_BLUR_BLOCK_SIZE, + MAX_BLUR_INTENSITY, + MAX_PLAYBACK_SPEED, + MIN_BLUR_BLOCK_SIZE, + MIN_BLUR_INTENSITY, + MIN_PLAYBACK_SPEED, type SpeedRegion, type TrimRegion, type WebcamLayoutPreset, type WebcamMaskShape, type WebcamPosition, + type WebcamSizePreset, type ZoomRegion, } from "./types"; -const WALLPAPER_COUNT = 18; +const VALID_BLUR_SHAPES = new Set(["rectangle", "oval", "freehand"] as const); -export const WALLPAPER_PATHS = Array.from( - { length: WALLPAPER_COUNT }, - (_, i) => `/wallpapers/wallpaper${i + 1}.jpg`, -); +// Pre-fix projects could persist resolved file:// URLs (machine-specific) for +// bundled wallpapers. Rewrite only paths that match a known install layout +// (resources/[assets/]wallpapers for packaged, public/wallpapers for dev) so +// a legitimate user file that happens to live in a folder named "wallpapers" +// elsewhere is never silently replaced. +const LEGACY_FILE_WALLPAPER_RE = + /^file:\/\/.*?\/(?:resources\/(?:assets\/)?|public\/)wallpapers\/(wallpaper\d+\.jpg)$/i; +const CANONICAL_WALLPAPERS = new Set(WALLPAPER_PATHS); + +function normalizeWallpaperValue(value: string): string { + const match = LEGACY_FILE_WALLPAPER_RE.exec(value); + if (!match) return value; + const canonical = `/wallpapers/${match[1]}`; + return CANONICAL_WALLPAPERS.has(canonical) ? canonical : DEFAULT_WALLPAPER; +} export const PROJECT_VERSION = 2; @@ -47,12 +73,14 @@ export interface ProjectEditorState { aspectRatio: AspectRatio; webcamLayoutPreset: WebcamLayoutPreset; webcamMaskShape: WebcamMaskShape; + webcamSizePreset: WebcamSizePreset; webcamPosition: WebcamPosition | null; exportQuality: ExportQuality; exportFormat: ExportFormat; gifFrameRate: GifFrameRate; gifLoop: boolean; gifSizePreset: GifSizePreset; + cursorHighlight: import("./videoPlayback/cursorHighlight").CursorHighlightConfig; } export interface EditorProjectData { @@ -66,6 +94,26 @@ function isFiniteNumber(value: unknown): value is number { return typeof value === "number" && Number.isFinite(value); } +function computeNormalizedWebcamLayoutPreset( + webcamLayoutPreset: Partial["webcamLayoutPreset"], + normalizedAspectRatio: AspectRatio, +): WebcamLayoutPreset { + switch (webcamLayoutPreset) { + case "picture-in-picture": + return webcamLayoutPreset; + case "vertical-stack": + return isPortraitAspectRatio(normalizedAspectRatio) + ? webcamLayoutPreset + : DEFAULT_WEBCAM_LAYOUT_PRESET; + case "dual-frame": + return isPortraitAspectRatio(normalizedAspectRatio) + ? DEFAULT_WEBCAM_LAYOUT_PRESET + : webcamLayoutPreset; + default: + return DEFAULT_WEBCAM_LAYOUT_PRESET; + } +} + function clamp(value: number, min: number, max: number) { return Math.min(max, Math.max(min, value)); } @@ -173,6 +221,26 @@ export function resolveProjectMedia( export function normalizeProjectEditor(editor: Partial): ProjectEditorState { const validAspectRatios = new Set(ASPECT_RATIOS); + const normalizedAspectRatio: AspectRatio = validAspectRatios.has( + editor.aspectRatio as AspectRatio, + ) + ? (editor.aspectRatio as AspectRatio) + : "16:9"; + const normalizedWebcamLayoutPreset = computeNormalizedWebcamLayoutPreset( + editor.webcamLayoutPreset, + normalizedAspectRatio, + ); + const normalizedWebcamPosition: WebcamPosition | null = + normalizedWebcamLayoutPreset === "picture-in-picture" && + editor.webcamPosition && + typeof editor.webcamPosition === "object" && + isFiniteNumber((editor.webcamPosition as WebcamPosition).cx) && + isFiniteNumber((editor.webcamPosition as WebcamPosition).cy) + ? { + cx: clamp((editor.webcamPosition as WebcamPosition).cx, 0, 1), + cy: clamp((editor.webcamPosition as WebcamPosition).cy, 0, 1), + } + : DEFAULT_WEBCAM_POSITION; const normalizedZoomRegions: ZoomRegion[] = Array.isArray(editor.zoomRegions) ? editor.zoomRegions @@ -223,14 +291,10 @@ export function normalizeProjectEditor(editor: Partial): Pro const endMs = Math.max(startMs + 1, rawEnd); const speed = - region.speed === 0.25 || - region.speed === 0.5 || - region.speed === 0.75 || - region.speed === 1.25 || - region.speed === 1.5 || - region.speed === 1.75 || - region.speed === 2 - ? region.speed + isFiniteNumber(region.speed) && + region.speed >= MIN_PLAYBACK_SPEED && + region.speed <= MAX_PLAYBACK_SPEED + ? clampPlaybackSpeed(region.speed) : DEFAULT_PLAYBACK_SPEED; return { @@ -252,12 +316,22 @@ export function normalizeProjectEditor(editor: Partial): Pro const rawEnd = isFiniteNumber(region.endMs) ? Math.round(region.endMs) : rawStart + 1000; const startMs = Math.max(0, Math.min(rawStart, rawEnd)); const endMs = Math.max(startMs + 1, rawEnd); + const blurShape = + typeof region.blurData?.shape === "string" && + VALID_BLUR_SHAPES.has(region.blurData.shape) + ? region.blurData.shape + : DEFAULT_BLUR_DATA.shape; + const blurType = normalizeBlurType(region.blurData?.type); + const blurColor = normalizeBlurColor(region.blurData?.color); return { id: region.id, startMs, endMs, - type: region.type === "image" || region.type === "figure" ? region.type : "text", + type: + region.type === "image" || region.type === "figure" || region.type === "blur" + ? region.type + : "text", content: typeof region.content === "string" ? region.content : "", textContent: typeof region.textContent === "string" ? region.textContent : undefined, imageContent: typeof region.imageContent === "string" ? region.imageContent : undefined, @@ -304,6 +378,42 @@ export function normalizeProjectEditor(editor: Partial): Pro ...region.figureData, } : undefined, + blurData: + region.blurData && typeof region.blurData === "object" + ? { + ...DEFAULT_BLUR_DATA, + ...region.blurData, + type: blurType, + shape: blurShape, + color: blurColor, + intensity: isFiniteNumber(region.blurData.intensity) + ? clamp(region.blurData.intensity, MIN_BLUR_INTENSITY, MAX_BLUR_INTENSITY) + : DEFAULT_BLUR_INTENSITY, + blockSize: isFiniteNumber(region.blurData.blockSize) + ? clamp(region.blurData.blockSize, MIN_BLUR_BLOCK_SIZE, MAX_BLUR_BLOCK_SIZE) + : DEFAULT_BLUR_BLOCK_SIZE, + freehandPoints: Array.isArray(region.blurData.freehandPoints) + ? region.blurData.freehandPoints + .filter( + ( + point, + ): point is { + x: number; + y: number; + } => + Boolean( + point && + isFiniteNumber((point as { x?: unknown }).x) && + isFiniteNumber((point as { y?: unknown }).y), + ), + ) + .map((point) => ({ + x: clamp(point.x, 0, 100), + y: clamp(point.y, 0, 100), + })) + : DEFAULT_BLUR_FREEHAND_POINTS, + } + : undefined, }; }) : []; @@ -327,7 +437,10 @@ export function normalizeProjectEditor(editor: Partial): Pro const cropHeight = clamp(rawCropHeight, 0.01, 1 - cropY); return { - wallpaper: typeof editor.wallpaper === "string" ? editor.wallpaper : WALLPAPER_PATHS[0], + wallpaper: + typeof editor.wallpaper === "string" + ? normalizeWallpaperValue(editor.wallpaper) + : DEFAULT_WALLPAPER, shadowIntensity: typeof editor.shadowIntensity === "number" ? editor.shadowIntensity : 0, showBlur: typeof editor.showBlur === "boolean" ? editor.showBlur : false, motionBlurAmount: isFiniteNumber(editor.motionBlurAmount) @@ -349,13 +462,8 @@ export function normalizeProjectEditor(editor: Partial): Pro trimRegions: normalizedTrimRegions, speedRegions: normalizedSpeedRegions, annotationRegions: normalizedAnnotationRegions, - aspectRatio: - editor.aspectRatio && validAspectRatios.has(editor.aspectRatio) ? editor.aspectRatio : "16:9", - webcamLayoutPreset: - editor.webcamLayoutPreset === "vertical-stack" || - editor.webcamLayoutPreset === "picture-in-picture" - ? editor.webcamLayoutPreset - : DEFAULT_WEBCAM_LAYOUT_PRESET, + aspectRatio: normalizedAspectRatio, + webcamLayoutPreset: normalizedWebcamLayoutPreset, webcamMaskShape: editor.webcamMaskShape === "rectangle" || editor.webcamMaskShape === "circle" || @@ -363,16 +471,11 @@ export function normalizeProjectEditor(editor: Partial): Pro editor.webcamMaskShape === "rounded" ? editor.webcamMaskShape : DEFAULT_WEBCAM_MASK_SHAPE, - webcamPosition: - editor.webcamPosition && - typeof editor.webcamPosition === "object" && - isFiniteNumber((editor.webcamPosition as WebcamPosition).cx) && - isFiniteNumber((editor.webcamPosition as WebcamPosition).cy) - ? { - cx: clamp((editor.webcamPosition as WebcamPosition).cx, 0, 1), - cy: clamp((editor.webcamPosition as WebcamPosition).cy, 0, 1), - } - : DEFAULT_WEBCAM_POSITION, + webcamSizePreset: + typeof editor.webcamSizePreset === "number" && isFiniteNumber(editor.webcamSizePreset) + ? Math.max(10, Math.min(50, editor.webcamSizePreset)) + : DEFAULT_WEBCAM_SIZE_PRESET, + webcamPosition: normalizedWebcamPosition, exportQuality: editor.exportQuality === "medium" || editor.exportQuality === "source" ? editor.exportQuality @@ -392,6 +495,52 @@ export function normalizeProjectEditor(editor: Partial): Pro editor.gifSizePreset === "original" ? editor.gifSizePreset : "medium", + cursorHighlight: normalizeCursorHighlight(editor.cursorHighlight), + }; +} + +function normalizeCursorHighlight( + value: unknown, +): import("./videoPlayback/cursorHighlight").CursorHighlightConfig { + const fallback: import("./videoPlayback/cursorHighlight").CursorHighlightConfig = { + enabled: false, + style: "ring", + sizePx: 24, + color: "#FFD700", + opacity: 0.9, + onlyOnClicks: false, + clickEmphasisDurationMs: 350, + offsetXNorm: 0, + offsetYNorm: 0, + }; + if (!value || typeof value !== "object") return fallback; + const v = value as Partial; + return { + enabled: typeof v.enabled === "boolean" ? v.enabled : fallback.enabled, + style: v.style === "dot" || v.style === "ring" ? v.style : fallback.style, + sizePx: + typeof v.sizePx === "number" && v.sizePx >= 10 && v.sizePx <= 36 ? v.sizePx : fallback.sizePx, + color: + typeof v.color === "string" && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(v.color) + ? v.color + : fallback.color, + opacity: + typeof v.opacity === "number" && v.opacity >= 0 && v.opacity <= 1 + ? v.opacity + : fallback.opacity, + onlyOnClicks: typeof v.onlyOnClicks === "boolean" ? v.onlyOnClicks : fallback.onlyOnClicks, + clickEmphasisDurationMs: + typeof v.clickEmphasisDurationMs === "number" && v.clickEmphasisDurationMs > 0 + ? v.clickEmphasisDurationMs + : fallback.clickEmphasisDurationMs, + offsetXNorm: + typeof v.offsetXNorm === "number" && Number.isFinite(v.offsetXNorm) + ? Math.max(-1, Math.min(1, v.offsetXNorm)) + : fallback.offsetXNorm, + offsetYNorm: + typeof v.offsetYNorm === "number" && Number.isFinite(v.offsetYNorm) + ? Math.max(-1, Math.min(1, v.offsetYNorm)) + : fallback.offsetYNorm, }; } @@ -405,3 +554,19 @@ export function createProjectData( editor, }; } + +export function createProjectSnapshot( + media: ProjectMedia, + editor: Partial, +): string { + return JSON.stringify(createProjectData(media, normalizeProjectEditor(editor))); +} + +export function hasProjectUnsavedChanges( + currentSnapshot: string | null, + baselineSnapshot: string | null, +): boolean { + return Boolean( + currentSnapshot !== null && baselineSnapshot !== null && currentSnapshot !== baselineSnapshot, + ); +} diff --git a/src/components/video-editor/timeline/Item.tsx b/src/components/video-editor/timeline/Item.tsx index f265fe4..d2b80c7 100644 --- a/src/components/video-editor/timeline/Item.tsx +++ b/src/components/video-editor/timeline/Item.tsx @@ -1,7 +1,8 @@ import type { Span } from "dnd-timeline"; import { useItem } from "dnd-timeline"; -import { Gauge, MessageSquare, Scissors, ZoomIn } from "lucide-react"; +import { Gauge, MessageSquare, MousePointer2, Scissors, ZoomIn } from "lucide-react"; import { useMemo } from "react"; +import { useScopedT } from "@/contexts/I18nContext"; import { cn } from "@/lib/utils"; import glassStyles from "./ItemGlass.module.css"; @@ -14,7 +15,8 @@ interface ItemProps { onSelect?: () => void; zoomDepth?: number; speedValue?: number; - variant?: "zoom" | "trim" | "annotation" | "speed"; + isAutoFocus?: boolean; + variant?: "zoom" | "trim" | "annotation" | "speed" | "blur"; } // Map zoom depth to multiplier labels @@ -45,9 +47,11 @@ export default function Item({ onSelect, zoomDepth = 1, speedValue, + isAutoFocus = false, variant = "zoom", children, }: ItemProps) { + const t = useScopedT("timeline"); const { setNodeRef, attributes, listeners, itemStyle, itemContentStyle } = useItem({ id, span, @@ -132,19 +136,25 @@ export default function Item({ {ZOOM_LABELS[zoomDepth] || `${zoomDepth}×`} + {isAutoFocus && ( + + )} ) : isTrim ? ( <> - Trim + {t("labels.trim")} ) : isSpeed ? ( <> - {speedValue !== undefined ? `${speedValue}×` : "Speed"} + {speedValue !== undefined ? `${speedValue}×` : t("labels.speed")} ) : ( diff --git a/src/components/video-editor/timeline/TimelineEditor.tsx b/src/components/video-editor/timeline/TimelineEditor.tsx index b64aad0..6fe3474 100644 --- a/src/components/video-editor/timeline/TimelineEditor.tsx +++ b/src/components/video-editor/timeline/TimelineEditor.tsx @@ -44,6 +44,7 @@ import { detectZoomDwellCandidates, normalizeCursorTelemetry } from "./zoomSugge const ZOOM_ROW_ID = "row-zoom"; const TRIM_ROW_ID = "row-trim"; const ANNOTATION_ROW_ID = "row-annotation"; +const BLUR_ROW_ID = "row-blur"; const SPEED_ROW_ID = "row-speed"; const FALLBACK_RANGE_MS = 1000; const TARGET_MARKER_COUNT = 12; @@ -73,6 +74,12 @@ interface TimelineEditorProps { onAnnotationDelete?: (id: string) => void; selectedAnnotationId?: string | null; onSelectAnnotation?: (id: string | null) => void; + blurRegions?: AnnotationRegion[]; + onBlurAdded?: (span: Span) => void; + onBlurSpanChange?: (id: string, span: Span) => void; + onBlurDelete?: (id: string) => void; + selectedBlurId?: string | null; + onSelectBlur?: (id: string | null) => void; speedRegions?: SpeedRegion[]; onSpeedAdded?: (span: Span) => void; onSpeedSpanChange?: (id: string, span: Span) => void; @@ -96,7 +103,8 @@ interface TimelineRenderItem { label: string; zoomDepth?: number; speedValue?: number; - variant: "zoom" | "trim" | "annotation" | "speed"; + isAutoFocus?: boolean; + variant: "zoom" | "trim" | "annotation" | "speed" | "blur"; } const SCALE_CANDIDATES = [ @@ -525,10 +533,12 @@ function Timeline({ onSelectZoom, onSelectTrim, onSelectAnnotation, + onSelectBlur, onSelectSpeed, selectedZoomId, selectedTrimId, selectedAnnotationId, + selectedBlurId, selectedSpeedId, keyframes = [], }: { @@ -540,10 +550,12 @@ function Timeline({ onSelectZoom?: (id: string | null) => void; onSelectTrim?: (id: string | null) => void; onSelectAnnotation?: (id: string | null) => void; + onSelectBlur?: (id: string | null) => void; onSelectSpeed?: (id: string | null) => void; selectedZoomId: string | null; selectedTrimId?: string | null; selectedAnnotationId?: string | null; + selectedBlurId?: string | null; selectedSpeedId?: string | null; keyframes?: { id: string; time: number }[]; }) { @@ -568,6 +580,7 @@ function Timeline({ onSelectZoom?.(null); onSelectTrim?.(null); onSelectAnnotation?.(null); + onSelectBlur?.(null); onSelectSpeed?.(null); const rect = e.currentTarget.getBoundingClientRect(); @@ -586,6 +599,7 @@ function Timeline({ onSelectZoom, onSelectTrim, onSelectAnnotation, + onSelectBlur, onSelectSpeed, videoDurationMs, sidebarWidth, @@ -637,6 +651,7 @@ function Timeline({ const zoomItems = items.filter((item) => item.rowId === ZOOM_ROW_ID); const trimItems = items.filter((item) => item.rowId === TRIM_ROW_ID); const annotationItems = items.filter((item) => item.rowId === ANNOTATION_ROW_ID); + const blurItems = items.filter((item) => item.rowId === BLUR_ROW_ID); const speedItems = items.filter((item) => item.rowId === SPEED_ROW_ID); return ( @@ -668,6 +683,7 @@ function Timeline({ isSelected={item.id === selectedZoomId} onSelect={() => onSelectZoom?.(item.id)} zoomDepth={item.zoomDepth} + isAutoFocus={item.isAutoFocus} variant="zoom" > {item.label} @@ -711,6 +727,22 @@ function Timeline({ ))} + + {blurItems.map((item) => ( + onSelectBlur?.(item.id)} + variant={item.variant} + > + {item.label} + + ))} + + {speedItems.map((item) => ( { + if (!selectedBlurId || !onBlurDelete || !onSelectBlur) return; + onBlurDelete(selectedBlurId); + onSelectBlur(null); + }, [selectedBlurId, onBlurDelete, onSelectBlur]); + const deleteSelectedSpeed = useCallback(() => { if (!selectedSpeedId || !onSpeedDelete || !onSelectSpeed) return; onSpeedDelete(selectedSpeedId); @@ -908,9 +952,10 @@ export default function TimelineEditor({ const isZoomItem = zoomRegions.some((r) => r.id === excludeId); const isTrimItem = trimRegions.some((r) => r.id === excludeId); const isAnnotationItem = annotationRegions.some((r) => r.id === excludeId); + const isBlurItem = blurRegions.some((r) => r.id === excludeId); const isSpeedItem = speedRegions.some((r) => r.id === excludeId); - if (isAnnotationItem) { + if (isAnnotationItem || isBlurItem) { return false; } @@ -937,7 +982,7 @@ export default function TimelineEditor({ return false; }, - [zoomRegions, trimRegions, annotationRegions, speedRegions], + [zoomRegions, trimRegions, annotationRegions, blurRegions, speedRegions], ); // At least 5% of the timeline or 1000ms, whichever is larger, so the region @@ -1165,6 +1210,21 @@ export default function TimelineEditor({ onAnnotationAdded({ start: startPos, end: endPos }); }, [videoDuration, totalMs, currentTimeMs, onAnnotationAdded, defaultRegionDurationMs]); + const handleAddBlur = useCallback(() => { + if (!videoDuration || videoDuration === 0 || totalMs === 0 || !onBlurAdded) { + return; + } + + const defaultDuration = Math.min(defaultRegionDurationMs, totalMs); + if (defaultDuration <= 0) { + return; + } + + const startPos = Math.max(0, Math.min(currentTimeMs, totalMs)); + const endPos = Math.min(startPos + defaultDuration, totalMs); + onBlurAdded({ start: startPos, end: endPos }); + }, [videoDuration, totalMs, currentTimeMs, onBlurAdded, defaultRegionDurationMs]); + useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) { @@ -1183,6 +1243,9 @@ export default function TimelineEditor({ if (matchesShortcut(e, keyShortcuts.addAnnotation, isMac)) { handleAddAnnotation(); } + if (matchesShortcut(e, keyShortcuts.addBlur, isMac)) { + handleAddBlur(); + } if (matchesShortcut(e, keyShortcuts.addSpeed, isMac)) { handleAddSpeed(); } @@ -1223,6 +1286,8 @@ export default function TimelineEditor({ deleteSelectedTrim(); } else if (selectedAnnotationId) { deleteSelectedAnnotation(); + } else if (selectedBlurId) { + deleteSelectedBlur(); } else if (selectedSpeedId) { deleteSelectedSpeed(); } @@ -1235,16 +1300,19 @@ export default function TimelineEditor({ handleAddZoom, handleAddTrim, handleAddAnnotation, + handleAddBlur, handleAddSpeed, deleteSelectedKeyframe, deleteSelectedZoom, deleteSelectedTrim, deleteSelectedAnnotation, + deleteSelectedBlur, deleteSelectedSpeed, selectedKeyframeId, selectedZoomId, selectedTrimId, selectedAnnotationId, + selectedBlurId, selectedSpeedId, annotationRegions, currentTime, @@ -1271,6 +1339,7 @@ export default function TimelineEditor({ span: { start: region.startMs, end: region.endMs }, label: t("labels.zoomItem", { index: String(index + 1) }), zoomDepth: region.depth, + isAutoFocus: region.focusMode === "auto", variant: "zoom", })); @@ -1304,6 +1373,14 @@ export default function TimelineEditor({ }; }); + const blurs: TimelineRenderItem[] = blurRegions.map((region, index) => ({ + id: region.id, + rowId: BLUR_ROW_ID, + span: { start: region.startMs, end: region.endMs }, + label: t("labels.blurItem", { index: String(index + 1) }), + variant: "blur", + })); + const speeds: TimelineRenderItem[] = speedRegions.map((region, index) => ({ id: region.id, rowId: SPEED_ROW_ID, @@ -1313,8 +1390,8 @@ export default function TimelineEditor({ variant: "speed", })); - return [...zooms, ...trims, ...annotations, ...speeds]; - }, [zoomRegions, trimRegions, annotationRegions, speedRegions, t]); + return [...zooms, ...trims, ...annotations, ...blurs, ...speeds]; + }, [zoomRegions, trimRegions, annotationRegions, blurRegions, speedRegions, t]); // Flat list of all non-annotation region spans for neighbour-clamping during drag/resize const allRegionSpans = useMemo(() => { @@ -1335,6 +1412,8 @@ export default function TimelineEditor({ onSpeedSpanChange?.(id, span); } else if (annotationRegions.some((r) => r.id === id)) { onAnnotationSpanChange?.(id, span); + } else if (blurRegions.some((r) => r.id === id)) { + onBlurSpanChange?.(id, span); } }, [ @@ -1342,10 +1421,12 @@ export default function TimelineEditor({ trimRegions, speedRegions, annotationRegions, + blurRegions, onZoomSpanChange, onTrimSpanChange, onSpeedSpanChange, onAnnotationSpanChange, + onBlurSpanChange, ], ); @@ -1403,6 +1484,25 @@ export default function TimelineEditor({ > +